From 3cb2fb82504e0b738301e57b9b60c282912ee557 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=9D=9E=E6=B3=95=E6=93=8D=E4=BD=9C?= Date: Wed, 6 Nov 2024 19:06:55 +0800 Subject: [PATCH 1/5] =?UTF-8?q?fix:=20remove=20duplicated=20category=20?= =?UTF-8?q?=E2=80=9Crecommended=E2=80=9D=20(#10375)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- web/app/components/explore/category.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/web/app/components/explore/category.tsx b/web/app/components/explore/category.tsx index cbf6cd26fe..8f67f0fd49 100644 --- a/web/app/components/explore/category.tsx +++ b/web/app/components/explore/category.tsx @@ -28,7 +28,7 @@ const Category: FC = ({ allCategoriesEn, }) => { const { t } = useTranslation() - const isAllCategories = !list.includes(value as AppCategory) + const isAllCategories = !list.includes(value as AppCategory) || value === allCategoriesEn const itemClassName = (isSelected: boolean) => cn( 'flex items-center px-3 py-[7px] h-[32px] rounded-lg border-[0.5px] border-transparent text-gray-700 font-medium leading-[18px] cursor-pointer hover:bg-gray-200', @@ -44,7 +44,7 @@ const Category: FC = ({ {t('explore.apps.allCategories')} - {list.map(name => ( + {list.filter(name => name !== allCategoriesEn).map(name => (
Date: Thu, 7 Nov 2024 11:40:57 +0900 Subject: [PATCH 2/5] fix typo: mMaximum -> Maximum (#10389) --- api/configs/feature/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/configs/feature/__init__.py b/api/configs/feature/__init__.py index 517b92fda4..3ac2c28c1f 100644 --- a/api/configs/feature/__init__.py +++ b/api/configs/feature/__init__.py @@ -109,7 +109,7 @@ class CodeExecutionSandboxConfig(BaseSettings): ) CODE_MAX_PRECISION: PositiveInt = Field( - description="mMaximum number of decimal places for floating-point numbers in code execution", + description="Maximum number of decimal places for floating-point numbers in code execution", default=20, ) From 93b72efc313e03f343699a271ab9d68d5fb00ad0 Mon Sep 17 00:00:00 2001 From: NFish Date: Thu, 7 Nov 2024 14:02:22 +0800 Subject: [PATCH 3/5] feat: Show warning tip on Login Page when License is expired. --- web/app/signin/normalForm.tsx | 18 ++++++++++++++++-- web/i18n/en-US/login.ts | 2 ++ web/i18n/zh-Hans/login.ts | 2 ++ web/types/feature.ts | 8 ++++++++ 4 files changed, 28 insertions(+), 2 deletions(-) diff --git a/web/app/signin/normalForm.tsx b/web/app/signin/normalForm.tsx index f4f46c68ba..032c10a301 100644 --- a/web/app/signin/normalForm.tsx +++ b/web/app/signin/normalForm.tsx @@ -2,7 +2,7 @@ import React, { useCallback, useEffect, useState } from 'react' import { useTranslation } from 'react-i18next' import Link from 'next/link' import { useRouter, useSearchParams } from 'next/navigation' -import { RiDoorLockLine } from '@remixicon/react' +import { RiContractLine, RiDoorLockLine, RiErrorWarningFill } from '@remixicon/react' import Loading from '../components/base/loading' import MailAndCodeAuth from './components/mail-and-code-auth' import MailAndPasswordAuth from './components/mail-and-password-auth' @@ -10,7 +10,7 @@ import SocialAuth from './components/social-auth' import SSOAuth from './components/sso-auth' import cn from '@/utils/classnames' import { getSystemFeatures, invitationCheck } from '@/service/common' -import { defaultSystemFeatures } from '@/types/feature' +import { LicenseStatus, defaultSystemFeatures } from '@/types/feature' import Toast from '@/app/components/base/toast' import { IS_CE_EDITION } from '@/config' @@ -83,6 +83,20 @@ const NormalForm = () => {
} + if (systemFeatures.license_status === LicenseStatus.EXPIRED) { + return
+
+
+
+ + +
+

{t('login.licenseExpired')}

+

{t('login.licenseExpiredTip')}

+
+
+
+ } return ( <> diff --git a/web/i18n/en-US/login.ts b/web/i18n/en-US/login.ts index b47d7bd69a..b14bd1e2a0 100644 --- a/web/i18n/en-US/login.ts +++ b/web/i18n/en-US/login.ts @@ -98,6 +98,8 @@ const translation = { back: 'Back', noLoginMethod: 'Authentication method not configured', noLoginMethodTip: 'Please contact the system admin to add an authentication method.', + licenseExpired: 'License Expired', + licenseExpiredTip: 'Your organization\'s Dify Enterprise license has expired.Please contact your administrator to continue using Dify.', } export default translation diff --git a/web/i18n/zh-Hans/login.ts b/web/i18n/zh-Hans/login.ts index 40697701da..02959a2987 100644 --- a/web/i18n/zh-Hans/login.ts +++ b/web/i18n/zh-Hans/login.ts @@ -99,6 +99,8 @@ const translation = { back: '返回', noLoginMethod: '未配置身份认证方式', noLoginMethodTip: '请联系系统管理员添加身份认证方式', + licenseExpired: '许可证已过期', + licenseExpiredTip: '您的组织的 Dify 企业许可证已过期。请联系您的管理员续订继续使用 Dify。', } export default translation diff --git a/web/types/feature.ts b/web/types/feature.ts index 0d9b2ec18d..aaba147540 100644 --- a/web/types/feature.ts +++ b/web/types/feature.ts @@ -4,6 +4,12 @@ export enum SSOProtocol { OAuth2 = 'oauth2', } +export enum LicenseStatus { + NONE = 'none', + ACTIVE = 'active', + EXPIRED = 'expired', +} + export type SystemFeatures = { sso_enforced_for_signin: boolean sso_enforced_for_signin_protocol: SSOProtocol | '' @@ -15,6 +21,7 @@ export type SystemFeatures = { enable_social_oauth_login: boolean is_allow_create_workspace: boolean is_allow_register: boolean + license_status: LicenseStatus } export const defaultSystemFeatures: SystemFeatures = { @@ -28,4 +35,5 @@ export const defaultSystemFeatures: SystemFeatures = { enable_social_oauth_login: false, is_allow_create_workspace: false, is_allow_register: false, + license_status: LicenseStatus.NONE, } From b3e0a5c078a410b6be212b801b94f38bbdbb03e4 Mon Sep 17 00:00:00 2001 From: NFish Date: Thu, 7 Nov 2024 14:09:29 +0800 Subject: [PATCH 4/5] fix: update i18n & show warning tip on Login page when License is Inactive --- web/app/signin/normalForm.tsx | 14 ++++++++++++++ web/i18n/en-US/login.ts | 4 +++- web/i18n/zh-Hans/login.ts | 4 +++- web/types/feature.ts | 1 + 4 files changed, 21 insertions(+), 2 deletions(-) diff --git a/web/app/signin/normalForm.tsx b/web/app/signin/normalForm.tsx index 032c10a301..b6a8b24584 100644 --- a/web/app/signin/normalForm.tsx +++ b/web/app/signin/normalForm.tsx @@ -97,6 +97,20 @@ const NormalForm = () => { } + if (systemFeatures.license_status === LicenseStatus.NONE) { + return
+
+
+
+ + +
+

{t('login.licenseInactive')}

+

{t('login.licenseInactiveTip')}

+
+
+
+ } return ( <> diff --git a/web/i18n/en-US/login.ts b/web/i18n/en-US/login.ts index b14bd1e2a0..3c7c6e3433 100644 --- a/web/i18n/en-US/login.ts +++ b/web/i18n/en-US/login.ts @@ -99,7 +99,9 @@ const translation = { noLoginMethod: 'Authentication method not configured', noLoginMethodTip: 'Please contact the system admin to add an authentication method.', licenseExpired: 'License Expired', - licenseExpiredTip: 'Your organization\'s Dify Enterprise license has expired.Please contact your administrator to continue using Dify.', + licenseExpiredTip: 'The Dify Enterprise license for your workspace has expired. Please contact your administrator to continue using Dify.', + licenseInactive: 'License Inactive', + licenseInactiveTip: 'Your organization\'s Dify Enterprise license Inactive.Please contact your administrator to continue using Dify.', } export default translation diff --git a/web/i18n/zh-Hans/login.ts b/web/i18n/zh-Hans/login.ts index 02959a2987..7113e714f3 100644 --- a/web/i18n/zh-Hans/login.ts +++ b/web/i18n/zh-Hans/login.ts @@ -100,7 +100,9 @@ const translation = { noLoginMethod: '未配置身份认证方式', noLoginMethodTip: '请联系系统管理员添加身份认证方式', licenseExpired: '许可证已过期', - licenseExpiredTip: '您的组织的 Dify 企业许可证已过期。请联系您的管理员续订继续使用 Dify。', + licenseExpiredTip: '您所在空间的 Dify Enterprise 许可证已过期,请联系管理员以继续使用 Dify。', + licenseInactive: '许可证未激活', + licenseInactiveTip: '您的组织的 Dify 企业许可证未激活。请联系您的管理员激活后继续使用 Dify。', } export default translation diff --git a/web/types/feature.ts b/web/types/feature.ts index aaba147540..fe1cf22a9d 100644 --- a/web/types/feature.ts +++ b/web/types/feature.ts @@ -7,6 +7,7 @@ export enum SSOProtocol { export enum LicenseStatus { NONE = 'none', ACTIVE = 'active', + INACTIVE = 'inactive', EXPIRED = 'expired', } From 4129595369d0da7742161e215455a075ebd63010 Mon Sep 17 00:00:00 2001 From: NFish Date: Thu, 7 Nov 2024 15:56:57 +0800 Subject: [PATCH 5/5] feat: Display License status in navbar when Active or Expiring --- web/app/components/header/index.tsx | 2 ++ .../components/header/license-env/index.tsx | 29 +++++++++++++++++++ web/app/signin/normalForm.tsx | 4 +-- web/context/app-context.tsx | 2 +- web/i18n/en-US/common.ts | 4 +++ web/i18n/en-US/login.ts | 2 +- web/i18n/zh-Hans/common.ts | 4 +++ web/i18n/zh-Hans/login.ts | 2 +- web/types/feature.ts | 16 ++++++++-- 9 files changed, 57 insertions(+), 8 deletions(-) create mode 100644 web/app/components/header/license-env/index.tsx diff --git a/web/app/components/header/index.tsx b/web/app/components/header/index.tsx index 2b020b81e7..3757d552df 100644 --- a/web/app/components/header/index.tsx +++ b/web/app/components/header/index.tsx @@ -12,6 +12,7 @@ import EnvNav from './env-nav' import ExploreNav from './explore-nav' import ToolsNav from './tools-nav' import GithubStar from './github-star' +import LicenseNav from './license-env' import { WorkspaceProvider } from '@/context/workspace-context' import { useAppContext } from '@/context/app-context' import LogoSite from '@/app/components/base/logo/logo-site' @@ -79,6 +80,7 @@ const Header = () => { )}
+ {enableBilling && (
diff --git a/web/app/components/header/license-env/index.tsx b/web/app/components/header/license-env/index.tsx new file mode 100644 index 0000000000..800d86d2b8 --- /dev/null +++ b/web/app/components/header/license-env/index.tsx @@ -0,0 +1,29 @@ +'use client' + +import AppContext from '@/context/app-context' +import { LicenseStatus } from '@/types/feature' +import { useTranslation } from 'react-i18next' +import { useContextSelector } from 'use-context-selector' +import dayjs from 'dayjs' + +const LicenseNav = () => { + const { t } = useTranslation() + const systemFeatures = useContextSelector(AppContext, s => s.systemFeatures) + + if (systemFeatures.license?.status === LicenseStatus.EXPIRING) { + const expiredAt = systemFeatures.license?.expired_at + const count = dayjs(expiredAt).diff(dayjs(), 'days') + return
+ {count <= 1 && {t('common.license.expiring', { count })}} + {count > 1 && {t('common.license.expiring_plural', { count })}} +
+ } + if (systemFeatures.license.status === LicenseStatus.ACTIVE) { + return
+ Enterprise +
+ } + return null +} + +export default LicenseNav diff --git a/web/app/signin/normalForm.tsx b/web/app/signin/normalForm.tsx index b6a8b24584..605adeec03 100644 --- a/web/app/signin/normalForm.tsx +++ b/web/app/signin/normalForm.tsx @@ -83,7 +83,7 @@ const NormalForm = () => {
} - if (systemFeatures.license_status === LicenseStatus.EXPIRED) { + if (systemFeatures.license?.status === LicenseStatus.EXPIRED) { return
@@ -97,7 +97,7 @@ const NormalForm = () => {
} - if (systemFeatures.license_status === LicenseStatus.NONE) { + if (systemFeatures.license?.status === LicenseStatus.INACTIVE) { return
diff --git a/web/context/app-context.tsx b/web/context/app-context.tsx index 78ac1c9848..fe797663e7 100644 --- a/web/context/app-context.tsx +++ b/web/context/app-context.tsx @@ -144,7 +144,7 @@ export const AppContextProvider: FC = ({ children }) => theme, setTheme: handleSetTheme, apps: appList.data, - systemFeatures, + systemFeatures: { ...systemFeatures, ...defaultSystemFeatures }, mutateApps, userProfile, mutateUserProfile, diff --git a/web/i18n/en-US/common.ts b/web/i18n/en-US/common.ts index 3390280e8a..f9d815be2c 100644 --- a/web/i18n/en-US/common.ts +++ b/web/i18n/en-US/common.ts @@ -591,6 +591,10 @@ const translation = { created: 'Tag created successfully', failed: 'Tag creation failed', }, + license: { + expiring: 'Expiring in one day', + expiring_plural: 'Expiring in {{count}} days', + }, } export default translation diff --git a/web/i18n/en-US/login.ts b/web/i18n/en-US/login.ts index 3c7c6e3433..cbe21458ff 100644 --- a/web/i18n/en-US/login.ts +++ b/web/i18n/en-US/login.ts @@ -101,7 +101,7 @@ const translation = { licenseExpired: 'License Expired', licenseExpiredTip: 'The Dify Enterprise license for your workspace has expired. Please contact your administrator to continue using Dify.', licenseInactive: 'License Inactive', - licenseInactiveTip: 'Your organization\'s Dify Enterprise license Inactive.Please contact your administrator to continue using Dify.', + licenseInactiveTip: 'The Dify Enterprise license for your workspace is inactive. Please contact your administrator to continue using Dify.', } export default translation diff --git a/web/i18n/zh-Hans/common.ts b/web/i18n/zh-Hans/common.ts index 58d56a8331..207beaab8c 100644 --- a/web/i18n/zh-Hans/common.ts +++ b/web/i18n/zh-Hans/common.ts @@ -591,6 +591,10 @@ const translation = { created: '标签创建成功', failed: '标签创建失败', }, + license: { + expiring: '许可证还有 1 天到期', + expiring_plural: '许可证还有 {{count}} 天到期', + }, } export default translation diff --git a/web/i18n/zh-Hans/login.ts b/web/i18n/zh-Hans/login.ts index 7113e714f3..4d77b8e403 100644 --- a/web/i18n/zh-Hans/login.ts +++ b/web/i18n/zh-Hans/login.ts @@ -102,7 +102,7 @@ const translation = { licenseExpired: '许可证已过期', licenseExpiredTip: '您所在空间的 Dify Enterprise 许可证已过期,请联系管理员以继续使用 Dify。', licenseInactive: '许可证未激活', - licenseInactiveTip: '您的组织的 Dify 企业许可证未激活。请联系您的管理员激活后继续使用 Dify。', + licenseInactiveTip: '您所在空间的 Dify Enterprise 许可证尚未激活,请联系管理员以继续使用 Dify。', } export default translation diff --git a/web/types/feature.ts b/web/types/feature.ts index fe1cf22a9d..47e8e1aad1 100644 --- a/web/types/feature.ts +++ b/web/types/feature.ts @@ -6,9 +6,16 @@ export enum SSOProtocol { export enum LicenseStatus { NONE = 'none', - ACTIVE = 'active', INACTIVE = 'inactive', + ACTIVE = 'active', + EXPIRING = 'expiring', EXPIRED = 'expired', + LOST = 'lost', +} + +type License = { + status: LicenseStatus + expired_at: string | null } export type SystemFeatures = { @@ -22,7 +29,7 @@ export type SystemFeatures = { enable_social_oauth_login: boolean is_allow_create_workspace: boolean is_allow_register: boolean - license_status: LicenseStatus + license: License } export const defaultSystemFeatures: SystemFeatures = { @@ -36,5 +43,8 @@ export const defaultSystemFeatures: SystemFeatures = { enable_social_oauth_login: false, is_allow_create_workspace: false, is_allow_register: false, - license_status: LicenseStatus.NONE, + license: { + status: LicenseStatus.NONE, + expired_at: '', + }, }