mirror of
https://github.com/langgenius/dify.git
synced 2026-10-04 13:47:55 +08:00
refactor(web): remove obsolete maintenance notice (#42464)
This commit is contained in:
12 files changed
+1
-340
No files matched your search
@@ -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": {
|
||||
|
||||
@@ -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
|
||||
@@ -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)
|
||||
|
||||
@@ -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'),
|
||||
|
||||
@@ -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: '#',
|
||||
}
|
||||
Reference in new issue
Block a user