refactor(web): remove obsolete maintenance notice (#42464)

This commit is contained in:
yyh authored and GitHub committed 2026-09-18 02:31:51 +00:00
1 parent a504dfee27
commit bfa4a8b5e4
12 files changed
+1 -340

No files matched your search

+1 -1
View File
@@ -1287,7 +1287,7 @@
},
"web/app/components/base/icons/src/vender/line/general/index.ts": {
"no-barrel-files/no-barrel-files": {
"count": 10
"count": 9
}
},
"web/app/components/base/icons/src/vender/line/images/index.ts": {
-2
View File
@@ -1,6 +1,5 @@
import * as React from 'react'
import Zendesk from '@/app/components/base/zendesk'
import MaintenanceNotice from '@/app/components/header/maintenance-notice'
import MainNavLayout from '@/app/components/main-nav/server'
import { CommonLayoutGlobalMounts } from './global-mounts'
import { ConsoleContextProviders, ConsoleRuntimeProviders } from './providers'
@@ -16,7 +15,6 @@ export default async function Layout({
<React.Fragment>
<ConsoleRuntimeProviders>
<div className="flex h-full flex-col overflow-hidden">
<MaintenanceNotice />
<ConsoleContextProviders>
<MainNavLayout detailSidebar={detailSidebar}>{children}</MainNavLayout>
<CommonLayoutGlobalMounts />
@@ -1,7 +1,6 @@
import * as React from 'react'
import { ConsoleContextProviders, ConsoleRuntimeProviders } from '@/app/(commonLayout)/providers'
import HeaderWrapper from '@/app/components/header/header-wrapper'
import MaintenanceNotice from '@/app/components/header/maintenance-notice'
import Header from './header'
export default async function Layout({ children }: { children: React.ReactNode }) {
@@ -9,7 +8,6 @@ export default async function Layout({ children }: { children: React.ReactNode }
<React.Fragment>
<ConsoleRuntimeProviders>
<div className="flex h-full flex-col overflow-hidden bg-background-body">
<MaintenanceNotice />
<ConsoleContextProviders>
<HeaderWrapper>
<Header />
@@ -1,39 +0,0 @@
{
"icon": {
"type": "element",
"isRootNode": true,
"name": "svg",
"attributes": {
"width": "16",
"height": "16",
"viewBox": "0 0 16 16",
"fill": "none",
"xmlns": "http://www.w3.org/2000/svg"
},
"children": [
{
"type": "element",
"name": "g",
"attributes": {
"id": "x"
},
"children": [
{
"type": "element",
"name": "path",
"attributes": {
"id": "Icon",
"d": "M11.3334 4.66663L4.66675 11.3333M4.66675 4.66663L11.3334 11.3333",
"stroke": "currentColor",
"stroke-width": "1.5",
"stroke-linecap": "round",
"stroke-linejoin": "round"
},
"children": []
}
]
}
]
},
"name": "X"
}
@@ -1,18 +0,0 @@
// GENERATE BY script
// DON NOT EDIT IT MANUALLY
import type { IconData } from '@/app/components/base/icons/IconBase'
import * as React from 'react'
import IconBase from '@/app/components/base/icons/IconBase'
import data from './X.json'
const Icon = ({
ref,
...props
}: React.SVGProps<SVGSVGElement> & {
ref?: React.RefObject<React.RefObject<HTMLOrSVGElement>>
}) => <IconBase {...props} ref={ref} data={data as IconData} />
Icon.displayName = 'X'
export default Icon
@@ -12,5 +12,3 @@ export { default as Plus02 } from './Plus02'
export { default as SearchMenu } from './SearchMenu'
export { default as Settings01 } from './Settings01'
export { default as X } from './X'
@@ -1,129 +0,0 @@
import { fireEvent, render, screen } from '@testing-library/react'
import { vi } from 'vite-plus/test'
import { useLanguage } from '@/app/components/header/account-setting/model-provider-page/hooks'
import { NOTICE_I18N } from '@/i18n-config/language'
import MaintenanceNotice from '../maintenance-notice'
const mockEnv = vi.hoisted(() => ({
NEXT_PUBLIC_MAINTENANCE_NOTICE: 'true',
}))
vi.mock('@/app/components/base/icons/src/vender/line/general', () => ({
X: (props: React.SVGProps<SVGSVGElement>) => <svg {...props} />,
}))
vi.mock('@/env', () => ({
env: mockEnv,
}))
vi.mock('@/app/components/header/account-setting/model-provider-page/hooks', () => ({
useLanguage: vi.fn(),
}))
vi.mock('@/i18n-config/language', async (importOriginal) => {
const actual = (await importOriginal()) as Record<string, unknown>
return {
...actual,
NOTICE_I18N: {
title: {
en_US: 'Notice Title',
zh_Hans: '提示标题',
},
desc: {
en_US: 'Notice Description',
zh_Hans: '提示描述',
},
href: '#',
},
}
})
describe('MaintenanceNotice', () => {
const windowOpenSpy = vi.spyOn(window, 'open').mockImplementation(() => null)
const setNoticeHref = (href: string) => {
NOTICE_I18N.href = href
}
beforeEach(() => {
vi.clearAllMocks()
localStorage.clear()
mockEnv.NEXT_PUBLIC_MAINTENANCE_NOTICE = 'true'
vi.mocked(useLanguage).mockReturnValue('en_US')
setNoticeHref('#')
})
afterAll(() => {
windowOpenSpy.mockRestore()
})
describe('Rendering', () => {
it('should render localized content correctly (English)', () => {
render(<MaintenanceNotice />)
expect(screen.getByText('Notice Title')).toBeInTheDocument()
expect(screen.getByText('Notice Description')).toBeInTheDocument()
})
it('should render localized content correctly (Chinese)', () => {
vi.mocked(useLanguage).mockReturnValue('zh_Hans')
render(<MaintenanceNotice />)
expect(screen.getByText('提示标题')).toBeInTheDocument()
expect(screen.getByText('提示描述')).toBeInTheDocument()
})
it('should not render when hidden in localStorage', () => {
localStorage.setItem('hide-maintenance-notice', '1')
const { container } = render(<MaintenanceNotice />)
expect(container.firstChild).toBeNull()
})
it('should not render when the notice env flag is disabled', () => {
mockEnv.NEXT_PUBLIC_MAINTENANCE_NOTICE = ''
const { container } = render(<MaintenanceNotice />)
expect(container.firstChild).toBeNull()
})
})
describe('User Interactions', () => {
it('should close the notice when X is clicked', () => {
render(<MaintenanceNotice />)
expect(screen.getByText('Notice Title')).toBeInTheDocument()
fireEvent.click(screen.getByRole('button', { name: 'common.operation.close' }))
expect(screen.queryByText('Notice Title')).not.toBeInTheDocument()
expect(localStorage.getItem('hide-maintenance-notice')).toBe('1')
})
it('should jump to notice when description is clicked and href is valid', () => {
setNoticeHref('https://dify.ai/notice')
render(<MaintenanceNotice />)
const desc = screen.getByRole('button', { name: 'Notice Description' })
fireEvent.click(desc)
expect(windowOpenSpy).toHaveBeenCalledWith('https://dify.ai/notice', '_blank')
})
it('should not jump when href is #', () => {
setNoticeHref('#')
render(<MaintenanceNotice />)
const desc = screen.getByText('Notice Description')
fireEvent.click(desc)
expect(windowOpenSpy).not.toHaveBeenCalled()
})
it('should not jump when href is empty', () => {
setNoticeHref('')
render(<MaintenanceNotice />)
const desc = screen.getByText('Notice Description')
fireEvent.click(desc)
expect(windowOpenSpy).not.toHaveBeenCalled()
})
})
})
@@ -1,67 +0,0 @@
'use client'
import { useState } from 'react'
import { useTranslation } from 'react-i18next'
import { X } from '@/app/components/base/icons/src/vender/line/general'
import { useLanguage } from '@/app/components/header/account-setting/model-provider-page/hooks'
import { env } from '@/env'
import { NOTICE_I18N } from '@/i18n-config/language'
import { useHideMaintenanceNotice } from './storage'
function MaintenanceNotice() {
if (!env.NEXT_PUBLIC_MAINTENANCE_NOTICE) return null
return <MaintenanceNoticeContent />
}
function MaintenanceNoticeContent() {
const { t } = useTranslation()
const locale = useLanguage()
const [hiddenNoticeValue, setHiddenNoticeValue] = useHideMaintenanceNotice()
const hiddenNotice = hiddenNoticeValue === '1'
const [closedInSession, setClosedInSession] = useState(false)
const showNotice = !hiddenNotice && !closedInSession
const handleJumpNotice = () => {
window.open(NOTICE_I18N.href, '_blank')
}
const handleCloseNotice = () => {
setHiddenNoticeValue('1')
setClosedInSession(true)
}
const titleByLocale: { [key: string]: string } = NOTICE_I18N.title
const descByLocale: { [key: string]: string } = NOTICE_I18N.desc
if (!showNotice) return null
return (
<div className="z-20 flex h-9.5 shrink-0 items-center border-[0.5px] border-b border-b-[#FEF0C7] bg-[#FFFAEB] px-4">
<div className="mr-2 flex h-5.5 shrink-0 items-center rounded-xl bg-[#F79009] px-2 text-[11px] font-medium text-white">
{titleByLocale[locale]}
</div>
{NOTICE_I18N.href && NOTICE_I18N.href !== '#' ? (
<button
type="button"
className="grow cursor-pointer border-none bg-transparent p-0 text-left text-xs font-medium text-gray-700"
onClick={handleJumpNotice}
>
{descByLocale[locale]}
</button>
) : (
<div className="grow text-xs font-medium text-gray-700">{descByLocale[locale]}</div>
)}
<button
type="button"
aria-label={t(($) => $['operation.close'], { ns: 'common' })}
className="size-4 shrink-0 cursor-pointer border-none bg-transparent p-0 text-gray-500"
onClick={handleCloseNotice}
>
<X className="size-4" aria-hidden="true" />
</button>
</div>
)
}
export default MaintenanceNotice
-6
View File
@@ -1,6 +0,0 @@
import { createLocalStorageState } from 'foxact/create-local-storage-state'
const [useHideMaintenanceNotice, _useHideMaintenanceNoticeValue, _useSetHideMaintenanceNotice] =
createLocalStorageState<string>('hide-maintenance-notice', '0', { raw: true })
export { useHideMaintenanceNotice }
@@ -205,10 +205,6 @@ vi.mock('@/app/components/base/zendesk/runtime', () => ({
},
}))
vi.mock('@/app/components/header/maintenance-notice', () => ({
default: () => null,
}))
function ConsoleBootstrapProbe() {
const currentWorkspace = useAtomValue(currentWorkspaceAtom)
const isCurrentWorkspaceManager = useAtomValue(isCurrentWorkspaceManagerAtom)
-4
View File
@@ -101,7 +101,6 @@ const clientSchema = {
* Maximum loop count in the workflow
*/
NEXT_PUBLIC_LOOP_NODE_MAX_COUNT: coercedNumber.default(100),
NEXT_PUBLIC_MAINTENANCE_NOTICE: z.string().optional(),
/**
* Additional literal characters allowed in Markdown form field names.
*/
@@ -267,9 +266,6 @@ export const env = createEnv({
NEXT_PUBLIC_LOOP_NODE_MAX_COUNT: isServer
? process.env.NEXT_PUBLIC_LOOP_NODE_MAX_COUNT
: getRuntimeEnvFromBody('loopNodeMaxCount'),
NEXT_PUBLIC_MAINTENANCE_NOTICE: isServer
? process.env.NEXT_PUBLIC_MAINTENANCE_NOTICE
: getRuntimeEnvFromBody('maintenanceNotice'),
NEXT_PUBLIC_MARKDOWN_FORM_FIELD_NAME_EXTRA_CHARS: isServer
? process.env.NEXT_PUBLIC_MARKDOWN_FORM_FIELD_NAME_EXTRA_CHARS
: getRuntimeEnvFromBody('markdownFormFieldNameExtraChars'),
-66
View File
@@ -71,69 +71,3 @@ export const getDocLanguage = (locale: string): DocLanguage => {
export const getAccessControlTemplateLanguage = (locale: string): AccessControlTemplateLanguage => {
return ACCESS_CONTROL_TEMPLATE_LANGUAGE[locale] || 'en'
}
export const NOTICE_I18N = {
title: {
en_US: 'Important Notice',
zh_Hans: '重要公告',
zh_Hant: '重要公告',
pt_BR: 'Aviso Importante',
es_ES: 'Aviso Importante',
fr_FR: 'Avis important',
de_DE: 'Wichtiger Hinweis',
ja_JP: '重要なお知らせ',
ko_KR: '중요 공지',
ru_RU: 'Важное Уведомление',
it_IT: 'Avviso Importante',
th_TH: 'ประกาศสำคัญ',
id_ID: 'Pengumuman Penting',
uk_UA: 'Важливе повідомлення',
vi_VN: 'Thông báo quan trọng',
ro_RO: 'Anunț Important',
pl_PL: 'Ważne ogłoszenie',
hi_IN: 'महत्वपूर्ण सूचना',
tr_TR: 'Önemli Duyuru',
fa_IR: 'هشدار مهم',
sl_SI: 'Pomembno obvestilo',
ar_TN: 'إشعار مهم',
},
desc: {
en_US:
'Our system will be unavailable from 19:00 to 24:00 UTC on August 28 for an upgrade. For questions, kindly contact our support team (support@dify.ai). We value your patience.',
zh_Hans:
'为了有效提升数据检索能力及稳定性,Dify 将于 2023 年 8 月 29 日 03:00 至 08:00 期间进行服务升级,届时 Dify 云端版及应用将无法访问。感谢您的耐心与支持。',
pt_BR:
'Our system will be unavailable from 19:00 to 24:00 UTC on August 28 for an upgrade. For questions, kindly contact our support team (support@dify.ai). We value your patience.',
es_ES:
'Our system will be unavailable from 19:00 to 24:00 UTC on August 28 for an upgrade. For questions, kindly contact our support team (support@dify.ai). We value your patience.',
fr_FR:
'Our system will be unavailable from 19:00 to 24:00 UTC on August 28 for an upgrade. For questions, kindly contact our support team (support@dify.ai). We value your patience.',
de_DE:
'Our system will be unavailable from 19:00 to 24:00 UTC on August 28 for an upgrade. For questions, kindly contact our support team (support@dify.ai). We value your patience.',
ja_JP:
'Our system will be unavailable from 19:00 to 24:00 UTC on August 28 for an upgrade. For questions, kindly contact our support team (support@dify.ai). We value your patience.',
ko_KR:
'시스템이 업그레이드를 위해 UTC 시간대로 8 월 28 일 19:00 ~ 24:00 에 사용 불가될 예정입니다. 질문이 있으시면 지원 팀에 연락주세요 (support@dify.ai). 최선을 다해 답변해드리겠습니다.',
pl_PL:
'Nasz system będzie niedostępny od 19:00 do 24:00 UTC 28 sierpnia w celu aktualizacji. W przypadku pytań prosimy o kontakt z naszym zespołem wsparcia (support@dify.ai). Doceniamy Twoją cierpliwość.',
uk_UA:
'Наша система буде недоступна з 19:00 до 24:00 UTC 28 серпня для оновлення. Якщо у вас виникнуть запитання, будь ласка, зв’яжіться з нашою службою підтримки (support@dify.ai). Дякуємо за терпіння.',
ru_RU:
'Наша система будет недоступна с 19:00 до 24:00 UTC 28 августа для обновления. По вопросам, пожалуйста, обращайтесь в нашу службу поддержки (support@dify.ai). Спасибо за ваше терпение',
vi_VN:
'Hệ thống của chúng tôi sẽ ngừng hoạt động từ 19:00 đến 24:00 UTC vào ngày 28 tháng 8 để nâng cấp. Nếu có thắc mắc, vui lòng liên hệ với nhóm hỗ trợ của chúng tôi (support@dify.ai). Chúng tôi đánh giá cao sự kiên nhẫn của bạn.',
id_ID:
'Sistem kami tidak akan tersedia dari 19:00 hingga 24:00 UTC pada 28 Agustus untuk pemutakhiran. Untuk pertanyaan, silakan hubungi tim dukungan kami (support@dify.ai). Kami menghargai kesabaran Anda.',
tr_TR:
"Sistemimiz, 28 Ağustos'ta 19:00 ile 24:00 UTC saatleri arasında güncelleme nedeniyle kullanılamayacaktır. Sorularınız için lütfen destek ekibimizle iletişime geçin (support@dify.ai). Sabrınız için teşekkür ederiz.",
fa_IR:
'سیستم ما از ساعت 19:00 تا 24:00 UTC در تاریخ 28 اوت برای ارتقاء در دسترس نخواهد بود. برای سؤالات، لطفاً با تیم پشتیبانی ما (support@dify.ai) تماس بگیرید. ما برای صبر شما ارزش قائلیم.',
sl_SI:
'Naš sistem ne bo na voljo od 19:00 do 24:00 UTC 28. avgusta zaradi nadgradnje. Za vprašanja se obrnite na našo skupino za podporo (support@dify.ai). Cenimo vašo potrpežljivost.',
th_TH:
'ระบบของเราจะไม่สามารถใช้งานได้ตั้งแต่เวลา 19:00 ถึง 24:00 UTC ในวันที่ 28 สิงหาคม เพื่อทำการอัปเกรด หากมีคำถามใดๆ กรุณาติดต่อทีมสนับสนุนของเรา (support@dify.ai) เราขอขอบคุณในความอดทนของท่าน',
ar_TN:
'سيكون نظامنا غير متاح من الساعة 19:00 إلى 24:00 بالتوقيت العالمي المنسق في 28 أغسطس لإجراء ترقية. للأسئلة، يرجى الاتصال بفريق الدعم لدينا (support@dify.ai). نحن نقدر صبرك.',
},
href: '#',
}