From 59a9235041f9e36b63e932dfb7ac64ac66a088dd Mon Sep 17 00:00:00 2001 From: JzoNg Date: Sat, 9 Nov 2024 12:12:10 +0800 Subject: [PATCH 01/68] useQuery for model list --- .../plugins/plugin-detail-panel/model-list.tsx | 9 ++------- web/service/use-models.ts | 17 +++++++++++++++++ 2 files changed, 19 insertions(+), 7 deletions(-) create mode 100644 web/service/use-models.ts diff --git a/web/app/components/plugins/plugin-detail-panel/model-list.tsx b/web/app/components/plugins/plugin-detail-panel/model-list.tsx index 2704ea741f..7980920119 100644 --- a/web/app/components/plugins/plugin-detail-panel/model-list.tsx +++ b/web/app/components/plugins/plugin-detail-panel/model-list.tsx @@ -1,19 +1,14 @@ import React from 'react' -import useSWR from 'swr' import { useTranslation } from 'react-i18next' import { usePluginPageContext } from '@/app/components/plugins/plugin-page/context' import ModelIcon from '@/app/components/header/account-setting/model-provider-page/model-icon' import ModelName from '@/app/components/header/account-setting/model-provider-page/model-name' -import { fetchModelProviderModelList } from '@/service/common' +import { useModelProviderModelList } from '@/service/use-models' const ModelList = () => { const { t } = useTranslation() const currentPluginDetail = usePluginPageContext(v => v.currentPluginDetail) - - const { data: res } = useSWR( - `/workspaces/current/model-providers/${currentPluginDetail.plugin_id}/${currentPluginDetail.name}/models`, - fetchModelProviderModelList, - ) + const { data: res } = useModelProviderModelList(`${currentPluginDetail.plugin_id}/${currentPluginDetail.name}`) if (!res) return null diff --git a/web/service/use-models.ts b/web/service/use-models.ts new file mode 100644 index 0000000000..84122cdd1f --- /dev/null +++ b/web/service/use-models.ts @@ -0,0 +1,17 @@ +import { get } from './base' +import type { + ModelItem, +} from '@/app/components/header/account-setting/model-provider-page/declarations' +import { + useQuery, + // useQueryClient, +} from '@tanstack/react-query' + +const NAME_SPACE = 'models' + +export const useModelProviderModelList = (provider: string) => { + return useQuery({ + queryKey: [NAME_SPACE, 'model-list', provider], + queryFn: () => get<{ data: ModelItem[] }>(`/workspaces/current/model-providers/${provider}/models`), + }) +} From 1e62768eed1b792f7cd7d654b73a7976ba622371 Mon Sep 17 00:00:00 2001 From: JzoNg Date: Sat, 9 Nov 2024 12:51:10 +0800 Subject: [PATCH 02/68] useQuery in action list --- .../plugin-detail-panel/action-list.tsx | 63 +++++++++--------- web/service/use-tools.ts | 65 ++++++++++++++++--- 2 files changed, 87 insertions(+), 41 deletions(-) diff --git a/web/app/components/plugins/plugin-detail-panel/action-list.tsx b/web/app/components/plugins/plugin-detail-panel/action-list.tsx index c90f1ffb0d..609e7d1306 100644 --- a/web/app/components/plugins/plugin-detail-panel/action-list.tsx +++ b/web/app/components/plugins/plugin-detail-panel/action-list.tsx @@ -1,5 +1,4 @@ import React, { useState } from 'react' -import useSWR from 'swr' import { useTranslation } from 'react-i18next' import { usePluginPageContext } from '@/app/components/plugins/plugin-page/context' import { useAppContext } from '@/context/app-context' @@ -9,28 +8,39 @@ import Indicator from '@/app/components/header/indicator' import ToolItem from '@/app/components/tools/provider/tool-item' import ConfigCredential from '@/app/components/tools/setting/build-in/config-credentials' import { - fetchBuiltInToolList, - fetchCollectionDetail, - removeBuiltInToolCredential, - updateBuiltInToolCredential, -} from '@/service/tools' + useBuiltinProviderInfo, + useBuiltinTools, + useInvalidateBuiltinProviderInfo, + useRemoveProviderCredentials, + useUpdateProviderCredentials, +} from '@/service/use-tools' const ActionList = () => { const { t } = useTranslation() const { isCurrentWorkspaceManager } = useAppContext() const currentPluginDetail = usePluginPageContext(v => v.currentPluginDetail) - const { data: provider } = useSWR( - `builtin/${currentPluginDetail.plugin_id}/${currentPluginDetail.name}`, - fetchCollectionDetail, - ) - const { data } = useSWR( - `${currentPluginDetail.plugin_id}/${currentPluginDetail.name}`, - fetchBuiltInToolList, - ) + const { data: provider } = useBuiltinProviderInfo(`${currentPluginDetail.plugin_id}/${currentPluginDetail.name}`) + const invalidateProviderInfo = useInvalidateBuiltinProviderInfo() + const { data } = useBuiltinTools(`${currentPluginDetail.plugin_id}/${currentPluginDetail.name}`) const [showSettingAuth, setShowSettingAuth] = useState(false) - const handleCredentialSettingUpdate = () => {} + const handleCredentialSettingUpdate = () => { + invalidateProviderInfo(`${currentPluginDetail.plugin_id}/${currentPluginDetail.name}`) + Toast.notify({ + type: 'success', + message: t('common.api.actionSuccess'), + }) + setShowSettingAuth(false) + } + + const { mutate: updatePermission } = useUpdateProviderCredentials({ + onSuccess: handleCredentialSettingUpdate, + }) + + const { mutate: removePermission } = useRemoveProviderCredentials({ + onSuccess: handleCredentialSettingUpdate, + }) if (!data || !provider) return null @@ -77,24 +87,11 @@ const ActionList = () => { setShowSettingAuth(false)} - onSaved={async (value) => { - await updateBuiltInToolCredential(provider.name, value) - Toast.notify({ - type: 'success', - message: t('common.api.actionSuccess'), - }) - handleCredentialSettingUpdate() - setShowSettingAuth(false) - }} - onRemove={async () => { - await removeBuiltInToolCredential(provider.name) - Toast.notify({ - type: 'success', - message: t('common.api.actionSuccess'), - }) - handleCredentialSettingUpdate() - setShowSettingAuth(false) - }} + onSaved={async value => updatePermission({ + providerName: provider.name, + credentials: value, + })} + onRemove={async () => removePermission(provider.name)} /> )} diff --git a/web/service/use-tools.ts b/web/service/use-tools.ts index fb01888e7f..0d0f816b3e 100644 --- a/web/service/use-tools.ts +++ b/web/service/use-tools.ts @@ -1,14 +1,13 @@ -import { get } from './base' +import { get, post } from './base' import type { + Collection, Tool, } from '@/app/components/tools/types' import type { ToolWithProvider } from '@/app/components/workflow/types' import { - useQueryClient, -} from '@tanstack/react-query' - -import { + useMutation, useQuery, + useQueryClient, } from '@tanstack/react-query' const NAME_SPACE = 'tools' @@ -45,9 +44,59 @@ export const useAllWorkflowTools = () => { }) } -export const useBuiltInTools = (collectionName: string) => { +export const useBuiltinProviderInfo = (providerName: string) => { return useQuery({ - queryKey: [NAME_SPACE, 'builtIn', collectionName], - queryFn: () => get(`/workspaces/current/tool-provider/builtin/${collectionName}/tools`), + queryKey: [NAME_SPACE, 'builtin-provider-info', providerName], + queryFn: () => get(`/workspaces/current/tool-provider/builtin/${providerName}/info`), + }) +} + +export const useInvalidateBuiltinProviderInfo = () => { + const queryClient = useQueryClient() + return (providerName: string) => { + queryClient.invalidateQueries( + { + queryKey: [NAME_SPACE, 'builtin-provider-info', providerName], + }) + } +} + +export const useBuiltinTools = (providerName: string) => { + return useQuery({ + queryKey: [NAME_SPACE, 'builtin-provider-tools', providerName], + queryFn: () => get(`/workspaces/current/tool-provider/builtin/${providerName}/tools`), + }) +} + +export const useUpdateProviderCredentials = ({ + onSuccess, +}: { + onSuccess?: () => void +}) => { + return useMutation({ + mutationFn: (payload: { providerName: string, credentials: Record }) => { + const { providerName, credentials } = payload + return post(`/workspaces/current/tool-provider/builtin/${providerName}/update`, { + body: { + credentials, + }, + }) + }, + onSuccess, + }) +} + +export const useRemoveProviderCredentials = ({ + onSuccess, +}: { + onSuccess?: () => void +}) => { + return useMutation({ + mutationFn: (providerName: string) => { + return post(`/workspaces/current/tool-provider/builtin/${providerName}/delete`, { + body: {}, + }) + }, + onSuccess, }) } From 5e81150b22786fc6b7c7c3b9ff4c8e3dc0536d07 Mon Sep 17 00:00:00 2001 From: JzoNg Date: Sat, 9 Nov 2024 14:44:48 +0800 Subject: [PATCH 03/68] useQuery for endpoints --- .../plugin-detail-panel/endpoint-card.tsx | 101 +++++------- .../plugin-detail-panel/endpoint-list.tsx | 54 +++---- web/app/components/plugins/types.ts | 11 +- web/service/plugins.ts | 35 ---- web/service/use-endpoints.ts | 149 ++++++++++++++++++ web/service/use-tools.ts | 2 + 6 files changed, 212 insertions(+), 140 deletions(-) create mode 100644 web/service/use-endpoints.ts diff --git a/web/app/components/plugins/plugin-detail-panel/endpoint-card.tsx b/web/app/components/plugins/plugin-detail-panel/endpoint-card.tsx index 1a984b4eda..14e9abef9b 100644 --- a/web/app/components/plugins/plugin-detail-panel/endpoint-card.tsx +++ b/web/app/components/plugins/plugin-detail-panel/endpoint-card.tsx @@ -13,11 +13,11 @@ import Indicator from '@/app/components/header/indicator' import Switch from '@/app/components/base/switch' import Toast from '@/app/components/base/toast' import { - deleteEndpoint, - disableEndpoint, - enableEndpoint, - updateEndpoint, -} from '@/service/plugins' + useDeleteEndpoint, + useDisableEndpoint, + useEnableEndpoint, + useUpdateEndpoint, +} from '@/service/use-endpoints' type Props = { data: EndpointListItem @@ -32,43 +32,34 @@ const EndpointCard = ({ const [active, setActive] = useState(data.enabled) const endpointID = data.id + // switch const [isShowDisableConfirm, { setTrue: showDisableConfirm, setFalse: hideDisableConfirm, }] = useBoolean(false) - const activeEndpoint = async () => { - try { - await enableEndpoint({ - url: '/workspaces/current/endpoints/enable', - endpointID, - }) + const { mutate: enableEndpoint } = useEnableEndpoint({ + onSuccess: async () => { await handleChange() - } - catch (error: any) { - console.error(error) + }, + onError: () => { Toast.notify({ type: 'error', message: t('common.actionMsg.modifiedUnsuccessfully') }) setActive(false) - } - } - const inactiveEndpoint = async () => { - try { - await disableEndpoint({ - url: '/workspaces/current/endpoints/disable', - endpointID, - }) + }, + }) + const { mutate: disableEndpoint } = useDisableEndpoint({ + onSuccess: async () => { await handleChange() hideDisableConfirm() - } - catch (error) { - console.error(error) + }, + onError: () => { Toast.notify({ type: 'error', message: t('common.actionMsg.modifiedUnsuccessfully') }) - setActive(true) - } - } + setActive(false) + }, + }) const handleSwitch = (state: boolean) => { if (state) { setActive(true) - activeEndpoint() + enableEndpoint(endpointID) } else { setActive(false) @@ -76,30 +67,26 @@ const EndpointCard = ({ } } + // delete const [isShowDeleteConfirm, { setTrue: showDeleteConfirm, setFalse: hideDeleteConfirm, }] = useBoolean(false) - const handleDelete = async () => { - try { - await deleteEndpoint({ - url: '/workspaces/current/endpoints/delete', - endpointID, - }) + const { mutate: deleteEndpoint } = useDeleteEndpoint({ + onSuccess: async () => { await handleChange() hideDeleteConfirm() - } - catch (error) { - console.error(error) + }, + onError: () => { Toast.notify({ type: 'error', message: t('common.actionMsg.modifiedUnsuccessfully') }) - } - } + }, + }) + // update const [isShowEndpointModal, { setTrue: showEndpointModalConfirm, setFalse: hideEndpointModalConfirm, }] = useBoolean(false) - const formSchemas = useMemo(() => { return toolCredentialToFormSchemas([NAME_FIELD, ...data.declaration.settings]) }, [data.declaration.settings]) @@ -110,27 +97,19 @@ const EndpointCard = ({ } return addDefaultValue(formValue, formSchemas) }, [data.name, data.settings, formSchemas]) - - const handleUpdate = async (state: any) => { - const newName = state.name - delete state.name - try { - await updateEndpoint({ - url: '/workspaces/current/endpoints/update', - body: { - endpoint_id: data.id, - settings: state, - name: newName, - }, - }) + const { mutate: updateEndpoint } = useUpdateEndpoint({ + onSuccess: async () => { await handleChange() hideEndpointModalConfirm() - } - catch (error) { - console.error(error) + }, + onError: () => { Toast.notify({ type: 'error', message: t('common.actionMsg.modifiedUnsuccessfully') }) - } - } + }, + }) + const handleUpdate = (state: any) => updateEndpoint({ + endpointID, + state, + }) return (
@@ -192,7 +171,7 @@ const EndpointCard = ({ hideDisableConfirm() setActive(true) }} - onConfirm={inactiveEndpoint} + onConfirm={() => disableEndpoint(endpointID)} /> )} {isShowDeleteConfirm && ( @@ -201,7 +180,7 @@ const EndpointCard = ({ title={t('plugin.detailPanel.endpointDeleteTip')} content={
{t('plugin.detailPanel.endpointDeleteContent', { name: data.name })}
} onCancel={hideDeleteConfirm} - onConfirm={handleDelete} + onConfirm={() => deleteEndpoint(endpointID)} /> )} {isShowEndpointModal && ( diff --git a/web/app/components/plugins/plugin-detail-panel/endpoint-list.tsx b/web/app/components/plugins/plugin-detail-panel/endpoint-list.tsx index 6323e42365..b5f5d2768e 100644 --- a/web/app/components/plugins/plugin-detail-panel/endpoint-list.tsx +++ b/web/app/components/plugins/plugin-detail-panel/endpoint-list.tsx @@ -1,6 +1,5 @@ import React, { useMemo } from 'react' import { useTranslation } from 'react-i18next' -import useSWR from 'swr' import { useBoolean } from 'ahooks' import { RiAddLine } from '@remixicon/react' import EndpointModal from './endpoint-modal' @@ -12,9 +11,10 @@ import Tooltip from '@/app/components/base/tooltip' import Toast from '@/app/components/base/toast' import { usePluginPageContext } from '@/app/components/plugins/plugin-page/context' import { - createEndpoint, - fetchEndpointList, -} from '@/service/plugins' + useCreateEndpoint, + useEndpointList, + useInvalidateEndpointList, +} from '@/service/use-endpoints' import cn from '@/utils/classnames' type Props = { @@ -25,17 +25,9 @@ const EndpointList = ({ showTopBorder }: Props) => { const pluginDetail = usePluginPageContext(v => v.currentPluginDetail) const pluginUniqueID = pluginDetail.plugin_unique_identifier const declaration = pluginDetail.declaration.endpoint - const { data, mutate } = useSWR( - { - url: '/workspaces/current/endpoints/list/plugin', - params: { - plugin_id: pluginDetail.plugin_id, - page: 1, - page_size: 100, - }, - }, - fetchEndpointList, - ) + const { data } = useEndpointList(pluginDetail.plugin_id) + const invalidateEndpointList = useInvalidateEndpointList() + const [isShowEndpointModal, { setTrue: showEndpointModal, setFalse: hideEndpointModal, @@ -45,26 +37,20 @@ const EndpointList = ({ showTopBorder }: Props) => { return toolCredentialToFormSchemas([NAME_FIELD, ...declaration.settings]) }, [declaration.settings]) - const handleCreate = async (state: any) => { - const newName = state.name - delete state.name - try { - await createEndpoint({ - url: '/workspaces/current/endpoints/create', - body: { - plugin_unique_identifier: pluginUniqueID, - settings: state, - name: newName, - }, - }) - await mutate() + const { mutate: createEndpoint } = useCreateEndpoint({ + onSuccess: async () => { + await invalidateEndpointList(pluginDetail.plugin_id) hideEndpointModal() - } - catch (error) { - console.error(error) + }, + onError: () => { Toast.notify({ type: 'error', message: t('common.actionMsg.modifiedUnsuccessfully') }) - } - } + }, + }) + + const handleCreate = (state: any) => createEndpoint({ + pluginUniqueID, + state, + }) if (!data) return null @@ -92,7 +78,7 @@ const EndpointList = ({ showTopBorder }: Props) => { invalidateEndpointList(pluginDetail.plugin_id)} /> ))}
diff --git a/web/app/components/plugins/types.ts b/web/app/components/plugins/types.ts index 629b9b7582..40627f67a3 100644 --- a/web/app/components/plugins/types.ts +++ b/web/app/components/plugins/types.ts @@ -194,19 +194,10 @@ export type GitHubUrlInfo = { } // endpoint -export type CreateEndpointRequest = { - plugin_unique_identifier: string - settings: Record - name: string -} export type EndpointOperationResponse = { result: 'success' | 'error' } -export type EndpointsRequest = { - page_size: number - page: number - plugin_id: string -} + export type EndpointsResponse = { endpoints: EndpointListItem[] has_more: boolean diff --git a/web/service/plugins.ts b/web/service/plugins.ts index 3e5d872bf2..999ed4f1b9 100644 --- a/web/service/plugins.ts +++ b/web/service/plugins.ts @@ -1,10 +1,6 @@ import type { Fetcher } from 'swr' import { get, getMarketplace, post, upload } from './base' import type { - CreateEndpointRequest, - EndpointOperationResponse, - EndpointsRequest, - EndpointsResponse, InstallPackageResponse, Permissions, PluginDeclaration, @@ -12,7 +8,6 @@ import type { PluginTasksResponse, TaskStatusResponse, UninstallPluginResponse, - UpdateEndpointRequest, uploadGitHubResponse, } from '@/app/components/plugins/types' import type { @@ -20,36 +15,6 @@ import type { MarketplaceCollectionsResponse, } from '@/app/components/plugins/marketplace/types' -export const createEndpoint: Fetcher = ({ url, body }) => { - // url = /workspaces/current/endpoints/create - return post(url, { body }) -} - -export const fetchEndpointList: Fetcher = ({ url, params }) => { - // url = /workspaces/current/endpoints/list/plugin?plugin_id=xxx - return get(url, { params }) -} - -export const deleteEndpoint: Fetcher = ({ url, endpointID }) => { - // url = /workspaces/current/endpoints/delete - return post(url, { body: { endpoint_id: endpointID } }) -} - -export const updateEndpoint: Fetcher = ({ url, body }) => { - // url = /workspaces/current/endpoints/update - return post(url, { body }) -} - -export const enableEndpoint: Fetcher = ({ url, endpointID }) => { - // url = /workspaces/current/endpoints/enable - return post(url, { body: { endpoint_id: endpointID } }) -} - -export const disableEndpoint: Fetcher = ({ url, endpointID }) => { - // url = /workspaces/current/endpoints/disable - return post(url, { body: { endpoint_id: endpointID } }) -} - export const uploadPackageFile = async (file: File) => { const formData = new FormData() formData.append('pkg', file) diff --git a/web/service/use-endpoints.ts b/web/service/use-endpoints.ts new file mode 100644 index 0000000000..43a82480b9 --- /dev/null +++ b/web/service/use-endpoints.ts @@ -0,0 +1,149 @@ +import { get, post } from './base' +import type { + EndpointsResponse, +} from '@/app/components/plugins/types' +import { + useMutation, + useQuery, + useQueryClient, +} from '@tanstack/react-query' + +const NAME_SPACE = 'endpoints' + +export const useEndpointList = (pluginID: string) => { + return useQuery({ + queryKey: [NAME_SPACE, 'list', pluginID], + queryFn: () => get('/workspaces/current/endpoints/list/plugin', { + params: { + plugin_id: pluginID, + page: 1, + page_size: 100, + }, + }), + }) +} + +export const useInvalidateEndpointList = () => { + const queryClient = useQueryClient() + return (pluginID: string) => { + queryClient.invalidateQueries( + { + queryKey: [NAME_SPACE, 'list', pluginID], + }) + } +} + +export const useCreateEndpoint = ({ + onSuccess, + onError, +}: { + onSuccess?: () => void + onError?: (error: any) => void +}) => { + return useMutation({ + mutationKey: [NAME_SPACE, 'create'], + mutationFn: (payload: { pluginUniqueID: string, state: Record }) => { + const { pluginUniqueID, state } = payload + const newName = state.name + delete state.name + return post('/workspaces/current/endpoints/create', { + body: { + plugin_unique_identifier: pluginUniqueID, + settings: state, + name: newName, + }, + }) + }, + onSuccess, + onError, + }) +} + +export const useUpdateEndpoint = ({ + onSuccess, + onError, +}: { + onSuccess?: () => void + onError?: (error: any) => void +}) => { + return useMutation({ + mutationKey: [NAME_SPACE, 'update'], + mutationFn: (payload: { endpointID: string, state: Record }) => { + const { endpointID, state } = payload + const newName = state.name + delete state.name + return post('/workspaces/current/endpoints/update', { + body: { + endpoint_id: endpointID, + settings: state, + name: newName, + }, + }) + }, + onSuccess, + onError, + }) +} + +export const useDeleteEndpoint = ({ + onSuccess, + onError, +}: { + onSuccess?: () => void + onError?: (error: any) => void +}) => { + return useMutation({ + mutationKey: [NAME_SPACE, 'delete'], + mutationFn: (endpointID: string) => { + return post('/workspaces/current/endpoints/delete', { + body: { + endpoint_id: endpointID, + }, + }) + }, + onSuccess, + onError, + }) +} + +export const useEnableEndpoint = ({ + onSuccess, + onError, +}: { + onSuccess?: () => void + onError?: (error: any) => void +}) => { + return useMutation({ + mutationKey: [NAME_SPACE, 'enable'], + mutationFn: (endpointID: string) => { + return post('/workspaces/current/endpoints/enable', { + body: { + endpoint_id: endpointID, + }, + }) + }, + onSuccess, + onError, + }) +} + +export const useDisableEndpoint = ({ + onSuccess, + onError, +}: { + onSuccess?: () => void + onError?: (error: any) => void +}) => { + return useMutation({ + mutationKey: [NAME_SPACE, 'disable'], + mutationFn: (endpointID: string) => { + return post('/workspaces/current/endpoints/disable', { + body: { + endpoint_id: endpointID, + }, + }) + }, + onSuccess, + onError, + }) +} diff --git a/web/service/use-tools.ts b/web/service/use-tools.ts index 0d0f816b3e..3c34de3be9 100644 --- a/web/service/use-tools.ts +++ b/web/service/use-tools.ts @@ -74,6 +74,7 @@ export const useUpdateProviderCredentials = ({ onSuccess?: () => void }) => { return useMutation({ + mutationKey: [NAME_SPACE, 'update-provider-credentials'], mutationFn: (payload: { providerName: string, credentials: Record }) => { const { providerName, credentials } = payload return post(`/workspaces/current/tool-provider/builtin/${providerName}/update`, { @@ -92,6 +93,7 @@ export const useRemoveProviderCredentials = ({ onSuccess?: () => void }) => { return useMutation({ + mutationKey: [NAME_SPACE, 'remove-provider-credentials'], mutationFn: (providerName: string) => { return post(`/workspaces/current/tool-provider/builtin/${providerName}/delete`, { body: {}, From 66b08e653e8ef42b33b6583251ec015e913e1d6c Mon Sep 17 00:00:00 2001 From: StyleZhang Date: Mon, 11 Nov 2024 12:27:13 +0800 Subject: [PATCH 04/68] fix: credentials: --- web/service/fetch.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/web/service/fetch.ts b/web/service/fetch.ts index 46e0e6295d..b70a13c6ca 100644 --- a/web/service/fetch.ts +++ b/web/service/fetch.ts @@ -158,10 +158,10 @@ async function base(url: string, options: FetchOptionType = {}, otherOptions: ], }, })(fetchPathname, { - credentials: isMarketplaceAPI - ? 'omit' - : (options.credentials || 'include'), ...init, + credentials: isMarketplaceAPI + ? undefined + : (options.credentials || 'include'), retry: { methods: [], }, From 822c18cb766bf5273f57a00cca68e1241a56db4e Mon Sep 17 00:00:00 2001 From: StyleZhang Date: Mon, 11 Nov 2024 12:27:58 +0800 Subject: [PATCH 05/68] fix: credentials: --- web/service/fetch.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/service/fetch.ts b/web/service/fetch.ts index b70a13c6ca..6551fa5793 100644 --- a/web/service/fetch.ts +++ b/web/service/fetch.ts @@ -160,7 +160,7 @@ async function base(url: string, options: FetchOptionType = {}, otherOptions: })(fetchPathname, { ...init, credentials: isMarketplaceAPI - ? undefined + ? 'omit' : (options.credentials || 'include'), retry: { methods: [], From f47b5ce63a633dbe181a7ac23468d61e1460855c Mon Sep 17 00:00:00 2001 From: Joel Date: Mon, 11 Nov 2024 13:00:41 +0800 Subject: [PATCH 06/68] chore: install plugin by local use use query --- .../install-from-local-package/steps/install.tsx | 4 +++- web/service/plugins.ts | 6 ------ web/service/use-plugins.ts | 10 ++++++++++ 3 files changed, 13 insertions(+), 7 deletions(-) diff --git a/web/app/components/plugins/install-plugin/install-from-local-package/steps/install.tsx b/web/app/components/plugins/install-plugin/install-from-local-package/steps/install.tsx index da5357d87d..b48922bdb9 100644 --- a/web/app/components/plugins/install-plugin/install-from-local-package/steps/install.tsx +++ b/web/app/components/plugins/install-plugin/install-from-local-package/steps/install.tsx @@ -8,7 +8,7 @@ import Button from '@/app/components/base/button' import { Trans, useTranslation } from 'react-i18next' import { RiLoader2Line } from '@remixicon/react' import Badge, { BadgeState } from '@/app/components/base/badge/index' -import { installPackageFromLocal } from '@/service/plugins' +import { useInstallPackageFromLocal } from '@/service/use-plugins' import checkTaskStatus from '../../base/check-task-status' import { usePluginTasksStore } from '@/app/components/plugins/plugin-page/store' @@ -33,6 +33,8 @@ const Installed: FC = ({ }) => { const { t } = useTranslation() const [isInstalling, setIsInstalling] = React.useState(false) + const { mutateAsync: installPackageFromLocal } = useInstallPackageFromLocal() + const { check, stop, diff --git a/web/service/plugins.ts b/web/service/plugins.ts index 999ed4f1b9..0b10196096 100644 --- a/web/service/plugins.ts +++ b/web/service/plugins.ts @@ -24,12 +24,6 @@ export const uploadPackageFile = async (file: File) => { }, false, '/workspaces/current/plugin/upload/pkg') } -export const installPackageFromLocal = async (uniqueIdentifier: string) => { - return post('/workspaces/current/plugin/install/pkg', { - body: { plugin_unique_identifiers: [uniqueIdentifier] }, - }) -} - export const updateFromMarketPlace = async (body: Record) => { return post('/workspaces/current/plugin/upgrade/marketplace', { body, diff --git a/web/service/use-plugins.ts b/web/service/use-plugins.ts index 2274250b58..3b72bee919 100644 --- a/web/service/use-plugins.ts +++ b/web/service/use-plugins.ts @@ -43,6 +43,16 @@ export const useInstallPackageFromMarketPlace = () => { }) } +export const useInstallPackageFromLocal = () => { + return useMutation({ + mutationFn: (uniqueIdentifier: string) => { + return post('/workspaces/current/plugin/install/pkg', { + body: { plugin_unique_identifiers: [uniqueIdentifier] }, + }) + }, + }) +} + export const useDebugKey = () => { return useQuery({ queryKey: [NAME_SPACE, 'debugKey'], From 810443c5119436e3187782509e2bb9416a9a1605 Mon Sep 17 00:00:00 2001 From: Yi Date: Mon, 11 Nov 2024 17:21:25 +0800 Subject: [PATCH 07/68] chore: update the upgrade button and add premium badge component --- .../icons/assets/public/common/highlight.svg | 9 +++ .../assets/public/common/sparkles-soft.svg | 6 ++ .../icons/src/image/llm/BaichuanTextCn.tsx | 2 +- .../base/icons/src/image/llm/Minimax.tsx | 2 +- .../base/icons/src/image/llm/MinimaxText.tsx | 2 +- .../base/icons/src/image/llm/Tongyi.tsx | 2 +- .../base/icons/src/image/llm/TongyiText.tsx | 2 +- .../base/icons/src/image/llm/TongyiTextCn.tsx | 2 +- .../base/icons/src/image/llm/Wxyy.tsx | 2 +- .../base/icons/src/image/llm/WxyyText.tsx | 2 +- .../base/icons/src/image/llm/WxyyTextCn.tsx | 2 +- .../icons/src/public/common/Highlight.json | 67 ++++++++++++++++ .../icons/src/public/common/Highlight.tsx | 16 ++++ .../base/icons/src/public/common/Lock.json | 38 +++++++++ .../base/icons/src/public/common/Lock.tsx | 16 ++++ .../icons/src/public/common/SparklesSoft.json | 47 +++++++++++ .../icons/src/public/common/SparklesSoft.tsx | 16 ++++ .../base/icons/src/public/common/index.ts | 3 + .../components/base/premium-badge/index.css | 48 ++++++++++++ .../components/base/premium-badge/index.tsx | 78 +++++++++++++++++++ .../workplace-selector/index.tsx | 15 +++- web/app/components/header/index.tsx | 17 +++- .../steps/selectPackage.tsx | 1 - 23 files changed, 381 insertions(+), 14 deletions(-) create mode 100644 web/app/components/base/icons/assets/public/common/highlight.svg create mode 100644 web/app/components/base/icons/assets/public/common/sparkles-soft.svg create mode 100644 web/app/components/base/icons/src/public/common/Highlight.json create mode 100644 web/app/components/base/icons/src/public/common/Highlight.tsx create mode 100644 web/app/components/base/icons/src/public/common/Lock.json create mode 100644 web/app/components/base/icons/src/public/common/Lock.tsx create mode 100644 web/app/components/base/icons/src/public/common/SparklesSoft.json create mode 100644 web/app/components/base/icons/src/public/common/SparklesSoft.tsx create mode 100644 web/app/components/base/premium-badge/index.css create mode 100644 web/app/components/base/premium-badge/index.tsx diff --git a/web/app/components/base/icons/assets/public/common/highlight.svg b/web/app/components/base/icons/assets/public/common/highlight.svg new file mode 100644 index 0000000000..f4b809040b --- /dev/null +++ b/web/app/components/base/icons/assets/public/common/highlight.svg @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/web/app/components/base/icons/assets/public/common/sparkles-soft.svg b/web/app/components/base/icons/assets/public/common/sparkles-soft.svg new file mode 100644 index 0000000000..37f3072df7 --- /dev/null +++ b/web/app/components/base/icons/assets/public/common/sparkles-soft.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/web/app/components/base/icons/src/image/llm/BaichuanTextCn.tsx b/web/app/components/base/icons/src/image/llm/BaichuanTextCn.tsx index 5206d02622..85280607a7 100644 --- a/web/app/components/base/icons/src/image/llm/BaichuanTextCn.tsx +++ b/web/app/components/base/icons/src/image/llm/BaichuanTextCn.tsx @@ -2,8 +2,8 @@ // DON NOT EDIT IT MANUALLY import * as React from 'react' -import s from './BaichuanTextCn.module.css' import cn from '@/utils/classnames' +import s from './BaichuanTextCn.module.css' const Icon = React.forwardRef, HTMLSpanElement>>(( { className, ...restProps }, diff --git a/web/app/components/base/icons/src/image/llm/Minimax.tsx b/web/app/components/base/icons/src/image/llm/Minimax.tsx index 7b75ff6f61..ea8c87a188 100644 --- a/web/app/components/base/icons/src/image/llm/Minimax.tsx +++ b/web/app/components/base/icons/src/image/llm/Minimax.tsx @@ -2,8 +2,8 @@ // DON NOT EDIT IT MANUALLY import * as React from 'react' -import s from './Minimax.module.css' import cn from '@/utils/classnames' +import s from './Minimax.module.css' const Icon = React.forwardRef, HTMLSpanElement>>(( { className, ...restProps }, diff --git a/web/app/components/base/icons/src/image/llm/MinimaxText.tsx b/web/app/components/base/icons/src/image/llm/MinimaxText.tsx index 490a977517..b6dfba4f70 100644 --- a/web/app/components/base/icons/src/image/llm/MinimaxText.tsx +++ b/web/app/components/base/icons/src/image/llm/MinimaxText.tsx @@ -2,8 +2,8 @@ // DON NOT EDIT IT MANUALLY import * as React from 'react' -import s from './MinimaxText.module.css' import cn from '@/utils/classnames' +import s from './MinimaxText.module.css' const Icon = React.forwardRef, HTMLSpanElement>>(( { className, ...restProps }, diff --git a/web/app/components/base/icons/src/image/llm/Tongyi.tsx b/web/app/components/base/icons/src/image/llm/Tongyi.tsx index 543b4ce63d..2fc2c8b000 100644 --- a/web/app/components/base/icons/src/image/llm/Tongyi.tsx +++ b/web/app/components/base/icons/src/image/llm/Tongyi.tsx @@ -2,8 +2,8 @@ // DON NOT EDIT IT MANUALLY import * as React from 'react' -import s from './Tongyi.module.css' import cn from '@/utils/classnames' +import s from './Tongyi.module.css' const Icon = React.forwardRef, HTMLSpanElement>>(( { className, ...restProps }, diff --git a/web/app/components/base/icons/src/image/llm/TongyiText.tsx b/web/app/components/base/icons/src/image/llm/TongyiText.tsx index 16e3920780..ca8cd5793b 100644 --- a/web/app/components/base/icons/src/image/llm/TongyiText.tsx +++ b/web/app/components/base/icons/src/image/llm/TongyiText.tsx @@ -2,8 +2,8 @@ // DON NOT EDIT IT MANUALLY import * as React from 'react' -import s from './TongyiText.module.css' import cn from '@/utils/classnames' +import s from './TongyiText.module.css' const Icon = React.forwardRef, HTMLSpanElement>>(( { className, ...restProps }, diff --git a/web/app/components/base/icons/src/image/llm/TongyiTextCn.tsx b/web/app/components/base/icons/src/image/llm/TongyiTextCn.tsx index c14d323c60..605a254b57 100644 --- a/web/app/components/base/icons/src/image/llm/TongyiTextCn.tsx +++ b/web/app/components/base/icons/src/image/llm/TongyiTextCn.tsx @@ -2,8 +2,8 @@ // DON NOT EDIT IT MANUALLY import * as React from 'react' -import s from './TongyiTextCn.module.css' import cn from '@/utils/classnames' +import s from './TongyiTextCn.module.css' const Icon = React.forwardRef, HTMLSpanElement>>(( { className, ...restProps }, diff --git a/web/app/components/base/icons/src/image/llm/Wxyy.tsx b/web/app/components/base/icons/src/image/llm/Wxyy.tsx index 312e325043..c73ddffa1c 100644 --- a/web/app/components/base/icons/src/image/llm/Wxyy.tsx +++ b/web/app/components/base/icons/src/image/llm/Wxyy.tsx @@ -2,8 +2,8 @@ // DON NOT EDIT IT MANUALLY import * as React from 'react' -import s from './Wxyy.module.css' import cn from '@/utils/classnames' +import s from './Wxyy.module.css' const Icon = React.forwardRef, HTMLSpanElement>>(( { className, ...restProps }, diff --git a/web/app/components/base/icons/src/image/llm/WxyyText.tsx b/web/app/components/base/icons/src/image/llm/WxyyText.tsx index fd618e8d34..1ba8335fd2 100644 --- a/web/app/components/base/icons/src/image/llm/WxyyText.tsx +++ b/web/app/components/base/icons/src/image/llm/WxyyText.tsx @@ -2,8 +2,8 @@ // DON NOT EDIT IT MANUALLY import * as React from 'react' -import s from './WxyyText.module.css' import cn from '@/utils/classnames' +import s from './WxyyText.module.css' const Icon = React.forwardRef, HTMLSpanElement>>(( { className, ...restProps }, diff --git a/web/app/components/base/icons/src/image/llm/WxyyTextCn.tsx b/web/app/components/base/icons/src/image/llm/WxyyTextCn.tsx index 01acc26241..02616573e5 100644 --- a/web/app/components/base/icons/src/image/llm/WxyyTextCn.tsx +++ b/web/app/components/base/icons/src/image/llm/WxyyTextCn.tsx @@ -2,8 +2,8 @@ // DON NOT EDIT IT MANUALLY import * as React from 'react' -import s from './WxyyTextCn.module.css' import cn from '@/utils/classnames' +import s from './WxyyTextCn.module.css' const Icon = React.forwardRef, HTMLSpanElement>>(( { className, ...restProps }, diff --git a/web/app/components/base/icons/src/public/common/Highlight.json b/web/app/components/base/icons/src/public/common/Highlight.json new file mode 100644 index 0000000000..d18386eb01 --- /dev/null +++ b/web/app/components/base/icons/src/public/common/Highlight.json @@ -0,0 +1,67 @@ +{ + "icon": { + "type": "element", + "isRootNode": true, + "name": "svg", + "attributes": { + "xmlns": "http://www.w3.org/2000/svg", + "width": "46", + "height": "24", + "viewBox": "0 0 46 24", + "fill": "none" + }, + "children": [ + { + "type": "element", + "name": "path", + "attributes": { + "opacity": "0.5", + "d": "M-6.5 8C-6.5 3.58172 -2.91828 0 1.5 0H45.5L33.0248 24H1.49999C-2.91829 24 -6.5 20.4183 -6.5 16V8Z", + "fill": "url(#paint0_linear_6333_42118)" + }, + "children": [] + }, + { + "type": "element", + "name": "defs", + "attributes": {}, + "children": [ + { + "type": "element", + "name": "linearGradient", + "attributes": { + "id": "paint0_linear_6333_42118", + "x1": "1.81679", + "y1": "5.47784e-07", + "x2": "101.257", + "y2": "30.3866", + "gradientUnits": "userSpaceOnUse" + }, + "children": [ + { + "type": "element", + "name": "stop", + "attributes": { + "stop-color": "white", + "stop-opacity": "0.12" + }, + "children": [] + }, + { + "type": "element", + "name": "stop", + "attributes": { + "offset": "1", + "stop-color": "white", + "stop-opacity": "0.3" + }, + "children": [] + } + ] + } + ] + } + ] + }, + "name": "Highlight" +} \ No newline at end of file diff --git a/web/app/components/base/icons/src/public/common/Highlight.tsx b/web/app/components/base/icons/src/public/common/Highlight.tsx new file mode 100644 index 0000000000..379f38f78e --- /dev/null +++ b/web/app/components/base/icons/src/public/common/Highlight.tsx @@ -0,0 +1,16 @@ +// GENERATE BY script +// DON NOT EDIT IT MANUALLY + +import * as React from 'react' +import data from './Highlight.json' +import IconBase from '@/app/components/base/icons/IconBase' +import type { IconBaseProps, IconData } from '@/app/components/base/icons/IconBase' + +const Icon = React.forwardRef, Omit>(( + props, + ref, +) => ) + +Icon.displayName = 'Highlight' + +export default Icon diff --git a/web/app/components/base/icons/src/public/common/Lock.json b/web/app/components/base/icons/src/public/common/Lock.json new file mode 100644 index 0000000000..24af41a73d --- /dev/null +++ b/web/app/components/base/icons/src/public/common/Lock.json @@ -0,0 +1,38 @@ +{ + "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": "lock" + }, + "children": [ + { + "type": "element", + "name": "path", + "attributes": { + "id": "Vector", + "fill-rule": "evenodd", + "clip-rule": "evenodd", + "d": "M8 1.75C6.27411 1.75 4.875 3.14911 4.875 4.875V6.125C3.83947 6.125 3 6.96444 3 8V12.375C3 13.4106 3.83947 14.25 4.875 14.25H11.125C12.1606 14.25 13 13.4106 13 12.375V8C13 6.96444 12.1606 6.125 11.125 6.125V4.875C11.125 3.14911 9.72587 1.75 8 1.75ZM9.875 6.125V4.875C9.875 3.83947 9.03556 3 8 3C6.96444 3 6.125 3.83947 6.125 4.875V6.125H9.875ZM8 8.625C8.34519 8.625 8.625 8.90481 8.625 9.25V11.125C8.625 11.4702 8.34519 11.75 8 11.75C7.65481 11.75 7.375 11.4702 7.375 11.125V9.25C7.375 8.90481 7.65481 8.625 8 8.625Z", + "fill": "#155AEF" + }, + "children": [] + } + ] + } + ] + }, + "name": "Lock" +} \ No newline at end of file diff --git a/web/app/components/base/icons/src/public/common/Lock.tsx b/web/app/components/base/icons/src/public/common/Lock.tsx new file mode 100644 index 0000000000..3a2ed38574 --- /dev/null +++ b/web/app/components/base/icons/src/public/common/Lock.tsx @@ -0,0 +1,16 @@ +// GENERATE BY script +// DON NOT EDIT IT MANUALLY + +import * as React from 'react' +import data from './Lock.json' +import IconBase from '@/app/components/base/icons/IconBase' +import type { IconBaseProps, IconData } from '@/app/components/base/icons/IconBase' + +const Icon = React.forwardRef, Omit>(( + props, + ref, +) => ) + +Icon.displayName = 'Lock' + +export default Icon diff --git a/web/app/components/base/icons/src/public/common/SparklesSoft.json b/web/app/components/base/icons/src/public/common/SparklesSoft.json new file mode 100644 index 0000000000..e22cec82a3 --- /dev/null +++ b/web/app/components/base/icons/src/public/common/SparklesSoft.json @@ -0,0 +1,47 @@ +{ + "icon": { + "type": "element", + "isRootNode": true, + "name": "svg", + "attributes": { + "width": "14", + "height": "14", + "viewBox": "0 0 14 14", + "fill": "none", + "xmlns": "http://www.w3.org/2000/svg" + }, + "children": [ + { + "type": "element", + "name": "g", + "attributes": { + "id": "sparkles-soft" + }, + "children": [ + { + "type": "element", + "name": "path", + "attributes": { + "id": "Vector", + "opacity": "0.5", + "d": "M10.9963 1.36798C10.9839 1.25339 10.8909 1.16677 10.7802 1.16666C10.6695 1.16654 10.5763 1.25295 10.5636 1.36752C10.5045 1.90085 10.3525 2.26673 10.1143 2.5149C9.87599 2.76307 9.52476 2.92145 9.01275 2.98296C8.90277 2.99618 8.81983 3.09324 8.81995 3.20856C8.82006 3.32388 8.90322 3.42076 9.0132 3.43373C9.51653 3.49312 9.87583 3.65148 10.1201 3.90135C10.3631 4.14986 10.518 4.51523 10.563 5.04321C10.573 5.16035 10.6673 5.25012 10.7802 5.24999C10.8931 5.24986 10.9872 5.15987 10.9969 5.0427C11.0401 4.52364 11.1949 4.15004 11.4394 3.89528C11.684 3.64052 12.0426 3.47926 12.5409 3.43433C12.6534 3.42419 12.7398 3.32619 12.7399 3.20858C12.7401 3.09097 12.6539 2.99277 12.5414 2.98236C12.0346 2.93546 11.6838 2.77407 11.4452 2.52098C11.2054 2.2665 11.0533 1.89229 10.9963 1.36798Z", + "fill": "#F5F8FF" + }, + "children": [] + }, + { + "type": "element", + "name": "path", + "attributes": { + "id": "Vector_2", + "d": "M7.13646 2.85102C7.10442 2.55638 6.8653 2.33365 6.5806 2.33334C6.29595 2.33304 6.05633 2.55526 6.02374 2.84984C5.87186 4.22127 5.48089 5.1621 4.86827 5.80025C4.25565 6.43838 3.35245 6.84566 2.03587 7.00386C1.75307 7.03781 1.53975 7.28742 1.54004 7.58393C1.54033 7.88049 1.75415 8.12958 2.03701 8.16294C3.33132 8.31566 4.25509 8.72289 4.88328 9.36543C5.50807 10.0045 5.90647 10.9439 6.02222 12.3016C6.04793 12.6029 6.29035 12.8337 6.58066 12.8333C6.87102 12.833 7.11294 12.6016 7.13797 12.3003C7.24885 10.9656 7.64695 10.0049 8.27583 9.34979C8.90477 8.69471 9.82698 8.28002 11.1083 8.16452C11.3976 8.13844 11.6197 7.88644 11.62 7.58399C11.6204 7.28159 11.3988 7.02906 11.1096 7.00229C9.8062 6.88171 8.90432 6.46673 8.29084 5.81589C7.674 5.16152 7.28306 4.19926 7.13646 2.85102Z", + "fill": "#F5F8FF" + }, + "children": [] + } + ] + } + ] + }, + "name": "SparklesSoft" +} \ No newline at end of file diff --git a/web/app/components/base/icons/src/public/common/SparklesSoft.tsx b/web/app/components/base/icons/src/public/common/SparklesSoft.tsx new file mode 100644 index 0000000000..dd422c400f --- /dev/null +++ b/web/app/components/base/icons/src/public/common/SparklesSoft.tsx @@ -0,0 +1,16 @@ +// GENERATE BY script +// DON NOT EDIT IT MANUALLY + +import * as React from 'react' +import data from './SparklesSoft.json' +import IconBase from '@/app/components/base/icons/IconBase' +import type { IconBaseProps, IconData } from '@/app/components/base/icons/IconBase' + +const Icon = React.forwardRef, Omit>(( + props, + ref, +) => ) + +Icon.displayName = 'SparklesSoft' + +export default Icon diff --git a/web/app/components/base/icons/src/public/common/index.ts b/web/app/components/base/icons/src/public/common/index.ts index b20668175c..788d275f92 100644 --- a/web/app/components/base/icons/src/public/common/index.ts +++ b/web/app/components/base/icons/src/public/common/index.ts @@ -2,8 +2,11 @@ export { default as D } from './D' export { default as DiagonalDividingLine } from './DiagonalDividingLine' export { default as Dify } from './Dify' export { default as Github } from './Github' +export { default as Highlight } from './Highlight' export { default as Line3 } from './Line3' +export { default as Lock } from './Lock' export { default as MessageChatSquare } from './MessageChatSquare' export { default as MultiPathRetrieval } from './MultiPathRetrieval' export { default as NTo1Retrieval } from './NTo1Retrieval' export { default as Notion } from './Notion' +export { default as SparklesSoft } from './SparklesSoft' diff --git a/web/app/components/base/premium-badge/index.css b/web/app/components/base/premium-badge/index.css new file mode 100644 index 0000000000..d92a2a2b2a --- /dev/null +++ b/web/app/components/base/premium-badge/index.css @@ -0,0 +1,48 @@ +@tailwind components; + +@layer components { + .premium-badge { + @apply inline-flex justify-center items-center rounded-full border border-white/95 text-white + } + + /* m is for the regular button */ + .premium-badge-m { + @apply border shadow-lg !p-1 h-6 w-auto + } + + .premium-badge-s { + @apply border-[0.5px] shadow-xs !px-1 !py-[3px] h-[18px] w-auto + } + + .premium-badge-blue { + @apply bg-gradient-to-r from-[#5289ffe6] to-[#155aefe6] bg-util-colors-blue-blue-200 + } + + .premium-badge-indigo { + @apply bg-gradient-to-r from-[#8098f9e6] to-[#444ce7e6] bg-util-colors-indigo-indigo-200 + } + + .premium-badge-gray { + @apply bg-gradient-to-r from-[#98a2b2e6] to-[#676f83e6] bg-util-colors-gray-gray-200 + } + + .premium-badge-orange { + @apply bg-gradient-to-r from-[#ff692ee6] to-[#e04f16e6] bg-util-colors-orange-orange-200 + } + + .premium-badge-blue.allowHover:hover { + @apply bg-gradient-to-r from-[#296dffe6] to-[#004aebe6] bg-util-colors-blue-blue-300 cursor-pointer + } + + .premium-badge-indigo.allowHover:hover { + @apply bg-gradient-to-r from-[#6172f3e6] to-[#2d31a6e6] bg-util-colors-indigo-indigo-300 cursor-pointer + } + + .premium-badge-gray.allowHover:hover { + @apply bg-gradient-to-r from-[#676f83e6] to-[#354052e6] bg-util-colors-gray-gray-300 cursor-pointer + } + + .premium-badge-orange.allowHover:hover { + @apply bg-gradient-to-r from-[#ff4405e6] to-[#b93815e6] bg-util-colors-orange-orange-300 cursor-pointer + } +} \ No newline at end of file diff --git a/web/app/components/base/premium-badge/index.tsx b/web/app/components/base/premium-badge/index.tsx new file mode 100644 index 0000000000..1af527cd16 --- /dev/null +++ b/web/app/components/base/premium-badge/index.tsx @@ -0,0 +1,78 @@ +import type { CSSProperties, ReactNode } from 'react' +import React from 'react' +import { type VariantProps, cva } from 'class-variance-authority' +import classNames from '@/utils/classnames' +import './index.css' +import { Highlight } from '../icons/src/public/common' + +const PremiumBadgeVariants = cva( + 'premium-badge', + { + variants: { + size: { + s: 'premium-badge-s', + m: 'premium-badge-m', + }, + color: { + blue: 'premium-badge-blue', + indigo: 'premium-badge-indigo', + gray: 'premium-badge-gray', + orange: 'premium-badge-orange', + }, + allowHover: { + true: 'allowHover', + false: '', + }, + }, + defaultVariants: { + size: 'm', + color: 'blue', + allowHover: false, + }, + }, +) + +type PremiumBadgeProps = { + size?: 's' | 'm' + color?: 'blue' | 'indigo' | 'gray' | 'orange' + allowHover?: boolean + styleCss?: CSSProperties + children?: ReactNode +} & React.HTMLAttributes & VariantProps + +const PremiumBadge: React.FC = ({ + className, + size, + color, + allowHover, + styleCss, + children, + ...props +}) => { + return ( +
+ {children} + +
+ ) +} +PremiumBadge.displayName = 'PremiumBadge' + +export default PremiumBadge +export { PremiumBadge, PremiumBadgeVariants } diff --git a/web/app/components/header/account-dropdown/workplace-selector/index.tsx b/web/app/components/header/account-dropdown/workplace-selector/index.tsx index ac9a5370ab..f7ecb67c5c 100644 --- a/web/app/components/header/account-dropdown/workplace-selector/index.tsx +++ b/web/app/components/header/account-dropdown/workplace-selector/index.tsx @@ -6,13 +6,17 @@ import { RiArrowDownSLine } from '@remixicon/react' import cn from '@/utils/classnames' import { switchWorkspace } from '@/service/common' import { useWorkspacesContext } from '@/context/workspace-context' +import { useProviderContext } from '@/context/provider-context' import { ToastContext } from '@/app/components/base/toast' +import PremiumBadge from '@/app/components/base/premium-badge' const WorkplaceSelector = () => { const { t } = useTranslation() + const { plan } = useProviderContext() const { notify } = useContext(ToastContext) const { workspaces } = useWorkspacesContext() const currentWorkspace = workspaces.find(v => v.current) + const isFreePlan = plan.type === 'sandbox' const handleSwitchWorkspace = async (tenant_id: string) => { try { if (currentWorkspace?.id === tenant_id) @@ -57,7 +61,7 @@ const WorkplaceSelector = () => { `, )} > -
+
{t('common.userProfile.workspace')}
@@ -66,6 +70,15 @@ const WorkplaceSelector = () => {
handleSwitchWorkspace(workspace.id)}>
{workspace.name[0].toLocaleUpperCase()}
{workspace.name}
+ { + +
+ + {plan.type.toUpperCase()} + +
+
+ }
)) } diff --git a/web/app/components/header/index.tsx b/web/app/components/header/index.tsx index 8f41dee938..8d1eda8a78 100644 --- a/web/app/components/header/index.tsx +++ b/web/app/components/header/index.tsx @@ -4,7 +4,8 @@ import Link from 'next/link' import { useBoolean } from 'ahooks' import { useSelectedLayoutSegment } from 'next/navigation' import { Bars3Icon } from '@heroicons/react/20/solid' -import HeaderBillingBtn from '../billing/header-billing-btn' +import { SparklesSoft } from '@/app/components/base/icons/src/public/common' +import PremiumBadge from '../base/premium-badge' import AccountDropdown from './account-dropdown' import AppNav from './app-nav' import DatasetNav from './dataset-nav' @@ -69,7 +70,14 @@ const Header = () => { {enableBilling && (
- + + +
+ + Upgrade + +
+
)}
@@ -84,7 +92,10 @@ const Header = () => {
/
{enableBilling && (
- + + +
Upgrade
+
)} diff --git a/web/app/components/plugins/install-plugin/install-from-github/steps/selectPackage.tsx b/web/app/components/plugins/install-plugin/install-from-github/steps/selectPackage.tsx index 9b83c39867..47a5d86498 100644 --- a/web/app/components/plugins/install-plugin/install-from-github/steps/selectPackage.tsx +++ b/web/app/components/plugins/install-plugin/install-from-github/steps/selectPackage.tsx @@ -48,7 +48,6 @@ const SelectPackage: React.FC = ({ const handleUploadPackage = async () => { if (isUploading) return setIsUploading(true) - try { const repo = repoUrl.replace('https://github.com/', '') await handleUpload(repo, selectedVersion, selectedPackage, (GitHubPackage) => { From a8e8e3675606c762b88dc58bcfe769176c669cc7 Mon Sep 17 00:00:00 2001 From: Yi Date: Mon, 11 Nov 2024 18:00:44 +0800 Subject: [PATCH 08/68] chore: update the upgrade button --- web/app/components/base/premium-badge/index.css | 2 +- web/app/components/header/index.tsx | 6 +++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/web/app/components/base/premium-badge/index.css b/web/app/components/base/premium-badge/index.css index d92a2a2b2a..be8f9e6ae6 100644 --- a/web/app/components/base/premium-badge/index.css +++ b/web/app/components/base/premium-badge/index.css @@ -2,7 +2,7 @@ @layer components { .premium-badge { - @apply inline-flex justify-center items-center rounded-full border border-white/95 text-white + @apply inline-flex justify-center items-center rounded-full border box-border border-[rgba(255,255,255,0.8)] text-white } /* m is for the regular button */ diff --git a/web/app/components/header/index.tsx b/web/app/components/header/index.tsx index 8d1eda8a78..c6befcc0d9 100644 --- a/web/app/components/header/index.tsx +++ b/web/app/components/header/index.tsx @@ -94,7 +94,11 @@ const Header = () => {
-
Upgrade
+
+ + Upgrade + +
)} From 27f794e1972db529b8b3a7ab6a889986ed4edd11 Mon Sep 17 00:00:00 2001 From: StyleZhang Date: Mon, 11 Nov 2024 18:17:44 +0800 Subject: [PATCH 09/68] feat: plugin task --- .../install-from-github/steps/loaded.tsx | 2 +- .../steps/install.tsx | 2 +- .../components/plugins/plugin-page/index.tsx | 8 +- .../plugins/plugin-page/install-info.tsx | 86 ----------- .../plugins/plugin-page/plugin-tasks/hooks.ts | 27 ++++ .../plugin-page/plugin-tasks/index.tsx | 137 ++++++++++++++++++ .../{store.tsx => plugin-tasks/store.ts} | 2 +- .../update-plugin/from-market-place.tsx | 2 +- web/i18n/en-US/plugin.ts | 6 + web/i18n/zh-Hans/plugin.ts | 6 + 10 files changed, 183 insertions(+), 95 deletions(-) delete mode 100644 web/app/components/plugins/plugin-page/install-info.tsx create mode 100644 web/app/components/plugins/plugin-page/plugin-tasks/hooks.ts create mode 100644 web/app/components/plugins/plugin-page/plugin-tasks/index.tsx rename web/app/components/plugins/plugin-page/{store.tsx => plugin-tasks/store.ts} (94%) diff --git a/web/app/components/plugins/install-plugin/install-from-github/steps/loaded.tsx b/web/app/components/plugins/install-plugin/install-from-github/steps/loaded.tsx index dce2e735c8..c046957263 100644 --- a/web/app/components/plugins/install-plugin/install-from-github/steps/loaded.tsx +++ b/web/app/components/plugins/install-plugin/install-from-github/steps/loaded.tsx @@ -9,7 +9,7 @@ import { pluginManifestToCardPluginProps } from '../../utils' import { useTranslation } from 'react-i18next' import { installPackageFromGitHub, uninstallPlugin } from '@/service/plugins' import { RiLoader2Line } from '@remixicon/react' -import { usePluginTasksStore } from '@/app/components/plugins/plugin-page/store' +import { usePluginTasksStore } from '@/app/components/plugins/plugin-page/plugin-tasks/store' import checkTaskStatus from '../../base/check-task-status' import { parseGitHubUrl } from '../../utils' diff --git a/web/app/components/plugins/install-plugin/install-from-local-package/steps/install.tsx b/web/app/components/plugins/install-plugin/install-from-local-package/steps/install.tsx index b48922bdb9..4d776f4430 100644 --- a/web/app/components/plugins/install-plugin/install-from-local-package/steps/install.tsx +++ b/web/app/components/plugins/install-plugin/install-from-local-package/steps/install.tsx @@ -10,7 +10,7 @@ import { RiLoader2Line } from '@remixicon/react' import Badge, { BadgeState } from '@/app/components/base/badge/index' import { useInstallPackageFromLocal } from '@/service/use-plugins' import checkTaskStatus from '../../base/check-task-status' -import { usePluginTasksStore } from '@/app/components/plugins/plugin-page/store' +import { usePluginTasksStore } from '@/app/components/plugins/plugin-page/plugin-tasks/store' const i18nPrefix = 'plugin.installModal' diff --git a/web/app/components/plugins/plugin-page/index.tsx b/web/app/components/plugins/plugin-page/index.tsx index f889bbc363..013c9bc9e2 100644 --- a/web/app/components/plugins/plugin-page/index.tsx +++ b/web/app/components/plugins/plugin-page/index.tsx @@ -16,8 +16,8 @@ import InstallPluginDropdown from './install-plugin-dropdown' import { useUploader } from './use-uploader' import usePermission from './use-permission' import DebugInfo from './debug-info' -import { usePluginTasksStore } from './store' -import InstallInfo from './install-info' +import { usePluginTasksStore } from './plugin-tasks/store' +import PluginTasks from './plugin-tasks' import Button from '@/app/components/base/button' import TabSlider from '@/app/components/base/tab-slider' import Tooltip from '@/app/components/base/tooltip' @@ -102,8 +102,6 @@ const PluginPage = ({ const options = usePluginPageContext(v => v.options) const [activeTab, setActiveTab] = usePluginPageContext(v => [v.activeTab, v.setActiveTab]) const { enable_marketplace } = useAppContextSelector(s => s.systemFeatures) - const [installed, total] = [2, 3] // Replace this with the actual progress - const progressPercentage = (installed / total) * 100 const uploaderProps = useUploader({ onFileChange: setCurrentFile, @@ -142,7 +140,7 @@ const PluginPage = ({ />
- + {canManagement && ( setActiveTab('discover')} diff --git a/web/app/components/plugins/plugin-page/install-info.tsx b/web/app/components/plugins/plugin-page/install-info.tsx deleted file mode 100644 index bb0a31f4be..0000000000 --- a/web/app/components/plugins/plugin-page/install-info.tsx +++ /dev/null @@ -1,86 +0,0 @@ -import { - useState, -} from 'react' -import { - RiCheckboxCircleFill, - RiErrorWarningFill, - RiInstallLine, -} from '@remixicon/react' -import { - PortalToFollowElem, - PortalToFollowElemContent, - PortalToFollowElemTrigger, -} from '@/app/components/base/portal-to-follow-elem' -import Tooltip from '@/app/components/base/tooltip' -import Button from '@/app/components/base/button' -// import ProgressCircle from '@/app/components/base/progress-bar/progress-circle' -import { useMemo } from 'react' -import cn from '@/utils/classnames' - -const InstallInfo = () => { - const [open, setOpen] = useState(false) - const status = 'error' - const statusError = useMemo(() => status === 'error', [status]) - - return ( -
- - setOpen(v => !v)}> - -
- -
- {/* */} - -
-
-
-
- -
-
3 plugins failed to install
-
-
- -
-
- DuckDuckGo Search -
- -
-
-
-
-
- ) -} - -export default InstallInfo diff --git a/web/app/components/plugins/plugin-page/plugin-tasks/hooks.ts b/web/app/components/plugins/plugin-page/plugin-tasks/hooks.ts new file mode 100644 index 0000000000..3a198f5068 --- /dev/null +++ b/web/app/components/plugins/plugin-page/plugin-tasks/hooks.ts @@ -0,0 +1,27 @@ +import { usePluginTasksStore } from './store' +import { TaskStatus } from '@/app/components/plugins/types' +import type { PluginStatus } from '@/app/components/plugins/types' + +export const usePluginTaskStatus = () => { + const pluginTasks = usePluginTasksStore(s => s.pluginTasks) + const allPlugins = pluginTasks.map(task => task.plugins).flat() + const errorPlugins: PluginStatus[] = [] + const successPlugins: PluginStatus[] = [] + const runningPlugins: PluginStatus[] = [] + + allPlugins.forEach((plugin) => { + if (plugin.status === TaskStatus.running) + runningPlugins.push(plugin) + if (plugin.status === TaskStatus.failed) + errorPlugins.push(plugin) + if (plugin.status === TaskStatus.success) + successPlugins.push(plugin) + }) + + return { + errorPlugins, + successPlugins, + runningPlugins, + totalPluginsLength: allPlugins.length, + } +} diff --git a/web/app/components/plugins/plugin-page/plugin-tasks/index.tsx b/web/app/components/plugins/plugin-page/plugin-tasks/index.tsx new file mode 100644 index 0000000000..bde4371839 --- /dev/null +++ b/web/app/components/plugins/plugin-page/plugin-tasks/index.tsx @@ -0,0 +1,137 @@ +import { + useMemo, + useState, +} from 'react' +import { + RiCheckboxCircleFill, + RiErrorWarningFill, + RiInstallLine, +} from '@remixicon/react' +import { useTranslation } from 'react-i18next' +import { usePluginTaskStatus } from './hooks' +import { + PortalToFollowElem, + PortalToFollowElemContent, + PortalToFollowElemTrigger, +} from '@/app/components/base/portal-to-follow-elem' +import Tooltip from '@/app/components/base/tooltip' +import Button from '@/app/components/base/button' +import ProgressCircle from '@/app/components/base/progress-bar/progress-circle' +import cn from '@/utils/classnames' + +const PluginTasks = () => { + const { t } = useTranslation() + const [open, setOpen] = useState(false) + const { + errorPlugins, + runningPlugins, + successPlugins, + totalPluginsLength, + } = usePluginTaskStatus() + + const isInstalling = runningPlugins.length > 0 && errorPlugins.length === 0 && successPlugins.length === 0 + const isInstallingWithError = errorPlugins.length > 0 && errorPlugins.length < totalPluginsLength + const isSuccess = successPlugins.length === totalPluginsLength && totalPluginsLength > 0 + const isFailed = errorPlugins.length === totalPluginsLength && totalPluginsLength > 0 + + const tip = useMemo(() => { + if (isInstalling) + return t('plugin.task.installing', { installingLength: runningPlugins.length, totalLength: totalPluginsLength }) + + if (isInstallingWithError) + return t('plugin.task.installingWithError', { installingLength: runningPlugins.length, totalLength: totalPluginsLength, errorLength: errorPlugins.length }) + + if (isFailed) + return t('plugin.task.installError', { errorLength: errorPlugins.length }) + }, [isInstalling, isInstallingWithError, isFailed, errorPlugins, runningPlugins, totalPluginsLength, t]) + + return ( +
+ + { + if (isFailed || isInstallingWithError) + setOpen(v => !v) + }} + > + +
+ +
+ { + isInstalling && ( + + ) + } + { + isInstallingWithError && ( + + ) + } + { + isSuccess && ( + + ) + } + { + isFailed && ( + + ) + } +
+
+
+
+ +
+
{t('plugin.task.installedError')}
+
+
+ +
+
+ DuckDuckGo Search +
+ +
+
+
+
+
+ ) +} + +export default PluginTasks diff --git a/web/app/components/plugins/plugin-page/store.tsx b/web/app/components/plugins/plugin-page/plugin-tasks/store.ts similarity index 94% rename from web/app/components/plugins/plugin-page/store.tsx rename to web/app/components/plugins/plugin-page/plugin-tasks/store.ts index 25074b973f..403d529a39 100644 --- a/web/app/components/plugins/plugin-page/store.tsx +++ b/web/app/components/plugins/plugin-page/plugin-tasks/store.ts @@ -1,5 +1,5 @@ import { create } from 'zustand' -import type { PluginTask } from '../types' +import type { PluginTask } from '@/app/components/plugins/types' import { fetchPluginTasks } from '@/service/plugins' type PluginTasksStore = { diff --git a/web/app/components/plugins/update-plugin/from-market-place.tsx b/web/app/components/plugins/update-plugin/from-market-place.tsx index e0b54a1acf..0454617a2e 100644 --- a/web/app/components/plugins/update-plugin/from-market-place.tsx +++ b/web/app/components/plugins/update-plugin/from-market-place.tsx @@ -12,7 +12,7 @@ import { pluginManifestToCardPluginProps } from '@/app/components/plugins/instal import useGetIcon from '../install-plugin/base/use-get-icon' import { updateFromMarketPlace } from '@/service/plugins' import checkTaskStatus from '@/app/components/plugins/install-plugin/base/check-task-status' -import { usePluginTasksStore } from '@/app/components/plugins/plugin-page/store' +import { usePluginTasksStore } from '@/app/components/plugins/plugin-page/plugin-tasks/store' const i18nPrefix = 'plugin.upgrade' diff --git a/web/i18n/en-US/plugin.ts b/web/i18n/en-US/plugin.ts index 5c3bdc6f29..abcf3480bb 100644 --- a/web/i18n/en-US/plugin.ts +++ b/web/i18n/en-US/plugin.ts @@ -124,6 +124,12 @@ const translation = { inDifyMarketplace: 'in Dify Marketplace', moreFrom: 'More from Marketplace', }, + task: { + installing: 'Installing {{installingLength}}/{{totalLength}} plugins...', + installingWithError: 'Installing {{installingLength}} of {{totalLength}} plugins, {{errorLength}} failed, click to view', + installError: '{{errorLength}} plugins failed to install, click to view', + installedError: '{{errorLength}} plugins failed to install', + }, } export default translation diff --git a/web/i18n/zh-Hans/plugin.ts b/web/i18n/zh-Hans/plugin.ts index c1f7bb7600..3355cb742c 100644 --- a/web/i18n/zh-Hans/plugin.ts +++ b/web/i18n/zh-Hans/plugin.ts @@ -124,6 +124,12 @@ const translation = { inDifyMarketplace: '在 Dify 市场中', moreFrom: '更多来自市场', }, + task: { + installing: '{{installingLength}}/{{totalLength}} 插件安装中...', + installingWithError: '{{installingLength}}/{{totalLength}} 插件安装中,{{errorLength}} 安装失败。点击查看', + installError: '{{errorLength}} 个插件安装失败,点击查看', + installedError: '{{errorLength}} 个插件安装失败', + }, } export default translation From 7e39565fd25d80ff94530519c3370632eca24f4a Mon Sep 17 00:00:00 2001 From: Joel Date: Tue, 12 Nov 2024 11:48:27 +0800 Subject: [PATCH 10/68] feat: handle on update show update modal --- .../plugin-detail-panel/detail-header.tsx | 47 +++++++++++++++++-- web/app/components/plugins/types.ts | 1 + .../update-plugin/from-market-place.tsx | 37 +++++++++------ 3 files changed, 67 insertions(+), 18 deletions(-) diff --git a/web/app/components/plugins/plugin-detail-panel/detail-header.tsx b/web/app/components/plugins/plugin-detail-panel/detail-header.tsx index b40f264967..97e61b66d8 100644 --- a/web/app/components/plugins/plugin-detail-panel/detail-header.tsx +++ b/web/app/components/plugins/plugin-detail-panel/detail-header.tsx @@ -28,7 +28,7 @@ import { Github } from '@/app/components/base/icons/src/public/common' import { uninstallPlugin } from '@/service/plugins' import { useGetLanguage } from '@/context/i18n' import { useModalContext } from '@/context/modal-context' - +import UpdateFromMarketplace from '@/app/components/plugins/update-plugin/from-market-place' import { API_PREFIX, MARKETPLACE_URL_PREFIX } from '@/config' import cn from '@/utils/classnames' @@ -55,17 +55,35 @@ const DetailHeader = ({ source, tenant_id, version, + latest_unique_identifier, latest_version, meta, } = detail const { author, name, label, description, icon, verified } = detail.declaration const isFromGitHub = source === PluginSource.github + const isFromMarketplace = source === PluginSource.marketplace const hasNewVersion = useMemo(() => { - return source === PluginSource.github && latest_version !== version - }, [source, latest_version, version]) + if (isFromGitHub) + return latest_version !== version + + if (isFromMarketplace) + return !!latest_version && latest_version !== version + + return false + }, [isFromGitHub, isFromMarketplace, latest_version, version]) + + const [isShowUpdateModal, { + setTrue: showUpdateModal, + setFalse: hideUpdateModal, + }] = useBoolean(false) const handleUpdate = async () => { + if (isFromMarketplace) { + showUpdateModal() + return + } + try { const fetchedReleases = await fetchReleases(author, name) if (fetchedReleases.length === 0) @@ -106,6 +124,11 @@ const DetailHeader = ({ } } + const handleUpdatedFromMarketplace = () => { + onUpdate() + hideUpdateModal() + } + const [isShowPluginInfo, { setTrue: showPluginInfo, setFalse: hidePluginInfo, @@ -222,6 +245,24 @@ const DetailHeader = ({ isDisabled={deleting} /> )} + { + isShowUpdateModal && ( + + ) + }
) } diff --git a/web/app/components/plugins/types.ts b/web/app/components/plugins/types.ts index 40627f67a3..a869b2c556 100644 --- a/web/app/components/plugins/types.ts +++ b/web/app/components/plugins/types.ts @@ -100,6 +100,7 @@ export type PluginDetail = { endpoints_active: number version: string latest_version: string + latest_unique_identifier: string source: PluginSource meta?: MetaData } diff --git a/web/app/components/plugins/update-plugin/from-market-place.tsx b/web/app/components/plugins/update-plugin/from-market-place.tsx index 0454617a2e..c76b154c40 100644 --- a/web/app/components/plugins/update-plugin/from-market-place.tsx +++ b/web/app/components/plugins/update-plugin/from-market-place.tsx @@ -69,23 +69,30 @@ const UpdatePluginModal: FC = ({ const handleConfirm = useCallback(async () => { if (uploadStep === UploadStep.notStarted) { setUploadStep(UploadStep.upgrading) - const { - all_installed: isInstalled, - task_id: taskId, - } = await updateFromMarketPlace({ - original_plugin_unique_identifier: originalPackageInfo.id, - new_plugin_unique_identifier: targetPackageInfo.id, - }) - if (isInstalled) { + try { + const { + all_installed: isInstalled, + task_id: taskId, + } = await updateFromMarketPlace({ + original_plugin_unique_identifier: originalPackageInfo.id, + new_plugin_unique_identifier: targetPackageInfo.id, + }) + + if (isInstalled) { + onSave() + return + } + setPluginTasksWithPolling() + await check({ + taskId, + pluginUniqueIdentifier: targetPackageInfo.id, + }) onSave() - return } - setPluginTasksWithPolling() - await check({ - taskId, - pluginUniqueIdentifier: targetPackageInfo.id, - }) - onSave() + catch (e) { + setUploadStep(UploadStep.notStarted) + } + return } if (uploadStep === UploadStep.installed) { onSave() From a059660ed862809d6deec7b25a0eef903b89580b Mon Sep 17 00:00:00 2001 From: AkaraChen Date: Tue, 12 Nov 2024 14:24:18 +0800 Subject: [PATCH 11/68] fix: sse post no token --- web/service/base.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/web/service/base.ts b/web/service/base.ts index 061e8dcd2c..e2dd3314a5 100644 --- a/web/service/base.ts +++ b/web/service/base.ts @@ -326,10 +326,15 @@ export const ssePost = ( } = otherOptions const abortController = new AbortController() + const token = localStorage.getItem('console_token') + const options = Object.assign({}, baseOptions, { method: 'POST', signal: abortController.signal, - }, fetchOptions) + headers: new Headers({ + Authorization: `Bearer ${token}`, + }), + } as RequestInit, fetchOptions) const contentType = (options.headers as Headers).get('Content-Type') if (!contentType) From d4c9c76454f5b32b0e7a06e5634c691877983cd6 Mon Sep 17 00:00:00 2001 From: Joel Date: Tue, 12 Nov 2024 14:31:04 +0800 Subject: [PATCH 12/68] chore: mask the debug key --- web/app/components/plugins/base/key-value-item.tsx | 4 +++- web/app/components/plugins/plugin-page/debug-info.tsx | 4 ++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/web/app/components/plugins/base/key-value-item.tsx b/web/app/components/plugins/base/key-value-item.tsx index c249284bb9..9d6cda18d3 100644 --- a/web/app/components/plugins/base/key-value-item.tsx +++ b/web/app/components/plugins/base/key-value-item.tsx @@ -15,6 +15,7 @@ type Props = { label: string labelWidthClassName?: string value: string + maskedValue?: string valueMaxWidthClassName?: string } @@ -22,6 +23,7 @@ const KeyValueItem: FC = ({ label, labelWidthClassName = 'w-10', value, + maskedValue, valueMaxWidthClassName = 'max-w-[162px]', }) => { const { t } = useTranslation() @@ -49,7 +51,7 @@ const KeyValueItem: FC = ({ {label}
- {value} + {maskedValue || value} diff --git a/web/app/components/plugins/plugin-page/debug-info.tsx b/web/app/components/plugins/plugin-page/debug-info.tsx index 9c777c5dd9..e4d249f3e2 100644 --- a/web/app/components/plugins/plugin-page/debug-info.tsx +++ b/web/app/components/plugins/plugin-page/debug-info.tsx @@ -17,6 +17,9 @@ const DebugInfo: FC = () => { const { t } = useTranslation() const { data: info, isLoading } = useDebugKey() + // info.key likes 4580bdb7-b878-471c-a8a4-bfd760263a53 mask the middle part using *. + const maskedKey = info?.key?.replace(/(.{8})(.*)(.{8})/, '$1********$3') + if (isLoading) return null return ( @@ -40,6 +43,7 @@ const DebugInfo: FC = () => {
From 8203b23df2022c78b33b95bfd9f43e301343a7ed Mon Sep 17 00:00:00 2001 From: Joel Date: Tue, 12 Nov 2024 15:48:00 +0800 Subject: [PATCH 13/68] feat: install bundle struct --- .../install-plugin/install-bundle/index.tsx | 38 +++++++++++++++++++ .../install-bundle/steps/select-package.tsx | 20 ++++++++++ .../steps/uploading.tsx | 1 + 3 files changed, 59 insertions(+) create mode 100644 web/app/components/plugins/install-plugin/install-bundle/index.tsx create mode 100644 web/app/components/plugins/install-plugin/install-bundle/steps/select-package.tsx diff --git a/web/app/components/plugins/install-plugin/install-bundle/index.tsx b/web/app/components/plugins/install-plugin/install-bundle/index.tsx new file mode 100644 index 0000000000..6086f0cbc3 --- /dev/null +++ b/web/app/components/plugins/install-plugin/install-bundle/index.tsx @@ -0,0 +1,38 @@ +'use client' +import type { FC } from 'react' +import React, { useState } from 'react' +import { InstallStep } from '../../types' +import type { PluginDeclaration } from '../../types' +import SelectPackage from './steps/select-package' + +export enum InstallType { + fromLocal = 'fromLocal', + fromMarketplace = 'fromMarketplace', + fromDSL = 'fromDSL', +} + +type Props = { + installType?: InstallType + plugins?: PluginDeclaration[] +} + +const InstallBundle: FC = ({ + installType = InstallType.fromMarketplace, + plugins = [], +}) => { + const [step, setStep] = useState(installType === InstallType.fromMarketplace ? InstallStep.readyToInstall : InstallStep.uploading) + const [selectedPlugins, setSelectedPlugins] = useState([]) + + const handleSelectedPluginsChange = (plugins: PluginDeclaration[]) => { + setSelectedPlugins(plugins) + } + return ( +
+ {step === InstallStep.readyToInstall && ( + + )} +
+ ) +} + +export default React.memo(InstallBundle) diff --git a/web/app/components/plugins/install-plugin/install-bundle/steps/select-package.tsx b/web/app/components/plugins/install-plugin/install-bundle/steps/select-package.tsx new file mode 100644 index 0000000000..70a51c265c --- /dev/null +++ b/web/app/components/plugins/install-plugin/install-bundle/steps/select-package.tsx @@ -0,0 +1,20 @@ +'use client' +import type { FC } from 'react' +import React from 'react' +import type { PluginDeclaration } from '../../../types' + +type Props = { + plugins: PluginDeclaration[], + onChange: (plugins: PluginDeclaration[]) => void +} + +const SelectPackage: FC = ({ + plugins, + onChange, +}) => { + return ( +
+
+ ) +} +export default React.memo(SelectPackage) diff --git a/web/app/components/plugins/install-plugin/install-from-local-package/steps/uploading.tsx b/web/app/components/plugins/install-plugin/install-from-local-package/steps/uploading.tsx index 793977519d..499326c63e 100644 --- a/web/app/components/plugins/install-plugin/install-from-local-package/steps/uploading.tsx +++ b/web/app/components/plugins/install-plugin/install-from-local-package/steps/uploading.tsx @@ -48,6 +48,7 @@ const Uploading: FC = ({ React.useEffect(() => { handleUpload() + // eslint-disable-next-line react-hooks/exhaustive-deps }, []) return ( <> From 7791d290c7696ca95f2c54f8d2bb4a8c358a117f Mon Sep 17 00:00:00 2001 From: twwu Date: Tue, 12 Nov 2024 15:49:00 +0800 Subject: [PATCH 14/68] refactor: update AudioPlayer styles with CSS variables and improve VideoGallery rendering --- .../base/audio-gallery/AudioPlayer.module.css | 26 +++++++++---------- .../components/base/video-gallery/index.tsx | 2 +- 2 files changed, 13 insertions(+), 15 deletions(-) diff --git a/web/app/components/base/audio-gallery/AudioPlayer.module.css b/web/app/components/base/audio-gallery/AudioPlayer.module.css index 6c070e107c..c5dd277fd6 100644 --- a/web/app/components/base/audio-gallery/AudioPlayer.module.css +++ b/web/app/components/base/audio-gallery/AudioPlayer.module.css @@ -2,15 +2,15 @@ display: flex; flex-direction: row; align-items: center; - background-color: #ffffff; + background-color: var(--color-components-chat-input-audio-bg-alt); border-radius: 10px; padding: 8px; min-width: 240px; max-width: 420px; max-height: 40px; backdrop-filter: blur(5px); - border: 1px solid rgba(16, 24, 40, 0.08); - box-shadow: 0 1px 2px rgba(9, 9, 11, 0.05); + border: 1px solid var(--color-components-panel-border-subtle); + box-shadow: 0 1px 2px var(--color-shadow-shadow-3); gap: 8px; } @@ -19,8 +19,8 @@ width: 16px; height: 16px; border-radius: 50%; - background-color: #296DFF; - color: white; + background-color: var(--color-components-button-primary-bg); + color: var(--color-components-chat-input-audio-bg-alt); border: none; cursor: pointer; align-items: center; @@ -30,16 +30,15 @@ } .playButton:hover { - background-color: #3367d6; + background-color: var(--color-components-button-primary-bg-hover); } .playButton:disabled { - background-color: #bdbdbf; + background-color: var(--color-components-button-primary-bg-disabled); } .audioControls { flex-grow: 1; - } .progressBarContainer { @@ -76,8 +75,8 @@ .timeDisplay { /* position: absolute; */ - color: #296DFF; - border-radius: 2px; + color: var(--color-text-accent-secondary); + font-size: 12px; order: 0; height: 100%; width: 50px; @@ -97,7 +96,6 @@ } */ .duration { - background-color: rgba(255, 255, 255, 0.8); padding: 2px 4px; border-radius: 10px; } @@ -114,6 +112,6 @@ } .playButton svg path, -.playButton svg rect{ - fill:currentColor; -} +.playButton svg rect { + fill: currentColor; +} \ No newline at end of file diff --git a/web/app/components/base/video-gallery/index.tsx b/web/app/components/base/video-gallery/index.tsx index a41dfe8e0a..ae2fab8e6f 100644 --- a/web/app/components/base/video-gallery/index.tsx +++ b/web/app/components/base/video-gallery/index.tsx @@ -6,7 +6,7 @@ type Props = { } const VideoGallery: React.FC = ({ srcs }) => { - return (<>
{srcs.map((src, index) => (<>
))}) + return (<>
{srcs.map((src, index) => (
))}) } export default React.memo(VideoGallery) From 07edda8a85683d8f140600c8ba7ab9ccfeb15b0b Mon Sep 17 00:00:00 2001 From: Joel Date: Tue, 12 Nov 2024 15:55:50 +0800 Subject: [PATCH 15/68] feat: add new marketplace env --- docker/docker-compose.yaml | 2 ++ web/Dockerfile | 2 ++ web/docker/entrypoint.sh | 2 ++ 3 files changed, 6 insertions(+) diff --git a/docker/docker-compose.yaml b/docker/docker-compose.yaml index a7cb8576fd..5a963b3beb 100644 --- a/docker/docker-compose.yaml +++ b/docker/docker-compose.yaml @@ -318,6 +318,8 @@ services: environment: CONSOLE_API_URL: ${CONSOLE_API_URL:-} APP_API_URL: ${APP_API_URL:-} + MARKETPLACE_API_URL: ${MARKETPLACE_API_URL:-} + MARKETPLACE_URL: ${MARKETPLACE_URL:-} SENTRY_DSN: ${WEB_SENTRY_DSN:-} NEXT_TELEMETRY_DISABLED: ${NEXT_TELEMETRY_DISABLED:-0} TEXT_GENERATION_TIMEOUT_MS: ${TEXT_GENERATION_TIMEOUT_MS:-60000} diff --git a/web/Dockerfile b/web/Dockerfile index 0610300361..256e601e11 100644 --- a/web/Dockerfile +++ b/web/Dockerfile @@ -41,6 +41,8 @@ ENV EDITION=SELF_HOSTED ENV DEPLOY_ENV=PRODUCTION ENV CONSOLE_API_URL=http://127.0.0.1:5001 ENV APP_API_URL=http://127.0.0.1:5001 +ENV MARKETPLACE_API_URL=http://127.0.0.1:5001 +ENV MARKETPLACE_URL=http://127.0.0.1:5001 ENV PORT=3000 ENV NEXT_TELEMETRY_DISABLED=1 diff --git a/web/docker/entrypoint.sh b/web/docker/entrypoint.sh index ad4b17a476..0e7587d663 100755 --- a/web/docker/entrypoint.sh +++ b/web/docker/entrypoint.sh @@ -16,6 +16,8 @@ export NEXT_PUBLIC_DEPLOY_ENV=${DEPLOY_ENV} export NEXT_PUBLIC_EDITION=${EDITION} export NEXT_PUBLIC_API_PREFIX=${CONSOLE_API_URL}/console/api export NEXT_PUBLIC_PUBLIC_API_PREFIX=${APP_API_URL}/api +export NEXT_PUBLIC_MARKETPLACE_API_PREFIX=${MARKETPLACE_API_URL}/api/v1 +export NEXT_PUBLIC_MARKETPLACE_URL_PREFIX=${MARKETPLACE_URL} export NEXT_PUBLIC_SENTRY_DSN=${SENTRY_DSN} export NEXT_PUBLIC_SITE_ABOUT=${SITE_ABOUT} From 2ba38c6c458d54aa88909a4b8e520d105650963c Mon Sep 17 00:00:00 2001 From: twwu Date: Tue, 12 Nov 2024 16:48:24 +0800 Subject: [PATCH 16/68] feat: add marketplace-divider-bg color variable for dark and light themes --- web/tailwind-common-config.ts | 1 + web/themes/dark.css | 1 + web/themes/light.css | 1 + 3 files changed, 3 insertions(+) diff --git a/web/tailwind-common-config.ts b/web/tailwind-common-config.ts index 35fd22e0a4..c1ec16a6a1 100644 --- a/web/tailwind-common-config.ts +++ b/web/tailwind-common-config.ts @@ -87,6 +87,7 @@ const config = { 'chatbot-bg': 'var(--color-chatbot-bg)', 'chat-bubble-bg': 'var(--color-chat-bubble-bg)', 'workflow-process-bg': 'var(--color-workflow-process-bg)', + 'marketplace-divider-bg': 'var(--color-marketplace-divider-bg)', }, animation: { 'spin-slow': 'spin 2s linear infinite', diff --git a/web/themes/dark.css b/web/themes/dark.css index 6b69342730..08994039eb 100644 --- a/web/themes/dark.css +++ b/web/themes/dark.css @@ -694,4 +694,5 @@ html[data-theme="dark"] { --color-third-party-model-bg-anthropic: #1D1917; --color-third-party-model-bg-default: #0B0B0E; --color-workflow-process-bg: linear-gradient(90deg, rgba(24, 24, 27, 0.25) 0%, rgba(24, 24, 27, 0.04) 100%); + --color-marketplace-divider-bg: linear-gradient(90deg, rgba(200, 206, 218, 0.14) 0%, rgba(0, 0, 0, 0) 100%); } \ No newline at end of file diff --git a/web/themes/light.css b/web/themes/light.css index 0d73875c29..ed563ad594 100644 --- a/web/themes/light.css +++ b/web/themes/light.css @@ -694,4 +694,5 @@ html[data-theme="light"] { --color-third-party-model-bg-anthropic: #EEEDE7; --color-third-party-model-bg-default: #F9FAFB; --color-workflow-process-bg: linear-gradient(90deg, rgba(200, 206, 218, 0.20) 0%, rgba(200, 206, 218, 0.04) 100%); + --color-marketplace-divider-bg: linear-gradient(90deg, rgba(16, 24, 40, 0.08) 0%, rgba(255, 255, 255, 0) 100%); } \ No newline at end of file From f5267d317ef0521e66b6e026b7b8f9eefb000fc8 Mon Sep 17 00:00:00 2001 From: JzoNg Date: Mon, 11 Nov 2024 11:46:36 +0800 Subject: [PATCH 17/68] fix quota of model provider --- .../header/account-setting/model-provider-page/utils.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/app/components/header/account-setting/model-provider-page/utils.ts b/web/app/components/header/account-setting/model-provider-page/utils.ts index 165926b2bb..b8ab0988ae 100644 --- a/web/app/components/header/account-setting/model-provider-page/utils.ts +++ b/web/app/components/header/account-setting/model-provider-page/utils.ts @@ -18,7 +18,7 @@ import { validateModelProvider, } from '@/service/common' -export const MODEL_PROVIDER_QUOTA_GET_PAID = ['anthropic', 'openai', 'azure_openai'] +export const MODEL_PROVIDER_QUOTA_GET_PAID = ['langgenius/anthropic/anthropic', 'langgenius/openai/openai', 'langgenius/azure_openai/azure_openai'] export const DEFAULT_BACKGROUND_COLOR = '#F3F4F6' From 06c4627abb2a00b7fe368ba750ec0018e8aef908 Mon Sep 17 00:00:00 2001 From: JzoNg Date: Mon, 11 Nov 2024 13:40:57 +0800 Subject: [PATCH 18/68] tool selecting in configure --- .../components/app/configuration/base/feature-panel/index.tsx | 4 ++-- .../app/configuration/config/agent/agent-tools/index.tsx | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/web/app/components/app/configuration/base/feature-panel/index.tsx b/web/app/components/app/configuration/base/feature-panel/index.tsx index 017e3bf5fd..dc5fe87ca3 100644 --- a/web/app/components/app/configuration/base/feature-panel/index.tsx +++ b/web/app/components/app/configuration/base/feature-panel/index.tsx @@ -3,7 +3,7 @@ import type { FC, ReactNode } from 'react' import React from 'react' import cn from '@/utils/classnames' -export interface IFeaturePanelProps { +export type IFeaturePanelProps = { className?: string headerIcon?: ReactNode title: ReactNode @@ -23,7 +23,7 @@ const FeaturePanel: FC = ({ children, }) => { return ( -
+
{/* Header */}
diff --git a/web/app/components/app/configuration/config/agent/agent-tools/index.tsx b/web/app/components/app/configuration/config/agent/agent-tools/index.tsx index 57d2e5f632..d83fcb3637 100644 --- a/web/app/components/app/configuration/config/agent/agent-tools/index.tsx +++ b/web/app/components/app/configuration/config/agent/agent-tools/index.tsx @@ -92,6 +92,7 @@ const AgentTools: FC = () => { tool_name: tool.tool_name, tool_label: tool.tool_label, tool_parameters: tool.params, + notAuthor: !(tool as ToolDefaultValue & { is_team_authorization: boolean }).is_team_authorization, enabled: true, }) }) @@ -101,7 +102,7 @@ const AgentTools: FC = () => { return ( <> From 5efcdd6fa7694cd68f3573e257371798584c3981 Mon Sep 17 00:00:00 2001 From: JzoNg Date: Tue, 12 Nov 2024 09:24:35 +0800 Subject: [PATCH 19/68] model parameters --- .../model-provider-page/model-parameter-modal/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/app/components/header/account-setting/model-provider-page/model-parameter-modal/index.tsx b/web/app/components/header/account-setting/model-provider-page/model-parameter-modal/index.tsx index e21aa33d7a..c7cf7dd19d 100644 --- a/web/app/components/header/account-setting/model-provider-page/model-parameter-modal/index.tsx +++ b/web/app/components/header/account-setting/model-provider-page/model-parameter-modal/index.tsx @@ -68,7 +68,7 @@ const stopParameterRule: ModelParameterRule = { }, } -const PROVIDER_WITH_PRESET_TONE = ['openai', 'azure_openai'] +const PROVIDER_WITH_PRESET_TONE = ['langgenius/openai/openai', 'langgenius/azure_openai/azure_openai'] const ModelParameterModal: FC = ({ popupClassName, portalToFollowElemContentClassName, From 75a037bc2a6b4873c092cd7fbc1f9b004ac1bcbc Mon Sep 17 00:00:00 2001 From: JzoNg Date: Tue, 12 Nov 2024 13:33:09 +0800 Subject: [PATCH 20/68] update style of model & parameter selector --- .../model-provider-page/model-icon/index.tsx | 3 +- .../model-parameter-modal/index.tsx | 23 ++++++--------- .../model-parameter-modal/parameter-item.tsx | 29 +++++++++---------- .../presets-parameter.tsx | 20 ++++++------- 4 files changed, 34 insertions(+), 41 deletions(-) diff --git a/web/app/components/header/account-setting/model-provider-page/model-icon/index.tsx b/web/app/components/header/account-setting/model-provider-page/model-icon/index.tsx index a16b101e6a..7960c441ab 100644 --- a/web/app/components/header/account-setting/model-provider-page/model-icon/index.tsx +++ b/web/app/components/header/account-setting/model-provider-page/model-icon/index.tsx @@ -19,11 +19,12 @@ const ModelIcon: FC = ({ }) => { const language = useLanguage() - if (provider?.provider === 'openai' && (modelName?.startsWith('gpt-4') || modelName?.includes('4o'))) + if (provider?.provider.includes('openai') && (modelName?.startsWith('gpt-4') || modelName?.includes('4o'))) return if (provider?.icon_small) { return ( + // eslint-disable-next-line @next/next/no-img-element model-icon = ({ ) } - -
-
-
-
+ +
+
+
+
{t('common.modelProvider.model').toLocaleUpperCase()}
{ !!parameterRules.length && ( -
+
) } { @@ -219,8 +215,8 @@ const ModelParameterModal: FC = ({ } { !isLoading && !!parameterRules.length && ( -
-
{t('common.modelProvider.parameters')}
+
+
{t('common.modelProvider.parameters')}
{ PROVIDER_WITH_PRESET_TONE.includes(provider) && ( @@ -237,7 +233,6 @@ const ModelParameterModal: FC = ({ ].map(parameter => ( handleParamChange(parameter.name, v)} @@ -250,7 +245,7 @@ const ModelParameterModal: FC = ({
{!hideDebugWithMultipleModel && (
onDebugWithMultipleModelChange?.()} > { diff --git a/web/app/components/header/account-setting/model-provider-page/model-parameter-modal/parameter-item.tsx b/web/app/components/header/account-setting/model-provider-page/model-parameter-modal/parameter-item.tsx index 376a08c120..4a4be4b686 100644 --- a/web/app/components/header/account-setting/model-provider-page/model-parameter-modal/parameter-item.tsx +++ b/web/app/components/header/account-setting/model-provider-page/model-parameter-modal/parameter-item.tsx @@ -17,7 +17,6 @@ type ParameterItemProps = { parameterRule: ModelParameterRule value?: ParameterValue onChange?: (value: ParameterValue) => void - className?: string onSwitch?: (checked: boolean, assignValue: ParameterValue) => void isInWorkflow?: boolean } @@ -25,7 +24,6 @@ const ParameterItem: FC = ({ parameterRule, value, onChange, - className, onSwitch, isInWorkflow, }) => { @@ -249,9 +247,20 @@ const ParameterItem: FC = ({ } return ( -
-
-
+
+
+
+ { + !parameterRule.required && parameterRule.name !== 'stop' && ( +
+ +
+ ) + }
= ({ /> ) } - { - !parameterRule.required && parameterRule.name !== 'stop' && ( - - ) - }
{ parameterRule.type === 'tag' && ( diff --git a/web/app/components/header/account-setting/model-provider-page/model-parameter-modal/presets-parameter.tsx b/web/app/components/header/account-setting/model-provider-page/model-parameter-modal/presets-parameter.tsx index de5061ef45..0d9e90853e 100644 --- a/web/app/components/header/account-setting/model-provider-page/model-parameter-modal/presets-parameter.tsx +++ b/web/app/components/header/account-setting/model-provider-page/model-parameter-modal/presets-parameter.tsx @@ -2,12 +2,13 @@ import type { FC } from 'react' import { useCallback } from 'react' import { useTranslation } from 'react-i18next' import { RiArrowDownSLine } from '@remixicon/react' +import Button from '@/app/components/base/button' import Dropdown from '@/app/components/base/dropdown' -import { SlidersH } from '@/app/components/base/icons/src/vender/line/mediaAndDevices' import { Brush01 } from '@/app/components/base/icons/src/vender/solid/editor' import { Scales02 } from '@/app/components/base/icons/src/vender/solid/FinanceAndECommerce' import { Target04 } from '@/app/components/base/icons/src/vender/solid/general' import { TONE_LIST } from '@/config' +import cn from '@/utils/classnames' type PresetsParameterProps = { onSelect: (toneId: number) => void @@ -18,19 +19,16 @@ const PresetsParameter: FC = ({ const { t } = useTranslation() const renderTrigger = useCallback((open: boolean) => { return ( -
- {t('common.modelProvider.loadPresets')} - -
+ + ) - }, []) + }, [t]) const getToneIcon = (toneId: number) => { const className = 'mr-2 w-[14px] h-[14px]' const res = ({ From b188800f1663d11ff2227998dcab04d43787830a Mon Sep 17 00:00:00 2001 From: JzoNg Date: Tue, 12 Nov 2024 16:40:43 +0800 Subject: [PATCH 21/68] model selector in endpoint modal --- .../model-provider-page/declarations.ts | 31 ++++--- .../model-provider-page/model-modal/Form.tsx | 85 +++++++++++++++++-- .../model-provider-page/model-modal/Input.tsx | 10 +-- 3 files changed, 98 insertions(+), 28 deletions(-) diff --git a/web/app/components/header/account-setting/model-provider-page/declarations.ts b/web/app/components/header/account-setting/model-provider-page/declarations.ts index c50a17c6b2..f1b1f8741a 100644 --- a/web/app/components/header/account-setting/model-provider-page/declarations.ts +++ b/web/app/components/header/account-setting/model-provider-page/declarations.ts @@ -1,6 +1,6 @@ export type FormValue = Record -export interface TypeWithI18N { +export type TypeWithI18N = { en_US: T zh_Hans: T [key: string]: T @@ -15,9 +15,12 @@ export enum FormTypeEnum { boolean = 'boolean', files = 'files', file = 'file', + modelSelector = 'model-selector', + toolSelector = 'tool-selector', + appSelector = 'app-selector', } -export interface FormOption { +export type FormOption = { label: TypeWithI18N value: string show_on: FormShowOnObject[] @@ -89,12 +92,12 @@ export enum CustomConfigurationStatusEnum { noConfigure = 'no-configure', } -export interface FormShowOnObject { +export type FormShowOnObject = { variable: string value: string } -export interface CredentialFormSchemaBase { +export type CredentialFormSchemaBase = { variable: string label: TypeWithI18N type: FormTypeEnum @@ -112,7 +115,7 @@ export type CredentialFormSchemaRadio = CredentialFormSchemaBase & { options: Fo export type CredentialFormSchemaSecretInput = CredentialFormSchemaBase & { placeholder?: TypeWithI18N } export type CredentialFormSchema = CredentialFormSchemaTextInput | CredentialFormSchemaSelect | CredentialFormSchemaRadio | CredentialFormSchemaSecretInput -export interface ModelItem { +export type ModelItem = { model: string label: TypeWithI18N model_type: ModelTypeEnum @@ -141,7 +144,7 @@ export enum QuotaUnitEnum { credits = 'credits', } -export interface QuotaConfiguration { +export type QuotaConfiguration = { quota_type: CurrentSystemQuotaTypeEnum quota_unit: QuotaUnitEnum quota_limit: number @@ -150,7 +153,7 @@ export interface QuotaConfiguration { is_valid: boolean } -export interface ModelProvider { +export type ModelProvider = { provider: string label: TypeWithI18N description?: TypeWithI18N @@ -184,7 +187,7 @@ export interface ModelProvider { } } -export interface Model { +export type Model = { provider: string icon_large: TypeWithI18N icon_small: TypeWithI18N @@ -193,7 +196,7 @@ export interface Model { status: ModelStatusEnum } -export interface DefaultModelResponse { +export type DefaultModelResponse = { model: string model_type: ModelTypeEnum provider: { @@ -203,17 +206,17 @@ export interface DefaultModelResponse { } } -export interface DefaultModel { +export type DefaultModel = { provider: string model: string } -export interface CustomConfigurationModelFixedFields { +export type CustomConfigurationModelFixedFields = { __model_name: string __model_type: ModelTypeEnum } -export interface ModelParameterRule { +export type ModelParameterRule = { default?: number | string | boolean | string[] help?: TypeWithI18N label: TypeWithI18N @@ -228,7 +231,7 @@ export interface ModelParameterRule { tagPlaceholder?: TypeWithI18N } -export interface ModelLoadBalancingConfigEntry { +export type ModelLoadBalancingConfigEntry = { /** model balancing config entry id */ id?: string /** is config entry enabled */ @@ -243,7 +246,7 @@ export interface ModelLoadBalancingConfigEntry { ttl?: number } -export interface ModelLoadBalancingConfig { +export type ModelLoadBalancingConfig = { enabled: boolean configs: ModelLoadBalancingConfigEntry[] } diff --git a/web/app/components/header/account-setting/model-provider-page/model-modal/Form.tsx b/web/app/components/header/account-setting/model-provider-page/model-modal/Form.tsx index c0a7be68a6..90d0688db0 100644 --- a/web/app/components/header/account-setting/model-provider-page/model-modal/Form.tsx +++ b/web/app/components/header/account-setting/model-provider-page/model-modal/Form.tsx @@ -1,4 +1,4 @@ -import { useState } from 'react' +import { useCallback, useState } from 'react' import type { FC } from 'react' import { ValidatingTip } from '../../key-validator/ValidateStatus' import type { @@ -17,6 +17,8 @@ import cn from '@/utils/classnames' import { SimpleSelect } from '@/app/components/base/select' import Tooltip from '@/app/components/base/tooltip' import Radio from '@/app/components/base/radio' +import ModelParameterModal from '@/app/components/header/account-setting/model-provider-page/model-parameter-modal' + type FormProps = { className?: string itemClassName?: string @@ -67,6 +69,24 @@ const Form: FC = ({ onChange({ ...value, [key]: val, ...shouldClearVariable }) } + const handleModelChanged = useCallback((key: string, model: { provider: string; modelId: string; mode?: string }) => { + const newValue = { + ...value[key], + provider: model.provider, + name: model.modelId, + mode: model.mode, + } + onChange({ ...value, [key]: newValue }) + }, [onChange, value]) + + const handleCompletionParamsChange = useCallback((key: string, newParams: Record) => { + const newValue = { + ...value[key], + completion_params: newParams, + } + onChange({ ...value, [key]: newValue }) + }, [onChange, value]) + const renderField = (formSchema: CredentialFormSchema) => { const tooltip = formSchema.tooltip const tooltipContent = (tooltip && ( @@ -94,7 +114,7 @@ const Form: FC = ({ const disabled = readonly || (isEditMode && (variable === '__model_type' || variable === '__model_name')) return (
-
+
{label[language] || label.en_US} { required && ( @@ -135,7 +155,7 @@ const Form: FC = ({ return (
-
+
{label[language] || label.en_US} { required && ( @@ -165,7 +185,7 @@ const Form: FC = ({ flex justify-center items-center mr-2 w-4 h-4 border border-gray-300 rounded-full ${value[variable] === option.value && 'border-[5px] border-primary-600'} `} /> -
{option.label[language] || option.label.en_US}
+
{option.label[language] || option.label.en_US}
)) } @@ -176,7 +196,7 @@ const Form: FC = ({ ) } - if (formSchema.type === 'select') { + if (formSchema.type === FormTypeEnum.select) { const { options, variable, @@ -191,7 +211,7 @@ const Form: FC = ({ return (
-
+
{label[language] || label.en_US} { @@ -202,6 +222,7 @@ const Form: FC = ({ {tooltipContent}
= ({ ) } - if (formSchema.type === 'boolean') { + if (formSchema.type === FormTypeEnum.boolean) { const { variable, label, @@ -233,9 +254,9 @@ const Form: FC = ({ return (
-
+
- {label[language] || label.en_US} + {label[language] || label.en_US} { required && ( * @@ -256,6 +277,52 @@ const Form: FC = ({
) } + + if (formSchema.type === FormTypeEnum.modelSelector) { + const { + variable, + label, + required, + } = formSchema as (CredentialFormSchemaTextInput | CredentialFormSchemaSecretInput) + + return ( +
+
+ {label[language] || label.en_US} + { + required && ( + * + ) + } + {tooltipContent} +
+ handleModelChanged(variable, model)} + onCompletionParamsChange={params => handleCompletionParamsChange(variable, params)} + hideDebugWithMultipleModel + debugWithMultipleModel={false} + readonly={readonly} + /> + {fieldMoreInfo?.(formSchema)} + {validating && changeKey === variable && } +
+ ) + } + + if (formSchema.type === FormTypeEnum.toolSelector) { + // TODO + } + + if (formSchema.type === FormTypeEnum.appSelector) { + // TODO + } } return ( diff --git a/web/app/components/header/account-setting/model-provider-page/model-modal/Input.tsx b/web/app/components/header/account-setting/model-provider-page/model-modal/Input.tsx index 86d52619e6..ee9d75becc 100644 --- a/web/app/components/header/account-setting/model-provider-page/model-modal/Input.tsx +++ b/web/app/components/header/account-setting/model-provider-page/model-modal/Input.tsx @@ -26,14 +26,14 @@ const Input: FC = ({ max, }) => { const toLimit = (v: string) => { - const minNum = parseFloat(`${min}`) - const maxNum = parseFloat(`${max}`) - if (!isNaN(minNum) && parseFloat(v) < minNum) { + const minNum = Number.parseFloat(`${min}`) + const maxNum = Number.parseFloat(`${max}`) + if (!isNaN(minNum) && Number.parseFloat(v) < minNum) { onChange(`${min}`) return } - if (!isNaN(maxNum) && parseFloat(v) > maxNum) + if (!isNaN(maxNum) && Number.parseFloat(v) > maxNum) onChange(`${max}`) } return ( @@ -41,7 +41,7 @@ const Input: FC = ({ Date: Tue, 12 Nov 2024 16:56:53 +0800 Subject: [PATCH 22/68] confirm model selector schema in agent and workflow --- .../workflow/nodes/tool/components/input-var-list.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/app/components/workflow/nodes/tool/components/input-var-list.tsx b/web/app/components/workflow/nodes/tool/components/input-var-list.tsx index 0c1ed78551..e47082f4b7 100644 --- a/web/app/components/workflow/nodes/tool/components/input-var-list.tsx +++ b/web/app/components/workflow/nodes/tool/components/input-var-list.tsx @@ -14,7 +14,7 @@ import VarReferencePicker from '@/app/components/workflow/nodes/_base/components import Input from '@/app/components/workflow/nodes/_base/components/input-support-select-var' import useAvailableVarList from '@/app/components/workflow/nodes/_base/hooks/use-available-var-list' import { VarType } from '@/app/components/workflow/types' -interface Props { +type Props = { readOnly: boolean nodeId: string schema: CredentialFormSchema[] From 3716ea46b550a054ba08ea86ca113d6b08e5a4b8 Mon Sep 17 00:00:00 2001 From: nite-knite Date: Tue, 12 Nov 2024 17:18:04 +0800 Subject: [PATCH 23/68] chore: bump elliptic from 6.5.7 to 6.6.0 --- web/pnpm-lock.yaml | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/web/pnpm-lock.yaml b/web/pnpm-lock.yaml index 236c23c9c6..5765f2589c 100644 --- a/web/pnpm-lock.yaml +++ b/web/pnpm-lock.yaml @@ -4068,8 +4068,8 @@ packages: elkjs@0.9.3: resolution: {integrity: sha512-f/ZeWvW/BCXbhGEf1Ujp29EASo/lk1FDnETgNKwJrsVvGZhUWCZyg3xLJjAsxfOmt8KjswHmI5EwCQcPMpOYhQ==} - elliptic@6.5.7: - resolution: {integrity: sha512-ESVCtTwiA+XhY3wyh24QqRGBoP3rEdDUl3EDUUo9tft074fi19IrdpH7hLCMMP3CIj7jb3W96rn8lt/BqIlt5Q==} + elliptic@6.6.0: + resolution: {integrity: sha512-dpwoQcLc/2WLQvJvLRHKZ+f9FgOdjnq11rurqwekGQygGPsYSK29OMMD2WalatiqQ+XGFDglTNixpPfI+lpaAA==} emittery@0.13.1: resolution: {integrity: sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==} @@ -11763,7 +11763,7 @@ snapshots: browserify-rsa: 4.1.1 create-hash: 1.2.0 create-hmac: 1.1.7 - elliptic: 6.5.7 + elliptic: 6.6.0 hash-base: 3.0.4 inherits: 2.0.4 parse-asn1: 5.1.7 @@ -12096,7 +12096,7 @@ snapshots: create-ecdh@4.0.4: dependencies: bn.js: 4.12.0 - elliptic: 6.5.7 + elliptic: 6.6.0 create-hash@1.2.0: dependencies: @@ -12558,7 +12558,7 @@ snapshots: elkjs@0.9.3: {} - elliptic@6.5.7: + elliptic@6.6.0: dependencies: bn.js: 4.12.0 brorand: 1.1.0 @@ -12830,7 +12830,7 @@ snapshots: debug: 4.3.7 enhanced-resolve: 5.17.1 eslint: 9.13.0(jiti@1.21.6) - eslint-module-utils: 2.12.0(@typescript-eslint/parser@8.11.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@8.11.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import-x@4.3.1(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5))(eslint-plugin-import@2.31.0)(eslint@9.13.0(jiti@1.21.6)))(eslint@9.13.0(jiti@1.21.6)) + eslint-module-utils: 2.12.0(@typescript-eslint/parser@8.11.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3)(eslint@9.13.0(jiti@1.21.6)) fast-glob: 3.3.2 get-tsconfig: 4.8.1 is-bun-module: 1.2.1 @@ -12848,7 +12848,7 @@ snapshots: dependencies: eslint: 9.13.0(jiti@1.21.6) - eslint-module-utils@2.12.0(@typescript-eslint/parser@8.11.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@8.11.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import-x@4.3.1(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5))(eslint-plugin-import@2.31.0)(eslint@9.13.0(jiti@1.21.6)))(eslint@9.13.0(jiti@1.21.6)): + eslint-module-utils@2.12.0(@typescript-eslint/parser@8.11.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3)(eslint@9.13.0(jiti@1.21.6)): dependencies: debug: 3.2.7 optionalDependencies: @@ -12904,7 +12904,7 @@ snapshots: doctrine: 2.1.0 eslint: 9.13.0(jiti@1.21.6) eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.12.0(@typescript-eslint/parser@8.11.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@8.11.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import-x@4.3.1(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5))(eslint-plugin-import@2.31.0)(eslint@9.13.0(jiti@1.21.6)))(eslint@9.13.0(jiti@1.21.6)) + eslint-module-utils: 2.12.0(@typescript-eslint/parser@8.11.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3)(eslint@9.13.0(jiti@1.21.6)) hasown: 2.0.2 is-core-module: 2.15.1 is-glob: 4.0.3 From 9c6aafd415369bef596e10e057a2d060f2f14f68 Mon Sep 17 00:00:00 2001 From: Joel Date: Tue, 12 Nov 2024 17:32:39 +0800 Subject: [PATCH 24/68] feat: install bundle ui --- .../(commonLayout)/plugins/test/card/page.tsx | 32 +++---- web/app/components/plugins/card/card-mock.ts | 1 + .../install-plugin/install-bundle/index.tsx | 45 ++++++++-- .../install-bundle/steps/install.tsx | 85 +++++++++++++++++++ .../install-bundle/steps/select-package.tsx | 20 ----- .../components/plugins/plugin-item/index.tsx | 4 +- web/i18n/en-US/plugin.ts | 4 +- web/i18n/zh-Hans/plugin.ts | 4 +- 8 files changed, 148 insertions(+), 47 deletions(-) create mode 100644 web/app/components/plugins/install-plugin/install-bundle/steps/install.tsx delete mode 100644 web/app/components/plugins/install-plugin/install-bundle/steps/select-package.tsx diff --git a/web/app/(commonLayout)/plugins/test/card/page.tsx b/web/app/(commonLayout)/plugins/test/card/page.tsx index dd280aac38..efc569a733 100644 --- a/web/app/(commonLayout)/plugins/test/card/page.tsx +++ b/web/app/(commonLayout)/plugins/test/card/page.tsx @@ -1,19 +1,21 @@ -import { handleDelete } from './actions' +'use client' import Card from '@/app/components/plugins/card' -import { customTool, extensionDallE, modelGPT4, toolNotion } from '@/app/components/plugins/card/card-mock' -import PluginItem from '@/app/components/plugins/plugin-item' +import { customTool, extensionDallE, modelGPT4, toolNeko, toolNotion } from '@/app/components/plugins/card/card-mock' +// import PluginItem from '@/app/components/plugins/plugin-item' import CardMoreInfo from '@/app/components/plugins/card/card-more-info' -import ProviderCard from '@/app/components/plugins/provider-card' +// import ProviderCard from '@/app/components/plugins/provider-card' import Badge from '@/app/components/base/badge' +import InstallBundle from '@/app/components/plugins/install-plugin/install-bundle' -const PluginList = async () => { +const PluginList = () => { const pluginList = [toolNotion, extensionDallE, modelGPT4, customTool] return (
+ { }} plugins={[toolNeko, { ...toolNeko, plugin_unique_identifier: `${toolNeko.plugin_unique_identifier}xxx` }]} />
-

Dify Plugin list

-
+ {/*

Dify Plugin list

*/} + {/*
{pluginList.map((plugin, index) => ( { onDelete={handleDelete} /> ))} -
+
*/}

Install Plugin / Package under bundle

@@ -33,21 +35,21 @@ const PluginList = async () => { } />
-

Installed

+ {/*

Installed

-
+
*/} -

Install model provide

+ {/*

Install model provide

{pluginList.map((plugin, index) => ( ))} -
+
*/}

Marketplace Plugin list

@@ -67,8 +69,8 @@ const PluginList = async () => { ) } -export const metadata = { - title: 'Plugins - Card', -} +// export const metadata = { +// title: 'Plugins - Card', +// } export default PluginList diff --git a/web/app/components/plugins/card/card-mock.ts b/web/app/components/plugins/card/card-mock.ts index 4217c4d33a..201a7bc65d 100644 --- a/web/app/components/plugins/card/card-mock.ts +++ b/web/app/components/plugins/card/card-mock.ts @@ -2,6 +2,7 @@ import type { PluginDeclaration } from '../types' import { PluginType } from '../types' export const toolNeko: PluginDeclaration = { + plugin_unique_identifier: 'xxxxxx', version: '0.0.1', author: 'langgenius', name: 'neko', diff --git a/web/app/components/plugins/install-plugin/install-bundle/index.tsx b/web/app/components/plugins/install-plugin/install-bundle/index.tsx index 6086f0cbc3..6f20db7725 100644 --- a/web/app/components/plugins/install-plugin/install-bundle/index.tsx +++ b/web/app/components/plugins/install-plugin/install-bundle/index.tsx @@ -1,9 +1,13 @@ 'use client' import type { FC } from 'react' -import React, { useState } from 'react' +import Modal from '@/app/components/base/modal' +import React, { useCallback, useState } from 'react' import { InstallStep } from '../../types' import type { PluginDeclaration } from '../../types' -import SelectPackage from './steps/select-package' +import Install from './steps/install' +import { useTranslation } from 'react-i18next' + +const i18nPrefix = 'plugin.installModal' export enum InstallType { fromLocal = 'fromLocal', @@ -14,24 +18,47 @@ export enum InstallType { type Props = { installType?: InstallType plugins?: PluginDeclaration[] + onClose: () => void } const InstallBundle: FC = ({ installType = InstallType.fromMarketplace, plugins = [], + onClose, }) => { + const { t } = useTranslation() const [step, setStep] = useState(installType === InstallType.fromMarketplace ? InstallStep.readyToInstall : InstallStep.uploading) - const [selectedPlugins, setSelectedPlugins] = useState([]) - const handleSelectedPluginsChange = (plugins: PluginDeclaration[]) => { - setSelectedPlugins(plugins) - } + const getTitle = useCallback(() => { + if (step === InstallStep.uploadFailed) + return t(`${i18nPrefix}.uploadFailed`) + if (step === InstallStep.installed) + return t(`${i18nPrefix}.installedSuccessfully`) + if (step === InstallStep.installFailed) + return t(`${i18nPrefix}.installFailed`) + + return t(`${i18nPrefix}.installPlugin`) + }, [step, t]) + return ( -
+ +
+
+ {getTitle()} +
+
{step === InstallStep.readyToInstall && ( - + )} -
+ ) } diff --git a/web/app/components/plugins/install-plugin/install-bundle/steps/install.tsx b/web/app/components/plugins/install-plugin/install-bundle/steps/install.tsx new file mode 100644 index 0000000000..9b0e996f82 --- /dev/null +++ b/web/app/components/plugins/install-plugin/install-bundle/steps/install.tsx @@ -0,0 +1,85 @@ +'use client' +import type { FC } from 'react' +import React from 'react' +import type { PluginDeclaration } from '../../../types' +import Card from '../../../card' +import Button from '@/app/components/base/button' +import { RiLoader2Line } from '@remixicon/react' +import Badge, { BadgeState } from '@/app/components/base/badge/index' +import { pluginManifestToCardPluginProps } from '../../utils' +import { useTranslation } from 'react-i18next' +import Checkbox from '@/app/components/base/checkbox' + +const i18nPrefix = 'plugin.installModal' + +type Props = { + plugins: PluginDeclaration[], + onCancel: () => void +} + +const Install: FC = ({ + plugins, + onCancel, +}) => { + const { t } = useTranslation() + const [selectedPlugins, setSelectedPlugins] = React.useState([]) + const selectedPluginsNum = selectedPlugins.length + const handleSelect = (plugin: PluginDeclaration) => { + return () => { + const isSelected = !!selectedPlugins.find(p => p.plugin_unique_identifier === plugin.plugin_unique_identifier) + let nextSelectedPlugins + if (isSelected) + nextSelectedPlugins = selectedPlugins.filter(p => p.plugin_unique_identifier !== plugin.plugin_unique_identifier) + else + nextSelectedPlugins = [...selectedPlugins, plugin] + setSelectedPlugins(nextSelectedPlugins) + } + } + const [isInstalling, setIsInstalling] = React.useState(false) + const handleInstall = () => { + + } + return ( + <> +
+
+

{t(`${i18nPrefix}.${selectedPluginsNum > 1 ? 'readyToInstallPackages' : 'readyToInstallPackage'}`, { num: selectedPluginsNum })}

+
+
+ {plugins.map(plugin => ( +
+ p.plugin_unique_identifier === plugin.plugin_unique_identifier)} + onCheck={handleSelect(plugin)} + /> + {plugin.version}} + /> +
+ ))} +
+
+ {/* Action Buttons */} +
+ {!isInstalling && ( + + )} + +
+ + ) +} +export default React.memo(Install) diff --git a/web/app/components/plugins/install-plugin/install-bundle/steps/select-package.tsx b/web/app/components/plugins/install-plugin/install-bundle/steps/select-package.tsx deleted file mode 100644 index 70a51c265c..0000000000 --- a/web/app/components/plugins/install-plugin/install-bundle/steps/select-package.tsx +++ /dev/null @@ -1,20 +0,0 @@ -'use client' -import type { FC } from 'react' -import React from 'react' -import type { PluginDeclaration } from '../../../types' - -type Props = { - plugins: PluginDeclaration[], - onChange: (plugins: PluginDeclaration[]) => void -} - -const SelectPackage: FC = ({ - plugins, - onChange, -}) => { - return ( -
-
- ) -} -export default React.memo(SelectPackage) diff --git a/web/app/components/plugins/plugin-item/index.tsx b/web/app/components/plugins/plugin-item/index.tsx index 5a6a3a6ca2..4ef0340641 100644 --- a/web/app/components/plugins/plugin-item/index.tsx +++ b/web/app/components/plugins/plugin-item/index.tsx @@ -61,7 +61,9 @@ const PluginItem: FC = ({ ? 'bg-[repeating-linear-gradient(-45deg,rgba(16,24,40,0.04),rgba(16,24,40,0.04)_5px,rgba(0,0,0,0.02)_5px,rgba(0,0,0,0.02)_10px)]' : 'bg-background-section-burn', )} - onClick={() => setCurrentPluginDetail(plugin)} + onClick={() => { + setCurrentPluginDetail(plugin) + }} >
diff --git a/web/i18n/en-US/plugin.ts b/web/i18n/en-US/plugin.ts index abcf3480bb..689510acca 100644 --- a/web/i18n/en-US/plugin.ts +++ b/web/i18n/en-US/plugin.ts @@ -80,7 +80,9 @@ const translation = { install: 'Install', installing: 'Installing...', uploadingPackage: 'Uploading {{packageName}}...', - readyToInstall: 'About to install the following plugin.', + readyToInstall: 'About to install the following plugin', + readyToInstallPackage: 'About to install the following plugin', + readyToInstallPackages: 'About to install the following {{num}} plugins', fromTrustSource: 'Please make sure that you only install plugins from a trusted source.', labels: { repository: 'Repository', diff --git a/web/i18n/zh-Hans/plugin.ts b/web/i18n/zh-Hans/plugin.ts index 3355cb742c..25cd0ba03f 100644 --- a/web/i18n/zh-Hans/plugin.ts +++ b/web/i18n/zh-Hans/plugin.ts @@ -80,7 +80,9 @@ const translation = { install: '安装', installing: '安装中...', uploadingPackage: '上传 {{packageName}} 中...', - readyToInstall: '即将安装以下插件。', + readyToInstall: '即将安装以下插件', + readyToInstallPackage: '即将安装以下插件', + readyToInstallPackages: '即将安装以下 {{num}} 个插件', fromTrustSource: '请保证仅从可信源安装插件。', labels: { repository: '仓库', From 13d3f67746bc4cbca3c2d27ae427aea61fe418c2 Mon Sep 17 00:00:00 2001 From: StyleZhang Date: Tue, 12 Nov 2024 17:58:14 +0800 Subject: [PATCH 25/68] feat: plugin task use query --- .../install-from-github/steps/loaded.tsx | 6 +-- .../steps/install.tsx | 6 +-- .../components/plugins/plugin-page/index.tsx | 7 --- .../plugins/plugin-page/plugin-tasks/hooks.ts | 26 +++++++++-- .../plugin-page/plugin-tasks/index.tsx | 43 +++++++++++------ .../plugins/plugin-page/plugin-tasks/store.ts | 40 ---------------- web/app/components/plugins/types.ts | 3 ++ .../update-plugin/from-market-place.tsx | 8 ++-- web/service/use-plugins.ts | 46 +++++++++++++++++++ 9 files changed, 111 insertions(+), 74 deletions(-) delete mode 100644 web/app/components/plugins/plugin-page/plugin-tasks/store.ts diff --git a/web/app/components/plugins/install-plugin/install-from-github/steps/loaded.tsx b/web/app/components/plugins/install-plugin/install-from-github/steps/loaded.tsx index c046957263..2311cb781e 100644 --- a/web/app/components/plugins/install-plugin/install-from-github/steps/loaded.tsx +++ b/web/app/components/plugins/install-plugin/install-from-github/steps/loaded.tsx @@ -9,7 +9,7 @@ import { pluginManifestToCardPluginProps } from '../../utils' import { useTranslation } from 'react-i18next' import { installPackageFromGitHub, uninstallPlugin } from '@/service/plugins' import { RiLoader2Line } from '@remixicon/react' -import { usePluginTasksStore } from '@/app/components/plugins/plugin-page/plugin-tasks/store' +import { usePluginTaskList } from '@/service/use-plugins' import checkTaskStatus from '../../base/check-task-status' import { parseGitHubUrl } from '../../utils' @@ -40,7 +40,7 @@ const Loaded: React.FC = ({ }) => { const { t } = useTranslation() const [isInstalling, setIsInstalling] = React.useState(false) - const setPluginTasksWithPolling = usePluginTasksStore(s => s.setPluginTasksWithPolling) + const { handleRefetch } = usePluginTaskList() const { check } = checkTaskStatus() const handleInstall = async () => { @@ -64,7 +64,7 @@ const Loaded: React.FC = ({ return } - setPluginTasksWithPolling() + handleRefetch() await check({ taskId, pluginUniqueIdentifier: uniqueIdentifier, diff --git a/web/app/components/plugins/install-plugin/install-from-local-package/steps/install.tsx b/web/app/components/plugins/install-plugin/install-from-local-package/steps/install.tsx index 4d776f4430..43c2a03319 100644 --- a/web/app/components/plugins/install-plugin/install-from-local-package/steps/install.tsx +++ b/web/app/components/plugins/install-plugin/install-from-local-package/steps/install.tsx @@ -10,7 +10,7 @@ import { RiLoader2Line } from '@remixicon/react' import Badge, { BadgeState } from '@/app/components/base/badge/index' import { useInstallPackageFromLocal } from '@/service/use-plugins' import checkTaskStatus from '../../base/check-task-status' -import { usePluginTasksStore } from '@/app/components/plugins/plugin-page/plugin-tasks/store' +import { usePluginTaskList } from '@/service/use-plugins' const i18nPrefix = 'plugin.installModal' @@ -45,7 +45,7 @@ const Installed: FC = ({ onCancel() } - const setPluginTasksWithPolling = usePluginTasksStore(s => s.setPluginTasksWithPolling) + const { handleRefetch } = usePluginTaskList() const handleInstall = async () => { if (isInstalling) return setIsInstalling(true) @@ -60,7 +60,7 @@ const Installed: FC = ({ onInstalled() return } - setPluginTasksWithPolling() + handleRefetch() await check({ taskId, pluginUniqueIdentifier: uniqueIdentifier, diff --git a/web/app/components/plugins/plugin-page/index.tsx b/web/app/components/plugins/plugin-page/index.tsx index 013c9bc9e2..2cba8cf939 100644 --- a/web/app/components/plugins/plugin-page/index.tsx +++ b/web/app/components/plugins/plugin-page/index.tsx @@ -16,7 +16,6 @@ import InstallPluginDropdown from './install-plugin-dropdown' import { useUploader } from './use-uploader' import usePermission from './use-permission' import DebugInfo from './debug-info' -import { usePluginTasksStore } from './plugin-tasks/store' import PluginTasks from './plugin-tasks' import Button from '@/app/components/base/button' import TabSlider from '@/app/components/base/tab-slider' @@ -111,12 +110,6 @@ const PluginPage = ({ const { dragging, fileUploader, fileChangeHandle, removeFile } = uploaderProps - const setPluginTasksWithPolling = usePluginTasksStore(s => s.setPluginTasksWithPolling) - - useEffect(() => { - setPluginTasksWithPolling() - }, [setPluginTasksWithPolling]) - return (
{ - const pluginTasks = usePluginTasksStore(s => s.pluginTasks) - const allPlugins = pluginTasks.map(task => task.plugins).flat() + const { + pluginTasks, + } = usePluginTaskList() + const { mutate } = useMutationClearTaskPlugin() + const allPlugins = pluginTasks.map(task => task.plugins.map((plugin) => { + return { + ...plugin, + taskId: task.id, + } + })).flat() const errorPlugins: PluginStatus[] = [] const successPlugins: PluginStatus[] = [] const runningPlugins: PluginStatus[] = [] @@ -18,10 +30,18 @@ export const usePluginTaskStatus = () => { successPlugins.push(plugin) }) + const handleClearErrorPlugin = useCallback((taskId: string, pluginId: string) => { + mutate({ + taskId, + pluginId, + }) + }, [mutate]) + return { errorPlugins, successPlugins, runningPlugins, totalPluginsLength: allPlugins.length, + handleClearErrorPlugin, } } diff --git a/web/app/components/plugins/plugin-page/plugin-tasks/index.tsx b/web/app/components/plugins/plugin-page/plugin-tasks/index.tsx index bde4371839..ebf2db44b6 100644 --- a/web/app/components/plugins/plugin-page/plugin-tasks/index.tsx +++ b/web/app/components/plugins/plugin-page/plugin-tasks/index.tsx @@ -17,16 +17,20 @@ import { import Tooltip from '@/app/components/base/tooltip' import Button from '@/app/components/base/button' import ProgressCircle from '@/app/components/base/progress-bar/progress-circle' +import CardIcon from '@/app/components/plugins/card/base/card-icon' import cn from '@/utils/classnames' +import { useGetLanguage } from '@/context/i18n' const PluginTasks = () => { const { t } = useTranslation() + const language = useGetLanguage() const [open, setOpen] = useState(false) const { errorPlugins, runningPlugins, successPlugins, totalPluginsLength, + handleClearErrorPlugin, } = usePluginTaskStatus() const isInstalling = runningPlugins.length > 0 && errorPlugins.length === 0 && successPlugins.length === 0 @@ -113,20 +117,31 @@ const PluginTasks = () => {
{t('plugin.task.installedError')}
-
-
- -
-
- DuckDuckGo Search -
- -
+ { + errorPlugins.map(errorPlugin => ( +
+
+ + +
+
+ {errorPlugin.labels[language]} +
+ +
+ )) + }
diff --git a/web/app/components/plugins/plugin-page/plugin-tasks/store.ts b/web/app/components/plugins/plugin-page/plugin-tasks/store.ts deleted file mode 100644 index 403d529a39..0000000000 --- a/web/app/components/plugins/plugin-page/plugin-tasks/store.ts +++ /dev/null @@ -1,40 +0,0 @@ -import { create } from 'zustand' -import type { PluginTask } from '@/app/components/plugins/types' -import { fetchPluginTasks } from '@/service/plugins' - -type PluginTasksStore = { - pluginTasks: PluginTask[] - setPluginTasks: (tasks: PluginTask[]) => void - setPluginTasksWithPolling: () => void -} - -let pluginTasksTimer: NodeJS.Timeout | null = null - -export const usePluginTasksStore = create(set => ({ - pluginTasks: [], - setPluginTasks: (tasks: PluginTask[]) => set({ pluginTasks: tasks }), - setPluginTasksWithPolling: async () => { - if (pluginTasksTimer) { - clearTimeout(pluginTasksTimer) - pluginTasksTimer = null - } - const handleUpdatePluginTasks = async () => { - const { tasks } = await fetchPluginTasks() - set({ pluginTasks: tasks }) - - if (tasks.length && !tasks.every(task => task.status === 'success')) { - pluginTasksTimer = setTimeout(() => { - handleUpdatePluginTasks() - }, 5000) - } - else { - if (pluginTasksTimer) { - clearTimeout(pluginTasksTimer) - pluginTasksTimer = null - } - } - } - - handleUpdatePluginTasks() - }, -})) diff --git a/web/app/components/plugins/types.ts b/web/app/components/plugins/types.ts index a869b2c556..1554c56097 100644 --- a/web/app/components/plugins/types.ts +++ b/web/app/components/plugins/types.ts @@ -260,6 +260,9 @@ export type PluginStatus = { plugin_id: string status: TaskStatus message: string + icon: string + labels: Record + taskId: string } export type PluginTask = { diff --git a/web/app/components/plugins/update-plugin/from-market-place.tsx b/web/app/components/plugins/update-plugin/from-market-place.tsx index c76b154c40..20dfc294a7 100644 --- a/web/app/components/plugins/update-plugin/from-market-place.tsx +++ b/web/app/components/plugins/update-plugin/from-market-place.tsx @@ -12,7 +12,7 @@ import { pluginManifestToCardPluginProps } from '@/app/components/plugins/instal import useGetIcon from '../install-plugin/base/use-get-icon' import { updateFromMarketPlace } from '@/service/plugins' import checkTaskStatus from '@/app/components/plugins/install-plugin/base/check-task-status' -import { usePluginTasksStore } from '@/app/components/plugins/plugin-page/plugin-tasks/store' +import { usePluginTaskList } from '@/service/use-plugins' const i18nPrefix = 'plugin.upgrade' @@ -56,7 +56,7 @@ const UpdatePluginModal: FC = ({ } const [uploadStep, setUploadStep] = useState(UploadStep.notStarted) - const setPluginTasksWithPolling = usePluginTasksStore(s => s.setPluginTasksWithPolling) + const { handleRefetch } = usePluginTaskList() const configBtnText = useMemo(() => { return ({ @@ -82,7 +82,7 @@ const UpdatePluginModal: FC = ({ onSave() return } - setPluginTasksWithPolling() + handleRefetch() await check({ taskId, pluginUniqueIdentifier: targetPackageInfo.id, @@ -98,7 +98,7 @@ const UpdatePluginModal: FC = ({ onSave() onCancel() } - }, [onCancel, onSave, uploadStep, check, originalPackageInfo.id, setPluginTasksWithPolling, targetPackageInfo.id]) + }, [onCancel, onSave, uploadStep, check, originalPackageInfo.id, handleRefetch, targetPackageInfo.id]) const usedInAppInfo = useMemo(() => { return (
diff --git a/web/service/use-plugins.ts b/web/service/use-plugins.ts index 3b72bee919..33abac865d 100644 --- a/web/service/use-plugins.ts +++ b/web/service/use-plugins.ts @@ -1,8 +1,10 @@ +import { useCallback, useState } from 'react' import type { DebugInfo as DebugInfoTypes, InstallPackageResponse, InstalledPluginListResponse, Permissions, + PluginTask, PluginsFromMarketplaceResponse, } from '@/app/components/plugins/types' import type { @@ -115,3 +117,47 @@ export const useMutationPluginsFromMarketplace = () => { }, }) } + +const usePluginTaskListKey = [NAME_SPACE, 'pluginTaskList'] +export const usePluginTaskList = () => { + const [enabled, setEnabled] = useState(true) + const { + data, + isFetched, + refetch, + ...rest + } = useQuery({ + queryKey: usePluginTaskListKey, + queryFn: async () => { + const currentData = await get<{ tasks: PluginTask[] }>('/workspaces/current/plugin/tasks?page=1&page_size=100') + const taskDone = currentData.tasks.every(task => task.total_plugins === task.completed_plugins) + + if (taskDone) + setEnabled(false) + + return currentData + }, + refetchInterval: 5000, + enabled, + }) + const handleRefetch = useCallback(() => { + setEnabled(true) + refetch() + }, [refetch]) + + return { + data, + pluginTasks: data?.tasks || [], + isFetched, + handleRefetch, + ...rest, + } +} + +export const useMutationClearTaskPlugin = () => { + return useMutation({ + mutationFn: ({ taskId, pluginId }: { taskId: string; pluginId: string }) => { + return post<{ success: boolean }>(`/workspaces/current/plugin/task/${taskId}/delete/${pluginId}`) + }, + }) +} From 582c7ce348aa49afea319b5f54f08d10ed618364 Mon Sep 17 00:00:00 2001 From: StyleZhang Date: Tue, 12 Nov 2024 18:28:34 +0800 Subject: [PATCH 26/68] fix: plugin task --- .../plugins/plugin-page/plugin-tasks/index.tsx | 9 +++------ web/service/use-plugins.ts | 2 +- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/web/app/components/plugins/plugin-page/plugin-tasks/index.tsx b/web/app/components/plugins/plugin-page/plugin-tasks/index.tsx index ebf2db44b6..6f4c8f390c 100644 --- a/web/app/components/plugins/plugin-page/plugin-tasks/index.tsx +++ b/web/app/components/plugins/plugin-page/plugin-tasks/index.tsx @@ -84,9 +84,6 @@ const PluginTasks = () => { isInstalling && ( ) } @@ -95,8 +92,8 @@ const PluginTasks = () => { ) } @@ -135,7 +132,7 @@ const PluginTasks = () => { diff --git a/web/service/use-plugins.ts b/web/service/use-plugins.ts index 33abac865d..fe5375b0df 100644 --- a/web/service/use-plugins.ts +++ b/web/service/use-plugins.ts @@ -120,7 +120,7 @@ export const useMutationPluginsFromMarketplace = () => { const usePluginTaskListKey = [NAME_SPACE, 'pluginTaskList'] export const usePluginTaskList = () => { - const [enabled, setEnabled] = useState(true) + const [enabled, setEnabled] = useState(false) const { data, isFetched, From 327940a1206e08d99688867752abccc797ab49b1 Mon Sep 17 00:00:00 2001 From: Yi Date: Wed, 13 Nov 2024 10:38:56 +0800 Subject: [PATCH 27/68] chore: update the update plugin from GitHub --- .../install-from-github/steps/loaded.tsx | 55 +++++++++++++------ .../components/plugins/plugin-item/action.tsx | 4 +- .../components/plugins/plugin-item/index.tsx | 4 +- web/app/components/plugins/types.ts | 5 ++ web/service/plugins.ts | 14 +++++ 5 files changed, 63 insertions(+), 19 deletions(-) diff --git a/web/app/components/plugins/install-plugin/install-from-github/steps/loaded.tsx b/web/app/components/plugins/install-plugin/install-from-github/steps/loaded.tsx index 2311cb781e..6338e387f7 100644 --- a/web/app/components/plugins/install-plugin/install-from-github/steps/loaded.tsx +++ b/web/app/components/plugins/install-plugin/install-from-github/steps/loaded.tsx @@ -7,7 +7,7 @@ import Card from '../../../card' import Badge, { BadgeState } from '@/app/components/base/badge/index' import { pluginManifestToCardPluginProps } from '../../utils' import { useTranslation } from 'react-i18next' -import { installPackageFromGitHub, uninstallPlugin } from '@/service/plugins' +import { installPackageFromGitHub, updateFromGitHub } from '@/service/plugins' import { RiLoader2Line } from '@remixicon/react' import { usePluginTaskList } from '@/service/use-plugins' import checkTaskStatus from '../../base/check-task-status' @@ -49,28 +49,49 @@ const Loaded: React.FC = ({ try { const { owner, repo } = parseGitHubUrl(repoUrl) - const { all_installed: isInstalled, task_id: taskId } = await installPackageFromGitHub( - `${owner}/${repo}`, - selectedVersion, - selectedPackage, - uniqueIdentifier, - ) + if (updatePayload) { + const { all_installed: isInstalled, task_id: taskId } = await updateFromGitHub( + `${owner}/${repo}`, + selectedVersion, + selectedPackage, + updatePayload.originalPackageInfo.id, + uniqueIdentifier, + ) - if (updatePayload && isInstalled) - await uninstallPlugin(updatePayload.originalPackageInfo.id) + if (isInstalled) { + onInstalled() + return + } + + handleRefetch() + await check({ + taskId, + pluginUniqueIdentifier: uniqueIdentifier, + }) - if (isInstalled) { onInstalled() - return } + else { + const { all_installed: isInstalled, task_id: taskId } = await installPackageFromGitHub( + `${owner}/${repo}`, + selectedVersion, + selectedPackage, + uniqueIdentifier, + ) - handleRefetch() - await check({ - taskId, - pluginUniqueIdentifier: uniqueIdentifier, - }) + if (isInstalled) { + onInstalled() + return + } - onInstalled() + handleRefetch() + await check({ + taskId, + pluginUniqueIdentifier: uniqueIdentifier, + }) + + onInstalled() + } } catch (e) { if (typeof e === 'string') { diff --git a/web/app/components/plugins/plugin-item/action.tsx b/web/app/components/plugins/plugin-item/action.tsx index 540c234407..80c5c5e78a 100644 --- a/web/app/components/plugins/plugin-item/action.tsx +++ b/web/app/components/plugins/plugin-item/action.tsx @@ -21,6 +21,7 @@ const i18nPrefix = 'plugin.action' type Props = { author: string installationId: string + pluginUniqueIdentifier: string pluginName: string version: string usedInApps: number @@ -33,6 +34,7 @@ type Props = { const Action: FC = ({ author, installationId, + pluginUniqueIdentifier, pluginName, version, isShowFetchNewVersion, @@ -70,7 +72,7 @@ const Action: FC = ({ type: PluginSource.github, github: { originalPackageInfo: { - id: installationId, + id: pluginUniqueIdentifier, repo: meta!.repo, version: meta!.version, package: meta!.package, diff --git a/web/app/components/plugins/plugin-item/index.tsx b/web/app/components/plugins/plugin-item/index.tsx index 4ef0340641..3569ed856c 100644 --- a/web/app/components/plugins/plugin-item/index.tsx +++ b/web/app/components/plugins/plugin-item/index.tsx @@ -42,6 +42,7 @@ const PluginItem: FC = ({ source, tenant_id, installation_id, + plugin_unique_identifier, endpoints_active, meta, plugin_id, @@ -73,7 +74,7 @@ const PluginItem: FC = ({ {`plugin-${installation_id}-logo`}
@@ -86,6 +87,7 @@ const PluginItem: FC = ({
e.stopPropagation()}> ) => { }) } +export const updateFromGitHub = async (repoUrl: string, selectedVersion: string, selectedPackage: string, + originalPlugin: string, newPlugin: string) => { + return post('/workspaces/current/plugin/upgrade/github', { + body: { + repo: repoUrl, + version: selectedVersion, + package: selectedPackage, + original_plugin_unique_identifier: originalPlugin, + new_plugin_unique_identifier: newPlugin, + }, + }) +} + export const uploadGitHub = async (repoUrl: string, selectedVersion: string, selectedPackage: string) => { return post('/workspaces/current/plugin/upload/github', { body: { From c6d1b7869d1ebfd2fb881d02a43e38190bf51c31 Mon Sep 17 00:00:00 2001 From: StyleZhang Date: Wed, 13 Nov 2024 11:33:39 +0800 Subject: [PATCH 28/68] fix: plugin task --- .../install-plugin/base/use-get-icon.ts | 19 ++++++------------- .../plugin-page/plugin-tasks/index.tsx | 5 ++++- web/service/use-plugins.ts | 6 +++--- 3 files changed, 13 insertions(+), 17 deletions(-) diff --git a/web/app/components/plugins/install-plugin/base/use-get-icon.ts b/web/app/components/plugins/install-plugin/base/use-get-icon.ts index ea7f8e36b9..bb46f27f53 100644 --- a/web/app/components/plugins/install-plugin/base/use-get-icon.ts +++ b/web/app/components/plugins/install-plugin/base/use-get-icon.ts @@ -1,19 +1,12 @@ +import { useCallback } from 'react' import { apiPrefix } from '@/config' -import { fetchWorkspaces } from '@/service/common' - -let tenantId: string | null | undefined = null +import { useSelector } from '@/context/app-context' const useGetIcon = () => { - const getIconUrl = async (fileName: string) => { - if (!tenantId) { - const { workspaces } = await fetchWorkspaces({ - url: '/workspaces', - params: {}, - }) - tenantId = workspaces.find(v => v.current)?.id - } - return `${apiPrefix}/workspaces/current/plugin/icon?tenant_id=${tenantId}&filename=${fileName}` - } + const currentWorkspace = useSelector(s => s.currentWorkspace) + const getIconUrl = useCallback((fileName: string) => { + return `${apiPrefix}/workspaces/current/plugin/icon?tenant_id=${currentWorkspace.id}&filename=${fileName}` + }, [currentWorkspace.id]) return { getIconUrl, diff --git a/web/app/components/plugins/plugin-page/plugin-tasks/index.tsx b/web/app/components/plugins/plugin-page/plugin-tasks/index.tsx index 6f4c8f390c..2ea822df42 100644 --- a/web/app/components/plugins/plugin-page/plugin-tasks/index.tsx +++ b/web/app/components/plugins/plugin-page/plugin-tasks/index.tsx @@ -20,6 +20,7 @@ import ProgressCircle from '@/app/components/base/progress-bar/progress-circle' import CardIcon from '@/app/components/plugins/card/base/card-icon' import cn from '@/utils/classnames' import { useGetLanguage } from '@/context/i18n' +import useGetIcon from '@/app/components/plugins/install-plugin/base/use-get-icon' const PluginTasks = () => { const { t } = useTranslation() @@ -32,6 +33,7 @@ const PluginTasks = () => { totalPluginsLength, handleClearErrorPlugin, } = usePluginTaskStatus() + const { getIconUrl } = useGetIcon() const isInstalling = runningPlugins.length > 0 && errorPlugins.length === 0 && successPlugins.length === 0 const isInstallingWithError = errorPlugins.length > 0 && errorPlugins.length < totalPluginsLength @@ -123,7 +125,8 @@ const PluginTasks = () => {
diff --git a/web/service/use-plugins.ts b/web/service/use-plugins.ts index fe5375b0df..646056e399 100644 --- a/web/service/use-plugins.ts +++ b/web/service/use-plugins.ts @@ -120,7 +120,7 @@ export const useMutationPluginsFromMarketplace = () => { const usePluginTaskListKey = [NAME_SPACE, 'pluginTaskList'] export const usePluginTaskList = () => { - const [enabled, setEnabled] = useState(false) + const [enabled, setEnabled] = useState(true) const { data, isFetched, @@ -137,7 +137,7 @@ export const usePluginTaskList = () => { return currentData }, - refetchInterval: 5000, + // refetchInterval: 5000, enabled, }) const handleRefetch = useCallback(() => { @@ -157,7 +157,7 @@ export const usePluginTaskList = () => { export const useMutationClearTaskPlugin = () => { return useMutation({ mutationFn: ({ taskId, pluginId }: { taskId: string; pluginId: string }) => { - return post<{ success: boolean }>(`/workspaces/current/plugin/task/${taskId}/delete/${pluginId}`) + return post<{ success: boolean }>(`/workspaces/current/plugin/tasks/${taskId}/delete/${pluginId}`) }, }) } From 83dae7e5bc4c2ca9b5eac7e8a3c7549a35525564 Mon Sep 17 00:00:00 2001 From: Joel Date: Wed, 13 Nov 2024 11:38:32 +0800 Subject: [PATCH 29/68] fix: can not select action in workflow and tools --- .../workflow/block-selector/tool/tool.tsx | 27 +++++++++---------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/web/app/components/workflow/block-selector/tool/tool.tsx b/web/app/components/workflow/block-selector/tool/tool.tsx index f7433b8e60..3ce6bdcf7d 100644 --- a/web/app/components/workflow/block-selector/tool/tool.tsx +++ b/web/app/components/workflow/block-selector/tool/tool.tsx @@ -34,7 +34,7 @@ const Tool: FC = ({ const language = useGetLanguage() const isFlatView = viewType === ViewType.flat const actions = payload.tools - const hasAction = payload.type === CollectionType.builtIn + const hasAction = true // Now always support actions const [isFold, { toggle: toggleFold, }] = useBoolean(false) @@ -62,25 +62,24 @@ const Tool: FC = ({
{ - if (hasAction) { + if (hasAction) toggleFold() - return - } - // TODO: get workflow and custom tool params + + // Now always support actions // if (payload.parameters) { // payload.parameters.forEach((item) => { // params[item.name] = '' // }) // } - onSelect(BlockEnum.Tool, { - provider_id: payload.id, - provider_type: payload.type, - provider_name: payload.name, - tool_name: payload.name, - tool_label: payload.label[language], - title: payload.label[language], - params: {}, - }) + // onSelect(BlockEnum.Tool, { + // provider_id: payload.id, + // provider_type: payload.type, + // provider_name: payload.name, + // tool_name: payload.name, + // tool_label: payload.label[language], + // title: payload.label[language], + // params: {}, + // }) }} >
From d67eb907dd2c76561ad2cd0d44ec9e0a0f3324ef Mon Sep 17 00:00:00 2001 From: Joel Date: Wed, 13 Nov 2024 11:56:33 +0800 Subject: [PATCH 30/68] fix: show index letter problem --- .../workflow/block-selector/tool/tool-list-tree-view/item.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/web/app/components/workflow/block-selector/tool/tool-list-tree-view/item.tsx b/web/app/components/workflow/block-selector/tool/tool-list-tree-view/item.tsx index 68bc97ee85..156bede917 100644 --- a/web/app/components/workflow/block-selector/tool/tool-list-tree-view/item.tsx +++ b/web/app/components/workflow/block-selector/tool/tool-list-tree-view/item.tsx @@ -20,7 +20,7 @@ const Item: FC = ({ }) => { return (
-
+
{groupName}
@@ -29,7 +29,7 @@ const Item: FC = ({ key={tool.id} payload={tool} viewType={ViewType.tree} - isShowLetterIndex + isShowLetterIndex={false} onSelect={onSelect} /> ))} From 1fe5be532ddcf3fab93302104eeae3cbd35df1c4 Mon Sep 17 00:00:00 2001 From: AkaraChen Date: Wed, 13 Nov 2024 12:59:52 +0800 Subject: [PATCH 31/68] fix: new workflow init draft failed --- web/service/fetch.ts | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/web/service/fetch.ts b/web/service/fetch.ts index 6551fa5793..0ca804c01e 100644 --- a/web/service/fetch.ts +++ b/web/service/fetch.ts @@ -32,11 +32,10 @@ export type ResponseError = { const afterResponseErrorCode = (otherOptions: IOtherOptions): AfterResponseHook => { return async (_request, _options, response) => { - if (!/^(2|3)\d{2}$/.test(String(response.status))) { - const bodyJson = response.json() as Promise - switch (response.status) { - case 401: - return Promise.reject(response) + const clonedResponse = response.clone() + if (!/^(2|3)\d{2}$/.test(String(clonedResponse.status))) { + const bodyJson = clonedResponse.json() as Promise + switch (clonedResponse.status) { case 403: bodyJson.then((data: ResponseError) => { if (!otherOptions.silent) @@ -51,8 +50,8 @@ const afterResponseErrorCode = (otherOptions: IOtherOptions): AfterResponseHook if (!otherOptions.silent) Toast.notify({ type: 'error', message: data.message }) }) + return Promise.reject(response) } - throw response } } } @@ -98,7 +97,7 @@ const baseHooks: Hooks = { ], } -const client = ky.create({ +const baseClient = ky.create({ hooks: baseHooks, timeout: TIME_OUT, }) @@ -139,7 +138,7 @@ async function base(url: string, options: FetchOptionType = {}, otherOptions: const fetchPathname = `${base}${url.startsWith('/') ? url : `/${url}`}` - const res = await client.extend({ + const client = baseClient.extend({ hooks: { ...baseHooks, beforeError: [ @@ -157,7 +156,9 @@ async function base(url: string, options: FetchOptionType = {}, otherOptions: afterResponseErrorCode(otherOptions), ], }, - })(fetchPathname, { + }) + + const res = await client(fetchPathname, { ...init, credentials: isMarketplaceAPI ? 'omit' @@ -174,14 +175,11 @@ async function base(url: string, options: FetchOptionType = {}, otherOptions: const contentType = res.headers.get('content-type') if ( contentType - && [ContentType.download, ContentType.audio].includes(contentType) + && [ContentType.download, ContentType.audio].includes(contentType) ) return await res.blob() as T return await res.json() as T } -export { - client, - base, -} +export { base } From fa01360498348d7f720bfd69e3a067c4856b1df5 Mon Sep 17 00:00:00 2001 From: twwu Date: Wed, 13 Nov 2024 13:11:47 +0800 Subject: [PATCH 32/68] fix: Fix theme initialization issue --- web/themes/dark.css | 701 ++++++++++++++++++++++++++++++++++++++++++ web/themes/light.css | 702 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 1403 insertions(+) diff --git a/web/themes/dark.css b/web/themes/dark.css index 08994039eb..6e645616fb 100644 --- a/web/themes/dark.css +++ b/web/themes/dark.css @@ -1,4 +1,705 @@ /* Attention: Generate by code. Don't update by hand!!! */ +@media (prefers-color-scheme: dark) { + html:not([data-theme="dark"]):not([data-theme="light"]) { + color-scheme: dark; + --color-components-input-bg-normal: #FFFFFF14; + --color-components-input-text-placeholder: #C8CEDA4D; + --color-components-input-bg-hover: #FFFFFF08; + --color-components-input-bg-active: #FFFFFF0D; + --color-components-input-border-active: #747481; + --color-components-input-border-destructive: #F97066; + --color-components-input-text-filled: #F4F4F5; + --color-components-input-bg-destructive: #FFFFFF03; + --color-components-input-bg-disabled: #FFFFFF08; + --color-components-input-text-disabled: #C8CEDA4D; + --color-components-input-text-filled-disabled: #C8CEDA99; + --color-components-input-border-hover: #3A3A40; + --color-components-input-border-active-prompt-1: #36BFFA; + --color-components-input-border-active-prompt-2: #296DFF; + + --color-components-kbd-bg-gray: #FFFFFF08; + --color-components-kbd-bg-white: #FFFFFF1F; + + --color-components-tooltip-bg: #18181BF2; + + --color-components-button-primary-text: #FFFFFFF2; + --color-components-button-primary-bg: #155AEF; + --color-components-button-primary-border: #FFFFFF1F; + --color-components-button-primary-bg-hover: #296DFF; + --color-components-button-primary-border-hover: #FFFFFF33; + --color-components-button-primary-bg-disabled: #FFFFFF08; + --color-components-button-primary-border-disabled: #FFFFFF14; + --color-components-button-primary-text-disabled: #FFFFFF33; + + --color-components-button-secondary-text: #FFFFFFCC; + --color-components-button-secondary-text-disabled: #FFFFFF33; + --color-components-button-secondary-bg: #FFFFFF1F; + --color-components-button-secondary-bg-hover: #FFFFFF33; + --color-components-button-secondary-bg-disabled: #FFFFFF08; + --color-components-button-secondary-border: #FFFFFF14; + --color-components-button-secondary-border-hover: #FFFFFF1F; + --color-components-button-secondary-border-disabled: #FFFFFF0D; + + --color-components-button-tertiary-text: #D9D9DE; + --color-components-button-tertiary-text-disabled: #FFFFFF33; + --color-components-button-tertiary-bg: #FFFFFF14; + --color-components-button-tertiary-bg-hover: #FFFFFF1F; + --color-components-button-tertiary-bg-disabled: #FFFFFF08; + + --color-components-button-ghost-text: #D9D9DE; + --color-components-button-ghost-text-disabled: #FFFFFF33; + --color-components-button-ghost-bg-hover: #C8CEDA14; + + --color-components-button-destructive-primary-text: #FFFFFFF2; + --color-components-button-destructive-primary-text-disabled: #FFFFFF33; + --color-components-button-destructive-primary-bg: #D92D20; + --color-components-button-destructive-primary-bg-hover: #F04438; + --color-components-button-destructive-primary-bg-disabled: #F0443824; + --color-components-button-destructive-primary-border: #FFFFFF1F; + --color-components-button-destructive-primary-border-hover: #FFFFFF33; + --color-components-button-destructive-primary-border-disabled: #FFFFFF14; + + --color-components-button-destructive-secondary-text: #F97066; + --color-components-button-destructive-secondary-text-disabled: #F0443833; + --color-components-button-destructive-secondary-bg: #FFFFFF1F; + --color-components-button-destructive-secondary-bg-hover: #F0443824; + --color-components-button-destructive-secondary-bg-disabled: #F0443814; + --color-components-button-destructive-secondary-border: #FFFFFF14; + --color-components-button-destructive-secondary-border-hover: #FFFFFF1F; + --color-components-button-destructive-secondary-border-disabled: #F0443814; + + --color-components-button-destructive-tertiary-text: #F97066; + --color-components-button-destructive-tertiary-text-disabled: #F0443833; + --color-components-button-destructive-tertiary-bg: #F0443824; + --color-components-button-destructive-tertiary-bg-hover: #F0443840; + --color-components-button-destructive-tertiary-bg-disabled: #F0443814; + + --color-components-button-destructive-ghost-text: #F97066; + --color-components-button-destructive-ghost-text-disabled: #F0443833; + --color-components-button-destructive-ghost-bg-hover: #F0443824; + + --color-components-button-secondary-accent-text: #FFFFFFCC; + --color-components-button-secondary-accent-text-disabled: #FFFFFF33; + --color-components-button-secondary-accent-bg: #FFFFFF0D; + --color-components-button-secondary-accent-bg-hover: #FFFFFF14; + --color-components-button-secondary-accent-bg-disabled: #FFFFFF08; + --color-components-button-secondary-accent-border: #FFFFFF14; + --color-components-button-secondary-accent-border-hover: #FFFFFF1F; + --color-components-button-secondary-accent-border-disabled: #FFFFFF0D; + + --color-components-checkbox-icon: #FFFFFFF2; + --color-components-checkbox-icon-disabled: #FFFFFF33; + --color-components-checkbox-bg: #296DFF; + --color-components-checkbox-bg-hover: #5289FF; + --color-components-checkbox-bg-disabled: #FFFFFF08; + --color-components-checkbox-border: #FFFFFF66; + --color-components-checkbox-border-hover: #FFFFFF99; + --color-components-checkbox-border-disabled: #FFFFFF03; + --color-components-checkbox-bg-unchecked: #FFFFFF08; + --color-components-checkbox-bg-unchecked-hover: #FFFFFF0D; + --color-components-checkbox-bg-disabled-checked: #155AEF33; + + --color-components-radio-border-checked: #296DFF; + --color-components-radio-border-checked-hover: #5289FF; + --color-components-radio-border-checked-disabled: #155AEF33; + --color-components-radio-bg-disabled: #FFFFFF08; + --color-components-radio-border: #FFFFFF66; + --color-components-radio-border-hover: #FFFFFF99; + --color-components-radio-border-disabled: #FFFFFF03; + --color-components-radio-bg: #FFFFFF00; + --color-components-radio-bg-hover: #FFFFFF0D; + + --color-components-toggle-knob: #F4F4F5; + --color-components-toggle-knob-disabled: #FFFFFF33; + --color-components-toggle-bg: #296DFF; + --color-components-toggle-bg-hover: #5289FF; + --color-components-toggle-bg-disabled: #FFFFFF14; + --color-components-toggle-bg-unchecked: #FFFFFF33; + --color-components-toggle-bg-unchecked-hover: #FFFFFF4D; + --color-components-toggle-bg-unchecked-disabled: #FFFFFF14; + --color-components-toggle-knob-hover: #FEFEFE; + + --color-components-card-bg: #222225; + --color-components-card-border: #FFFFFF08; + --color-components-card-bg-alt: #27272B; + + --color-components-menu-item-text: #C8CEDA99; + --color-components-menu-item-text-active: #FFFFFFF2; + --color-components-menu-item-text-hover: #C8CEDACC; + --color-components-menu-item-text-active-accent: #FFFFFFF2; + + --color-components-panel-bg: #222225; + --color-components-panel-bg-blur: #2C2C30F2; + --color-components-panel-border: #C8CEDA24; + --color-components-panel-border-subtle: #C8CEDA14; + --color-components-panel-gradient-2: #222225; + --color-components-panel-gradient-1: #27272B; + --color-components-panel-bg-alt: #222225; + --color-components-panel-on-panel-item-bg: #27272B; + --color-components-panel-on-panel-item-bg-hover: #3A3A40; + --color-components-panel-on-panel-item-bg-alt: #3A3A40; + --color-components-panel-on-panel-item-bg-transparent: #2C2C30F2; + --color-components-panel-on-panel-item-bg-hover-transparent: #3A3A4000; + --color-components-panel-on-panel-item-bg-destructive-hover-transparent: #FFFBFA00; + + --color-components-panel-bg-transparent: #22222500; + + --color-components-main-nav-nav-button-text: #C8CEDA99; + --color-components-main-nav-nav-button-text-active: #F4F4F5; + --color-components-main-nav-nav-button-bg: #FFFFFF00; + --color-components-main-nav-nav-button-bg-active: #C8CEDA24; + --color-components-main-nav-nav-button-border: #FFFFFF14; + --color-components-main-nav-nav-button-bg-hover: #C8CEDA0A; + + --color-components-main-nav-nav-user-border: #FFFFFF0D; + + --color-components-slider-knob: #F4F4F5; + --color-components-slider-knob-hover: #FEFEFE; + --color-components-slider-knob-disabled: #FFFFFF33; + --color-components-slider-range: #296DFF; + --color-components-slider-track: #FFFFFF33; + --color-components-slider-knob-border-hover: #1018284D; + --color-components-slider-knob-border: #10182833; + + --color-components-segmented-control-item-active-bg: #FFFFFF14; + --color-components-segmented-control-item-active-border: #C8CEDA14; + --color-components-segmented-control-bg-normal: #18181BB2; + --color-components-segmented-control-item-active-accent-bg: #155AEF33; + --color-components-segmented-control-item-active-accent-border: #155AEF4D; + + --color-components-option-card-option-bg: #C8CEDA0A; + --color-components-option-card-option-selected-bg: #FFFFFF0D; + --color-components-option-card-option-selected-border: #5289FF; + --color-components-option-card-option-border: #C8CEDA33; + --color-components-option-card-option-bg-hover: #C8CEDA24; + --color-components-option-card-option-border-hover: #C8CEDA4D; + + --color-components-tab-active: #296DFF; + + --color-components-badge-white-to-dark: #18181BCC; + --color-components-badge-status-light-success-bg: #17B26A; + --color-components-badge-status-light-success-border-inner: #47CD89; + --color-components-badge-status-light-success-halo: #17B26A4D; + + --color-components-badge-status-light-border-outer: #222225; + --color-components-badge-status-light-high-light: #FFFFFF4D; + --color-components-badge-status-light-warning-bg: #F79009; + --color-components-badge-status-light-warning-border-inner: #FDB022; + --color-components-badge-status-light-warning-halo: #F790094D; + + --color-components-badge-status-light-error-bg: #F04438; + --color-components-badge-status-light-error-border-inner: #F97066; + --color-components-badge-status-light-error-halo: #F044384D; + + --color-components-badge-status-light-normal-bg: #0BA5EC; + --color-components-badge-status-light-normal-border-inner: #36BFFA; + --color-components-badge-status-light-normal-halo: #0BA5EC4D; + + --color-components-badge-status-light-disabled-bg: #676F83; + --color-components-badge-status-light-disabled-border-inner: #98A2B2; + --color-components-badge-status-light-disabled-halo: #C8CEDA14; + + --color-components-badge-bg-green-soft: #17B26A24; + --color-components-badge-bg-orange-soft: #F7900924; + --color-components-badge-bg-red-soft: #F0443824; + --color-components-badge-bg-blue-light-soft: #0BA5EC24; + --color-components-badge-bg-gray-soft: #C8CEDA14; + + --color-components-chart-line: #5289FF; + --color-components-chart-area-1: #155AEF33; + --color-components-chart-area-2: #155AEF0A; + --color-components-chart-current-1: #5289FF; + --color-components-chart-current-2: #155AEF4D; + --color-components-chart-bg: #18181BF2; + + --color-components-actionbar-bg: #222225; + --color-components-actionbar-border: #C8CEDA14; + --color-components-actionbar-bg-accent: #27272B; + --color-components-actionbar-border-accent: #5289FF; + + --color-components-dropzone-bg-alt: #18181BCC; + --color-components-dropzone-bg: #18181B66; + --color-components-dropzone-bg-accent: #155AEF33; + --color-components-dropzone-border: #C8CEDA24; + --color-components-dropzone-border-alt: #C8CEDA33; + --color-components-dropzone-border-accent: #84ABFF; + + --color-components-progress-brand-progress: #5289FF; + --color-components-progress-brand-border: #5289FF; + --color-components-progress-brand-bg: #155AEF0A; + + --color-components-progress-white-progress: #FFFFFF; + --color-components-progress-white-border: #FFFFFFF2; + --color-components-progress-white-bg: #FFFFFF03; + + --color-components-progress-gray-progress: #98A2B2; + --color-components-progress-gray-border: #98A2B2; + --color-components-progress-gray-bg: #C8CEDA05; + + --color-components-progress-warning-progress: #FDB022; + --color-components-progress-warning-border: #FDB022; + --color-components-progress-warning-bg: #F790090A; + + --color-components-progress-error-progress: #F97066; + --color-components-progress-error-border: #F97066; + --color-components-progress-error-bg: #F044380A; + + --color-components-chat-input-audio-bg: #155AEF33; + --color-components-chat-input-audio-wave-default: #C8CEDA24; + --color-components-chat-input-bg-mask-1: #18181B0A; + --color-components-chat-input-bg-mask-2: #18181B99; + --color-components-chat-input-border: #C8CEDA33; + --color-components-chat-input-audio-wave-active: #84ABFF; + --color-components-chat-input-audio-bg-alt: #18181BE5; + + --color-components-avatar-shape-fill-stop-0: #FFFFFFF2; + --color-components-avatar-shape-fill-stop-100: #FFFFFFCC; + + --color-components-avatar-bg-mask-stop-0: #FFFFFF33; + --color-components-avatar-bg-mask-stop-100: #FFFFFF08; + + --color-components-avatar-default-avatar-bg: #222225; + --color-components-avatar-mask-darkmode-dimmed: #0000001F; + + --color-components-label-gray: #C8CEDA24; + + --color-components-premium-badge-blue-bg-stop-0: #5289FF; + --color-components-premium-badge-blue-bg-stop-100: #296DFF; + --color-components-premium-badge-blue-stroke-stop-0: #FFFFFF33; + --color-components-premium-badge-blue-stroke-stop-100: #296DFF; + --color-components-premium-badge-blue-text-stop-0: #EFF4FF; + --color-components-premium-badge-blue-text-stop-100: #B2CAFF; + --color-components-premium-badge-blue-glow: #004AEB; + --color-components-premium-badge-blue-bg-stop-0-hover: #84ABFF; + --color-components-premium-badge-blue-bg-stop-100-hover: #004AEB; + --color-components-premium-badge-blue-glow-hover: #D1E0FF; + --color-components-premium-badge-blue-stroke-stop-0-hover: #FFFFFF80; + --color-components-premium-badge-blue-stroke-stop-100-hover: #296DFF; + + --color-components-premium-badge-highlight-stop-0: #FFFFFF1F; + --color-components-premium-badge-highlight-stop-100: #FFFFFF33; + --color-components-premium-badge-indigo-bg-stop-0: #6172F3; + --color-components-premium-badge-indigo-bg-stop-100: #3538CD; + --color-components-premium-badge-indigo-stroke-stop-0: #FFFFFF33; + --color-components-premium-badge-indigo-stroke-stop-100: #444CE7; + --color-components-premium-badge-indigo-text-stop-0: #EEF4FF; + --color-components-premium-badge-indigo-text-stop-100: #C7D7FE; + --color-components-premium-badge-indigo-glow: #3538CD; + --color-components-premium-badge-indigo-glow-hover: #E0EAFF; + --color-components-premium-badge-indigo-bg-stop-0-hover: #A4BCFD; + --color-components-premium-badge-indigo-bg-stop-100-hover: #3538CD; + --color-components-premium-badge-indigo-stroke-stop-0-hover: #FFFFFF80; + --color-components-premium-badge-indigo-stroke-stop-100-hover: #444CE7; + + --color-components-premium-badge-grey-bg-stop-0: #676F83; + --color-components-premium-badge-grey-bg-stop-100: #495464; + --color-components-premium-badge-grey-stroke-stop-0: #FFFFFF1F; + --color-components-premium-badge-grey-stroke-stop-100: #495464; + --color-components-premium-badge-grey-text-stop-0: #F9FAFB; + --color-components-premium-badge-grey-text-stop-100: #E9EBF0; + --color-components-premium-badge-grey-glow: #354052; + --color-components-premium-badge-grey-glow-hover: #F2F4F7; + --color-components-premium-badge-grey-bg-stop-0-hover: #98A2B2; + --color-components-premium-badge-grey-bg-stop-100-hover: #354052; + --color-components-premium-badge-grey-stroke-stop-0-hover: #FFFFFF80; + --color-components-premium-badge-grey-stroke-stop-100-hover: #676F83; + + --color-components-premium-badge-orange-bg-stop-0: #FF692E; + --color-components-premium-badge-orange-bg-stop-100: #E04F16; + --color-components-premium-badge-orange-stroke-stop-0: #FFFFFF33; + --color-components-premium-badge-orange-stroke-stop-100: #FF4405; + --color-components-premium-badge-orange-text-stop-0: #FEF6EE; + --color-components-premium-badge-orange-text-stop-100: #F9DBAF; + --color-components-premium-badge-orange-glow: #B93815; + --color-components-premium-badge-orange-glow-hover: #FDEAD7; + --color-components-premium-badge-orange-bg-stop-0-hover: #FF692E; + --color-components-premium-badge-orange-bg-stop-100-hover: #B93815; + --color-components-premium-badge-orange-stroke-stop-0-hover: #FFFFFF80; + --color-components-premium-badge-orange-stroke-stop-100-hover: #FF4405; + + --color-text-primary: #FBFBFC; + --color-text-secondary: #D9D9DE; + --color-text-tertiary: #C8CEDA99; + --color-text-quaternary: #C8CEDA66; + --color-text-destructive: #F97066; + --color-text-success: #17B26A; + --color-text-warning: #F79009; + --color-text-destructive-secondary: #F97066; + --color-text-success-secondary: #47CD89; + --color-text-warning-secondary: #FDB022; + --color-text-accent: #5289FF; + --color-text-primary-on-surface: #FFFFFFF2; + --color-text-placeholder: #C8CEDA4D; + --color-text-disabled: #C8CEDA4D; + --color-text-accent-secondary: #84ABFF; + --color-text-accent-light-mode-only: #D9D9DE; + --color-text-text-selected: #155AEF4D; + --color-text-secondary-on-surface: #FFFFFFE5; + --color-text-logo-text: #E9E9EC; + --color-text-empty-state-icon: #C8CEDA4D; + --color-text-inverted: #FFFFFF; + --color-text-inverted-dimm: #FFFFFFCC; + + --color-background-body: #1D1D20; + --color-background-default-subtle: #222225; + --color-background-neutral-subtle: #1D1D20; + --color-background-sidenav-bg: #27272AEB; + --color-background-default: #222225; + --color-background-soft: #18181B40; + --color-background-gradient-bg-fill-chat-bg-1: #222225; + --color-background-gradient-bg-fill-chat-bg-2: #1D1D20; + --color-background-gradient-bg-fill-chat-bubble-bg-1: #C8CEDA14; + --color-background-gradient-bg-fill-chat-bubble-bg-2: #C8CEDA05; + --color-background-gradient-bg-fill-debug-bg-1: #C8CEDA14; + --color-background-gradient-bg-fill-debug-bg-2: #18181B0A; + + --color-background-gradient-mask-gray: #18181B14; + --color-background-gradient-mask-transparent: #00000000; + --color-background-gradient-mask-input-clear-2: #393A3E00; + --color-background-gradient-mask-input-clear-1: #393A3E; + --color-background-gradient-mask-transparent-dark: #00000000; + --color-background-gradient-mask-side-panel-2: #18181BE5; + --color-background-gradient-mask-side-panel-1: #18181B0A; + + --color-background-default-burn: #1D1D20; + --color-background-overlay-fullscreen: #27272AF7; + --color-background-default-lighter: #C8CEDA0A; + --color-background-section: #18181B66; + --color-background-interaction-from-bg-1: #18181B66; + --color-background-interaction-from-bg-2: #18181B24; + --color-background-section-burn: #18181B99; + --color-background-default-dodge: #3A3A40; + --color-background-overlay: #18181BCC; + --color-background-default-dimm: #27272B; + --color-background-default-hover: #27272B; + --color-background-overlay-alt: #18181B66; + --color-background-surface-white: #FFFFFFE5; + --color-background-overlay-destructive: #F044384D; + --color-background-overlay-backdrop: #18181BF2; + + --color-shadow-shadow-1: #0000000D; + --color-shadow-shadow-3: #0000001A; + --color-shadow-shadow-4: #0000001F; + --color-shadow-shadow-5: #00000029; + --color-shadow-shadow-6: #00000033; + --color-shadow-shadow-7: #0000003D; + --color-shadow-shadow-8: #00000047; + --color-shadow-shadow-9: #0000005C; + --color-shadow-shadow-2: #00000014; + --color-shadow-shadow-10: #00000066; + + --color-workflow-block-border: #FFFFFF14; + --color-workflow-block-parma-bg: #FFFFFF0D; + --color-workflow-block-bg: #27272B; + --color-workflow-block-bg-transparent: #27272BF5; + --color-workflow-block-border-highlight: #C8CEDA33; + + --color-workflow-canvas-workflow-dot-color: #8585AD26; + --color-workflow-canvas-workflow-bg: #1D1D20; + + --color-workflow-link-line-active: #5289FF; + --color-workflow-link-line-normal: #676F83; + --color-workflow-link-line-handle: #5289FF; + --color-workflow-link-line-normal-transparent: #676F8333; + --color-workflow-link-line-failure-active: #FDB022; + --color-workflow-link-line-failure-handle: #FDB022; + --color-workflow-link-line-failure-button-bg: #F79009; + --color-workflow-link-line-failure-button-hover: #DC6803; + + --color-workflow-link-line-success-active: #47CD89; + --color-workflow-link-line-success-handle: #47CD89; + + --color-workflow-link-line-error-active: #F97066; + --color-workflow-link-line-error-handle: #F97066; + + --color-workflow-minimap-bg: #27272B; + --color-workflow-minimap-block: #C8CEDA14; + + --color-workflow-display-success-bg: #17B26A33; + --color-workflow-display-success-border-1: #17B26AE5; + --color-workflow-display-success-border-2: #17B26ACC; + --color-workflow-display-success-vignette-color: #17B26A40; + --color-workflow-display-success-bg-line-pattern: #18181BCC; + + --color-workflow-display-glass-1: #FFFFFF08; + --color-workflow-display-glass-2: #FFFFFF0D; + --color-workflow-display-vignette-dark: #00000066; + --color-workflow-display-highlight: #FFFFFF1F; + --color-workflow-display-outline: #18181BF2; + --color-workflow-display-error-bg: #F0443833; + --color-workflow-display-error-bg-line-pattern: #18181BCC; + --color-workflow-display-error-border-1: #F04438E5; + --color-workflow-display-error-border-2: #F04438CC; + --color-workflow-display-error-vignette-color: #F0443840; + + --color-workflow-display-warning-bg: #F7900933; + --color-workflow-display-warning-bg-line-pattern: #18181BCC; + --color-workflow-display-warning-border-1: #F79009E5; + --color-workflow-display-warning-border-2: #F79009CC; + --color-workflow-display-warning-vignette-color: #F7900940; + + --color-workflow-display-normal-bg: #0BA5EC33; + --color-workflow-display-normal-bg-line-pattern: #18181BCC; + --color-workflow-display-normal-border-1: #0BA5ECE5; + --color-workflow-display-normal-border-2: #0BA5ECCC; + --color-workflow-display-normal-vignette-color: #0BA5EC40; + + --color-workflow-display-disabled-bg: #C8CEDA33; + --color-workflow-display-disabled-bg-line-pattern: #18181BCC; + --color-workflow-display-disabled-border-1: #C8CEDA99; + --color-workflow-display-disabled-border-2: #C8CEDA40; + --color-workflow-display-disabled-vignette-color: #C8CEDA40; + --color-workflow-display-disabled-outline: #18181BF2; + + --color-workflow-workflow-progress-bg-1: #18181B40; + --color-workflow-workflow-progress-bg-2: #18181B0A; + + --color-divider-subtle: #C8CEDA14; + --color-divider-regular: #C8CEDA24; + --color-divider-deep: #C8CEDA33; + --color-divider-burn: #18181BF2; + --color-divider-intense: #C8CEDA66; + --color-divider-solid: #3A3A40; + --color-divider-solid-alt: #747481; + + --color-state-base-hover: #C8CEDA14; + --color-state-base-active: #C8CEDA33; + --color-state-base-hover-alt: #C8CEDA24; + --color-state-base-handle: #C8CEDA4D; + --color-state-base-handle-hover: #C8CEDA80; + + --color-state-accent-hover: #155AEF24; + --color-state-accent-active: #155AEF24; + --color-state-accent-hover-alt: #155AEF40; + --color-state-accent-solid: #5289FF; + --color-state-accent-active-alt: #155AEF33; + + --color-state-destructive-hover: #F0443824; + --color-state-destructive-hover-alt: #F0443840; + --color-state-destructive-active: #F044384D; + --color-state-destructive-solid: #F97066; + --color-state-destructive-border: #F97066; + + --color-state-success-hover: #17B26A24; + --color-state-success-hover-alt: #17B26A40; + --color-state-success-active: #17B26A4D; + --color-state-success-solid: #47CD89; + + --color-state-warning-hover: #F7900924; + --color-state-warning-hover-alt: #F7900940; + --color-state-warning-active: #F790094D; + --color-state-warning-solid: #F79009; + + --color-effects-highlight: #C8CEDA14; + --color-effects-highlight-lightmode-off: #C8CEDA14; + --color-effects-image-frame: #FFFFFF; + + --color-util-colors-orange-dark-orange-dark-50: #57130A; + --color-util-colors-orange-dark-orange-dark-100: #771A0D; + --color-util-colors-orange-dark-orange-dark-200: #97180C; + --color-util-colors-orange-dark-orange-dark-300: #BC1B06; + --color-util-colors-orange-dark-orange-dark-400: #E62E05; + --color-util-colors-orange-dark-orange-dark-500: #FF4405; + --color-util-colors-orange-dark-orange-dark-600: #FF692E; + --color-util-colors-orange-dark-orange-dark-700: #FF9C66; + + --color-util-colors-orange-orange-50: #511C10; + --color-util-colors-orange-orange-100: #772917; + --color-util-colors-orange-orange-200: #932F19; + --color-util-colors-orange-orange-300: #B93815; + --color-util-colors-orange-orange-400: #E04F16; + --color-util-colors-orange-orange-500: #EF6820; + --color-util-colors-orange-orange-600: #F38744; + --color-util-colors-orange-orange-700: #F7B27A; + --color-util-colors-orange-orange-100-transparent: #77291700; + + --color-util-colors-pink-pink-50: #4E0D30; + --color-util-colors-pink-pink-100: #851651; + --color-util-colors-pink-pink-200: #9E165F; + --color-util-colors-pink-pink-300: #C11574; + --color-util-colors-pink-pink-400: #DD2590; + --color-util-colors-pink-pink-500: #EE46BC; + --color-util-colors-pink-pink-600: #F670C7; + --color-util-colors-pink-pink-700: #FAA7E0; + + --color-util-colors-fuchsia-fuchsia-50: #47104C; + --color-util-colors-fuchsia-fuchsia-100: #6F1877; + --color-util-colors-fuchsia-fuchsia-200: #821890; + --color-util-colors-fuchsia-fuchsia-300: #9F1AB1; + --color-util-colors-fuchsia-fuchsia-400: #BA24D5; + --color-util-colors-fuchsia-fuchsia-500: #D444F1; + --color-util-colors-fuchsia-fuchsia-600: #E478FA; + --color-util-colors-fuchsia-fuchsia-700: #EEAAFD; + + --color-util-colors-purple-purple-50: #27115F; + --color-util-colors-purple-purple-100: #3E1C96; + --color-util-colors-purple-purple-200: #4A1FB8; + --color-util-colors-purple-purple-300: #5925DC; + --color-util-colors-purple-purple-400: #6938EF; + --color-util-colors-purple-purple-500: #7A5AF8; + --color-util-colors-purple-purple-600: #9B8AFB; + --color-util-colors-purple-purple-700: #BDB4FE; + + --color-util-colors-indigo-indigo-50: #1F235B; + --color-util-colors-indigo-indigo-100: #2D3282; + --color-util-colors-indigo-indigo-200: #2D31A6; + --color-util-colors-indigo-indigo-300: #3538CD; + --color-util-colors-indigo-indigo-400: #444CE7; + --color-util-colors-indigo-indigo-500: #6172F3; + --color-util-colors-indigo-indigo-600: #8098F9; + --color-util-colors-indigo-indigo-700: #A4BCFD; + + --color-util-colors-blue-blue-50: #102A56; + --color-util-colors-blue-blue-100: #194185; + --color-util-colors-blue-blue-200: #1849A9; + --color-util-colors-blue-blue-300: #175CD3; + --color-util-colors-blue-blue-400: #1570EF; + --color-util-colors-blue-blue-500: #2E90FA; + --color-util-colors-blue-blue-600: #53B1FD; + --color-util-colors-blue-blue-700: #84CAFF; + + --color-util-colors-blue-light-blue-light-50: #062C41; + --color-util-colors-blue-light-blue-light-100: #0B4A6F; + --color-util-colors-blue-light-blue-light-200: #065986; + --color-util-colors-blue-light-blue-light-300: #026AA2; + --color-util-colors-blue-light-blue-light-400: #0086C9; + --color-util-colors-blue-light-blue-light-500: #0BA5EC; + --color-util-colors-blue-light-blue-light-600: #36BFFA; + --color-util-colors-blue-light-blue-light-700: #7CD4FD; + + --color-util-colors-gray-blue-gray-blue-50: #0D0F1C; + --color-util-colors-gray-blue-gray-blue-100: #101323; + --color-util-colors-gray-blue-gray-blue-200: #293056; + --color-util-colors-gray-blue-gray-blue-300: #363F72; + --color-util-colors-gray-blue-gray-blue-400: #3E4784; + --color-util-colors-gray-blue-gray-blue-500: #4E5BA6; + --color-util-colors-gray-blue-gray-blue-600: #717BBC; + --color-util-colors-gray-blue-gray-blue-700: #B3B8DB; + + --color-util-colors-blue-brand-blue-brand-50: #002066; + --color-util-colors-blue-brand-blue-brand-100: #00329E; + --color-util-colors-blue-brand-blue-brand-200: #003DC1; + --color-util-colors-blue-brand-blue-brand-300: #004AEB; + --color-util-colors-blue-brand-blue-brand-400: #155AEF; + --color-util-colors-blue-brand-blue-brand-500: #296DFF; + --color-util-colors-blue-brand-blue-brand-600: #5289FF; + --color-util-colors-blue-brand-blue-brand-700: #84ABFF; + + --color-util-colors-red-red-50: #55160C; + --color-util-colors-red-red-100: #7A271A; + --color-util-colors-red-red-200: #912018; + --color-util-colors-red-red-300: #B42318; + --color-util-colors-red-red-400: #D92D20; + --color-util-colors-red-red-500: #F04438; + --color-util-colors-red-red-600: #F97066; + --color-util-colors-red-red-700: #FDA29B; + + --color-util-colors-green-green-50: #053321; + --color-util-colors-green-green-100: #074D31; + --color-util-colors-green-green-200: #085D3A; + --color-util-colors-green-green-300: #067647; + --color-util-colors-green-green-400: #079455; + --color-util-colors-green-green-500: #17B26A; + --color-util-colors-green-green-600: #47CD89; + --color-util-colors-green-green-700: #75E0A7; + + --color-util-colors-warning-warning-50: #4E1D09; + --color-util-colors-warning-warning-100: #7A2E0E; + --color-util-colors-warning-warning-200: #93370D; + --color-util-colors-warning-warning-300: #B54708; + --color-util-colors-warning-warning-400: #DC6803; + --color-util-colors-warning-warning-500: #F79009; + --color-util-colors-warning-warning-600: #FDB022; + --color-util-colors-warning-warning-700: #FEC84B; + + --color-util-colors-yellow-yellow-50: #542C0D; + --color-util-colors-yellow-yellow-100: #713B12; + --color-util-colors-yellow-yellow-200: #854A0E; + --color-util-colors-yellow-yellow-300: #A15C07; + --color-util-colors-yellow-yellow-400: #CA8504; + --color-util-colors-yellow-yellow-500: #EAAA08; + --color-util-colors-yellow-yellow-600: #FAC515; + --color-util-colors-yellow-yellow-700: #FDE272; + + --color-util-colors-teal-teal-50: #0A2926; + --color-util-colors-teal-teal-100: #134E48; + --color-util-colors-teal-teal-200: #125D56; + --color-util-colors-teal-teal-300: #107569; + --color-util-colors-teal-teal-400: #0E9384; + --color-util-colors-teal-teal-500: #15B79E; + --color-util-colors-teal-teal-600: #2ED3B7; + --color-util-colors-teal-teal-700: #5FE9D0; + + --color-util-colors-cyan-cyan-50: #0D2D3A; + --color-util-colors-cyan-cyan-100: #164C63; + --color-util-colors-cyan-cyan-200: #155B75; + --color-util-colors-cyan-cyan-300: #0E7090; + --color-util-colors-cyan-cyan-400: #088AB2; + --color-util-colors-cyan-cyan-500: #06AED4; + --color-util-colors-cyan-cyan-600: #22CCEE; + --color-util-colors-cyan-cyan-700: #67E3F9; + + --color-util-colors-violet-violet-50: #2E125E; + --color-util-colors-violet-violet-100: #491C96; + --color-util-colors-violet-violet-200: #5720B7; + --color-util-colors-violet-violet-300: #6927DA; + --color-util-colors-violet-violet-400: #7839EE; + --color-util-colors-violet-violet-500: #875BF7; + --color-util-colors-violet-violet-600: #A48AFB; + --color-util-colors-violet-violet-700: #C3B5FD; + + --color-util-colors-gray-gray-50: #0C111C; + --color-util-colors-gray-gray-100: #101828; + --color-util-colors-gray-gray-200: #18222F; + --color-util-colors-gray-gray-300: #354052; + --color-util-colors-gray-gray-400: #495464; + --color-util-colors-gray-gray-500: #676F83; + --color-util-colors-gray-gray-600: #98A2B2; + --color-util-colors-gray-gray-700: #D0D5DC; + + --color-util-colors-green-light-green-light-50: #15290A; + --color-util-colors-green-light-green-light-100: #2B5314; + --color-util-colors-green-light-green-light-200: #326212; + --color-util-colors-green-light-green-light-300: #3B7C0F; + --color-util-colors-green-light-green-light-500: #66C61C; + --color-util-colors-green-light-green-light-400: #4CA30D; + --color-util-colors-green-light-green-light-600: #85E13A; + --color-util-colors-green-light-green-light-700: #A6EF67; + + --color-util-colors-rose-rose-50: #510B24; + --color-util-colors-rose-rose-100: #89123E; + --color-util-colors-rose-rose-200: #A11043; + --color-util-colors-rose-rose-300: #C01048; + --color-util-colors-rose-rose-400: #E31B54; + --color-util-colors-rose-rose-500: #F63D68; + --color-util-colors-rose-rose-600: #FD6F8E; + --color-util-colors-rose-rose-700: #FEA3B4; + + --color-util-colors-midnight-midnight-50: #171C22; + --color-util-colors-midnight-midnight-100: #202431; + --color-util-colors-midnight-midnight-200: #2F3648; + --color-util-colors-midnight-midnight-300: #3E465E; + --color-util-colors-midnight-midnight-400: #5D698D; + --color-util-colors-midnight-midnight-500: #828DAD; + --color-util-colors-midnight-midnight-600: #A7AEC5; + --color-util-colors-midnight-midnight-700: #C6CBD9; + + --color-third-party-LangChain: #FFFFFF; + --color-third-party-Langfuse: #FFFFFF; + + --color-chatbot-bg: linear-gradient(180deg, rgba(34, 34, 37, 0.90) 0%, rgba(29, 29, 32, 0.90) 90.48%); + --color-chat-bubble-bg: linear-gradient(180deg, rgba(200, 206, 218, 0.08) 0%, rgba(200, 206, 218, 0.02) 100%); + --color-third-party-Github: #FFFFFF; + --color-third-party-Github-tertiary: #C8CEDA99; + --color-third-party-Github-secondary: #D9D9DE; + --color-third-party-model-bg-openai: #121212; + --color-third-party-model-bg-anthropic: #1D1917; + --color-third-party-model-bg-default: #0B0B0E; + --color-workflow-process-bg: linear-gradient(90deg, rgba(24, 24, 27, 0.25) 0%, rgba(24, 24, 27, 0.04) 100%); + --color-marketplace-divider-bg: linear-gradient(90deg, rgba(200, 206, 218, 0.14) 0%, rgba(0, 0, 0, 0) 100%); + } +} + html[data-theme="dark"] { --color-components-input-bg-normal: #FFFFFF14; --color-components-input-text-placeholder: #C8CEDA4D; diff --git a/web/themes/light.css b/web/themes/light.css index ed563ad594..4e0ee8ae3e 100644 --- a/web/themes/light.css +++ b/web/themes/light.css @@ -1,4 +1,706 @@ /* Attention: Generate by code. Don't update by hand!!! */ +@media (prefers-color-scheme: light) { + html:not([data-theme="light"]):not([data-theme="dark"]) { + color-scheme: light; + --color-components-input-bg-normal: #C8CEDA40; + --color-components-input-text-placeholder: #98A2B2; + --color-components-input-bg-hover: #C8CEDA24; + --color-components-input-bg-active: #F9FAFB; + --color-components-input-border-active: #D0D5DC; + --color-components-input-border-destructive: #FDA29B; + --color-components-input-text-filled: #101828; + --color-components-input-bg-destructive: #FFFFFF; + --color-components-input-bg-disabled: #C8CEDA24; + --color-components-input-text-disabled: #D0D5DC; + --color-components-input-text-filled-disabled: #676F83; + --color-components-input-border-hover: #D0D5DC; + --color-components-input-border-active-prompt-1: #0BA5EC; + --color-components-input-border-active-prompt-2: #155AEF; + + --color-components-kbd-bg-gray: #1018280A; + --color-components-kbd-bg-white: #FFFFFF1F; + + --color-components-tooltip-bg: #FFFFFFF2; + + --color-components-button-primary-text: #FFFFFF; + --color-components-button-primary-bg: #155AEF; + --color-components-button-primary-border: #1018280A; + --color-components-button-primary-bg-hover: #004AEB; + --color-components-button-primary-border-hover: #10182814; + --color-components-button-primary-bg-disabled: #155AEF24; + --color-components-button-primary-border-disabled: #FFFFFF00; + --color-components-button-primary-text-disabled: #FFFFFF99; + + --color-components-button-secondary-text: #354052; + --color-components-button-secondary-text-disabled: #10182840; + --color-components-button-secondary-bg: #FFFFFF; + --color-components-button-secondary-bg-hover: #F9FAFB; + --color-components-button-secondary-bg-disabled: #F9FAFB; + --color-components-button-secondary-border: #10182824; + --color-components-button-secondary-border-hover: #10182833; + --color-components-button-secondary-border-disabled: #1018280A; + + --color-components-button-tertiary-text: #354052; + --color-components-button-tertiary-text-disabled: #10182840; + --color-components-button-tertiary-bg: #F2F4F7; + --color-components-button-tertiary-bg-hover: #E9EBF0; + --color-components-button-tertiary-bg-disabled: #F9FAFB; + + --color-components-button-ghost-text: #354052; + --color-components-button-ghost-text-disabled: #10182840; + --color-components-button-ghost-bg-hover: #C8CEDA33; + + --color-components-button-destructive-primary-text: #FFFFFF; + --color-components-button-destructive-primary-text-disabled: #FFFFFF99; + --color-components-button-destructive-primary-bg: #D92D20; + --color-components-button-destructive-primary-bg-hover: #B42318; + --color-components-button-destructive-primary-bg-disabled: #FEE4E2; + --color-components-button-destructive-primary-border: #18181B0A; + --color-components-button-destructive-primary-border-hover: #18181B14; + --color-components-button-destructive-primary-border-disabled: #FFFFFF00; + + --color-components-button-destructive-secondary-text: #D92D20; + --color-components-button-destructive-secondary-text-disabled: #F0443833; + --color-components-button-destructive-secondary-bg: #FFFFFF; + --color-components-button-destructive-secondary-bg-hover: #FEF3F2; + --color-components-button-destructive-secondary-bg-disabled: #FEF3F2; + --color-components-button-destructive-secondary-border: #18181B14; + --color-components-button-destructive-secondary-border-hover: #F0443840; + --color-components-button-destructive-secondary-border-disabled: #F044380A; + + --color-components-button-destructive-tertiary-text: #D92D20; + --color-components-button-destructive-tertiary-text-disabled: #F0443833; + --color-components-button-destructive-tertiary-bg: #FEE4E2; + --color-components-button-destructive-tertiary-bg-hover: #FECDCA; + --color-components-button-destructive-tertiary-bg-disabled: #F044380A; + + --color-components-button-destructive-ghost-text: #D92D20; + --color-components-button-destructive-ghost-text-disabled: #F0443833; + --color-components-button-destructive-ghost-bg-hover: #FEE4E2; + + --color-components-button-secondary-accent-text: #155AEF; + --color-components-button-secondary-accent-text-disabled: #B2CAFF; + --color-components-button-secondary-accent-bg: #FFFFFF; + --color-components-button-secondary-accent-bg-hover: #F2F4F7; + --color-components-button-secondary-accent-bg-disabled: #F9FAFB; + --color-components-button-secondary-accent-border: #10182824; + --color-components-button-secondary-accent-border-hover: #10182824; + --color-components-button-secondary-accent-border-disabled: #1018280A; + + --color-components-checkbox-icon: #FFFFFF; + --color-components-checkbox-icon-disabled: #FFFFFF80; + --color-components-checkbox-bg: #155AEF; + --color-components-checkbox-bg-hover: #004AEB; + --color-components-checkbox-bg-disabled: #F2F4F7; + --color-components-checkbox-border: #D0D5DC; + --color-components-checkbox-border-hover: #98A2B2; + --color-components-checkbox-border-disabled: #18181B0A; + --color-components-checkbox-bg-unchecked: #FFFFFF; + --color-components-checkbox-bg-unchecked-hover: #FFFFFF; + --color-components-checkbox-bg-disabled-checked: #B2CAFF; + + --color-components-radio-border-checked: #155AEF; + --color-components-radio-border-checked-hover: #004AEB; + --color-components-radio-border-checked-disabled: #B2CAFF; + --color-components-radio-bg-disabled: #FFFFFF00; + --color-components-radio-border: #D0D5DC; + --color-components-radio-border-hover: #98A2B2; + --color-components-radio-border-disabled: #18181B0A; + --color-components-radio-bg: #FFFFFF00; + --color-components-radio-bg-hover: #FFFFFF00; + + --color-components-toggle-knob: #FFFFFF; + --color-components-toggle-knob-disabled: #FFFFFFF2; + --color-components-toggle-bg: #155AEF; + --color-components-toggle-bg-hover: #004AEB; + --color-components-toggle-bg-disabled: #D1E0FF; + --color-components-toggle-bg-unchecked: #E9EBF0; + --color-components-toggle-bg-unchecked-hover: #D0D5DC; + --color-components-toggle-bg-unchecked-disabled: #F2F4F7; + --color-components-toggle-knob-hover: #FFFFFF; + + --color-components-card-bg: #FCFCFD; + --color-components-card-border: #FFFFFF; + --color-components-card-bg-alt: #FFFFFF; + + --color-components-menu-item-text: #495464; + --color-components-menu-item-text-active: #18222F; + --color-components-menu-item-text-hover: #354052; + --color-components-menu-item-text-active-accent: #18222F; + + --color-components-panel-bg: #FFFFFF; + --color-components-panel-bg-blur: #FFFFFFF2; + --color-components-panel-border: #10182814; + --color-components-panel-border-subtle: #10182814; + --color-components-panel-gradient-2: #F9FAFB; + --color-components-panel-gradient-1: #FFFFFF; + --color-components-panel-bg-alt: #F9FAFB; + --color-components-panel-on-panel-item-bg: #FFFFFF; + --color-components-panel-on-panel-item-bg-hover: #F9FAFB; + --color-components-panel-on-panel-item-bg-alt: #F9FAFB; + --color-components-panel-on-panel-item-bg-transparent: #FFFFFFF2; + --color-components-panel-on-panel-item-bg-hover-transparent: #F9FAFB00; + --color-components-panel-on-panel-item-bg-destructive-hover-transparent: #FEF3F200; + + --color-components-panel-bg-transparent: #FFFFFF00; + + --color-components-main-nav-nav-button-text: #495464; + --color-components-main-nav-nav-button-text-active: #155AEF; + --color-components-main-nav-nav-button-bg: #FFFFFF00; + --color-components-main-nav-nav-button-bg-active: #FCFCFD; + --color-components-main-nav-nav-button-border: #FFFFFFF2; + --color-components-main-nav-nav-button-bg-hover: #1018280A; + + --color-components-main-nav-nav-user-border: #FFFFFF; + + --color-components-slider-knob: #FFFFFF; + --color-components-slider-knob-hover: #FFFFFF; + --color-components-slider-knob-disabled: #FFFFFFF2; + --color-components-slider-range: #296DFF; + --color-components-slider-track: #E9EBF0; + --color-components-slider-knob-border-hover: #10182833; + --color-components-slider-knob-border: #10182824; + + --color-components-segmented-control-item-active-bg: #FFFFFF; + --color-components-segmented-control-item-active-border: #FFFFFF; + --color-components-segmented-control-bg-normal: #C8CEDA33; + --color-components-segmented-control-item-active-accent-bg: #FFFFFF; + --color-components-segmented-control-item-active-accent-border: #FFFFFF; + + --color-components-option-card-option-bg: #FCFCFD; + --color-components-option-card-option-selected-bg: #FFFFFF; + --color-components-option-card-option-selected-border: #296DFF; + --color-components-option-card-option-border: #E9EBF0; + --color-components-option-card-option-bg-hover: #FFFFFF; + --color-components-option-card-option-border-hover: #D0D5DC; + + --color-components-tab-active: #155AEF; + + --color-components-badge-white-to-dark: #FFFFFF; + --color-components-badge-status-light-success-bg: #47CD89; + --color-components-badge-status-light-success-border-inner: #17B26A; + --color-components-badge-status-light-success-halo: #17B26A40; + + --color-components-badge-status-light-border-outer: #FFFFFF; + --color-components-badge-status-light-high-light: #FFFFFF4D; + --color-components-badge-status-light-warning-bg: #FDB022; + --color-components-badge-status-light-warning-border-inner: #F79009; + --color-components-badge-status-light-warning-halo: #F7900940; + + --color-components-badge-status-light-error-bg: #F97066; + --color-components-badge-status-light-error-border-inner: #F04438; + --color-components-badge-status-light-error-halo: #F0443840; + + --color-components-badge-status-light-normal-bg: #36BFFA; + --color-components-badge-status-light-normal-border-inner: #0BA5EC; + --color-components-badge-status-light-normal-halo: #0BA5EC40; + + --color-components-badge-status-light-disabled-bg: #98A2B2; + --color-components-badge-status-light-disabled-border-inner: #676F83; + --color-components-badge-status-light-disabled-halo: #1018280A; + + --color-components-badge-bg-green-soft: #17B26A14; + --color-components-badge-bg-orange-soft: #F7900914; + --color-components-badge-bg-red-soft: #F0443814; + --color-components-badge-bg-blue-light-soft: #0BA5EC14; + --color-components-badge-bg-gray-soft: #1018280A; + + --color-components-chart-line: #296DFF; + --color-components-chart-area-1: #155AEF24; + --color-components-chart-area-2: #155AEF0A; + --color-components-chart-current-1: #155AEF; + --color-components-chart-current-2: #D1E0FF; + --color-components-chart-bg: #FFFFFF; + + --color-components-actionbar-bg: #FFFFFFF2; + --color-components-actionbar-border: #1018280A; + --color-components-actionbar-bg-accent: #F5F7FF; + --color-components-actionbar-border-accent: #B2CAFF; + + --color-components-dropzone-bg-alt: #F2F4F7; + --color-components-dropzone-bg: #F9FAFB; + --color-components-dropzone-bg-accent: #155AEF24; + --color-components-dropzone-border: #10182814; + --color-components-dropzone-border-alt: #10182833; + --color-components-dropzone-border-accent: #84ABFF; + + --color-components-progress-brand-progress: #296DFF; + --color-components-progress-brand-border: #296DFF; + --color-components-progress-brand-bg: #155AEF0A; + + --color-components-progress-white-progress: #FFFFFF; + --color-components-progress-white-border: #FFFFFFF2; + --color-components-progress-white-bg: #FFFFFF03; + + --color-components-progress-gray-progress: #98A2B2; + --color-components-progress-gray-border: #98A2B2; + --color-components-progress-gray-bg: #C8CEDA05; + + --color-components-progress-warning-progress: #F79009; + --color-components-progress-warning-border: #F79009; + --color-components-progress-warning-bg: #F790090A; + + --color-components-progress-error-progress: #F04438; + --color-components-progress-error-border: #F04438; + --color-components-progress-error-bg: #F044380A; + + --color-components-chat-input-audio-bg: #EFF4FF; + --color-components-chat-input-audio-wave-default: #155AEF33; + --color-components-chat-input-bg-mask-1: #FFFFFF03; + --color-components-chat-input-bg-mask-2: #F2F4F7; + --color-components-chat-input-border: #FFFFFF; + --color-components-chat-input-audio-wave-active: #296DFF; + --color-components-chat-input-audio-bg-alt: #FCFCFD; + + --color-components-avatar-shape-fill-stop-0: #FFFFFF; + --color-components-avatar-shape-fill-stop-100: #FFFFFFE5; + + --color-components-avatar-bg-mask-stop-0: #FFFFFF1F; + --color-components-avatar-bg-mask-stop-100: #FFFFFF14; + + --color-components-avatar-default-avatar-bg: #D0D5DC; + --color-components-avatar-mask-darkmode-dimmed: #FFFFFF00; + + --color-components-label-gray: #F2F4F7; + + --color-components-premium-badge-blue-bg-stop-0: #5289FF; + --color-components-premium-badge-blue-bg-stop-100: #155AEF; + --color-components-premium-badge-blue-stroke-stop-0: #FFFFFFF2; + --color-components-premium-badge-blue-stroke-stop-100: #155AEF; + --color-components-premium-badge-blue-text-stop-0: #F5F7FF; + --color-components-premium-badge-blue-text-stop-100: #D1E0FF; + --color-components-premium-badge-blue-glow: #00329E; + --color-components-premium-badge-blue-bg-stop-0-hover: #296DFF; + --color-components-premium-badge-blue-bg-stop-100-hover: #004AEB; + --color-components-premium-badge-blue-glow-hover: #84ABFF; + --color-components-premium-badge-blue-stroke-stop-0-hover: #FFFFFFF2; + --color-components-premium-badge-blue-stroke-stop-100-hover: #00329E; + + --color-components-premium-badge-highlight-stop-0: #FFFFFF1F; + --color-components-premium-badge-highlight-stop-100: #FFFFFF4D; + --color-components-premium-badge-indigo-bg-stop-0: #8098F9; + --color-components-premium-badge-indigo-bg-stop-100: #444CE7; + --color-components-premium-badge-indigo-stroke-stop-0: #FFFFFFF2; + --color-components-premium-badge-indigo-stroke-stop-100: #6172F3; + --color-components-premium-badge-indigo-text-stop-0: #F5F8FF; + --color-components-premium-badge-indigo-text-stop-100: #E0EAFF; + --color-components-premium-badge-indigo-glow: #2D3282; + --color-components-premium-badge-indigo-glow-hover: #A4BCFD; + --color-components-premium-badge-indigo-bg-stop-0-hover: #6172F3; + --color-components-premium-badge-indigo-bg-stop-100-hover: #2D31A6; + --color-components-premium-badge-indigo-stroke-stop-0-hover: #FFFFFFF2; + --color-components-premium-badge-indigo-stroke-stop-100-hover: #2D31A6; + + --color-components-premium-badge-grey-bg-stop-0: #98A2B2; + --color-components-premium-badge-grey-bg-stop-100: #676F83; + --color-components-premium-badge-grey-stroke-stop-0: #FFFFFFF2; + --color-components-premium-badge-grey-stroke-stop-100: #676F83; + --color-components-premium-badge-grey-text-stop-0: #FCFCFD; + --color-components-premium-badge-grey-text-stop-100: #F2F4F7; + --color-components-premium-badge-grey-glow: #101828; + --color-components-premium-badge-grey-glow-hover: #D0D5DC; + --color-components-premium-badge-grey-bg-stop-0-hover: #676F83; + --color-components-premium-badge-grey-bg-stop-100-hover: #354052; + --color-components-premium-badge-grey-stroke-stop-0-hover: #FFFFFFF2; + --color-components-premium-badge-grey-stroke-stop-100-hover: #354052; + + --color-components-premium-badge-orange-bg-stop-0: #FF692E; + --color-components-premium-badge-orange-bg-stop-100: #E04F16; + --color-components-premium-badge-orange-stroke-stop-0: #FFFFFFF2; + --color-components-premium-badge-orange-stroke-stop-100: #E62E05; + --color-components-premium-badge-orange-text-stop-0: #FEFAF5; + --color-components-premium-badge-orange-text-stop-100: #FDEAD7; + --color-components-premium-badge-orange-glow: #772917; + --color-components-premium-badge-orange-glow-hover: #F7B27A; + --color-components-premium-badge-orange-bg-stop-0-hover: #FF4405; + --color-components-premium-badge-orange-bg-stop-100-hover: #B93815; + --color-components-premium-badge-orange-stroke-stop-0-hover: #FFFFFFF2; + --color-components-premium-badge-orange-stroke-stop-100-hover: #BC1B06; + + --color-text-primary: #101828; + --color-text-secondary: #354052; + --color-text-tertiary: #676F83; + --color-text-quaternary: #1018284D; + --color-text-destructive: #D92D20; + --color-text-success: #079455; + --color-text-warning: #DC6803; + --color-text-destructive-secondary: #F04438; + --color-text-success-secondary: #17B26A; + --color-text-warning-secondary: #F79009; + --color-text-accent: #155AEF; + --color-text-primary-on-surface: #FFFFFF; + --color-text-placeholder: #98A2B2; + --color-text-disabled: #D0D5DC; + --color-text-accent-secondary: #296DFF; + --color-text-accent-light-mode-only: #155AEF; + --color-text-text-selected: #155AEF24; + --color-text-secondary-on-surface: #FFFFFFE5; + --color-text-logo-text: #18222F; + --color-text-empty-state-icon: #D0D5DC; + --color-text-inverted: #000000; + --color-text-inverted-dimm: #000000F2; + + --color-background-body: #F2F4F7; + --color-background-default-subtle: #FCFCFD; + --color-background-neutral-subtle: #F9FAFB; + --color-background-sidenav-bg: #FFFFFFCC; + --color-background-default: #FFFFFF; + --color-background-soft: #F9FAFB; + --color-background-gradient-bg-fill-chat-bg-1: #F9FAFB; + --color-background-gradient-bg-fill-chat-bg-2: #F2F4F7; + --color-background-gradient-bg-fill-chat-bubble-bg-1: #FFFFFF; + --color-background-gradient-bg-fill-chat-bubble-bg-2: #FFFFFF99; + --color-background-gradient-bg-fill-debug-bg-1: #FFFFFF00; + --color-background-gradient-bg-fill-debug-bg-2: #C8CEDA24; + + --color-background-gradient-mask-gray: #C8CEDA33; + --color-background-gradient-mask-transparent: #FFFFFF00; + --color-background-gradient-mask-input-clear-2: #E9EBF000; + --color-background-gradient-mask-input-clear-1: #E9EBF0; + --color-background-gradient-mask-transparent-dark: #00000000; + --color-background-gradient-mask-side-panel-2: #1018284D; + --color-background-gradient-mask-side-panel-1: #10182805; + + --color-background-default-burn: #E9EBF0; + --color-background-overlay-fullscreen: #F9FAFBF2; + --color-background-default-lighter: #FFFFFF80; + --color-background-section: #F9FAFB; + --color-background-interaction-from-bg-1: #C8CEDA33; + --color-background-interaction-from-bg-2: #C8CEDA24; + --color-background-section-burn: #F2F4F7; + --color-background-default-dodge: #FFFFFF; + --color-background-overlay: #10182899; + --color-background-default-dimm: #E9EBF0; + --color-background-default-hover: #F9FAFB; + --color-background-overlay-alt: #10182866; + --color-background-surface-white: #FFFFFFF2; + --color-background-overlay-destructive: #F044384D; + --color-background-overlay-backdrop: #F2F4F7F2; + + --color-shadow-shadow-1: #09090B08; + --color-shadow-shadow-3: #09090B0D; + --color-shadow-shadow-4: #09090B0F; + --color-shadow-shadow-5: #09090B14; + --color-shadow-shadow-6: #09090B1A; + --color-shadow-shadow-7: #09090B1F; + --color-shadow-shadow-8: #09090B24; + --color-shadow-shadow-9: #09090B2E; + --color-shadow-shadow-2: #09090B0A; + --color-shadow-shadow-10: #09090B0D; + + --color-workflow-block-border: #FFFFFF; + --color-workflow-block-parma-bg: #F2F4F7; + --color-workflow-block-bg: #FCFCFD; + --color-workflow-block-bg-transparent: #FCFCFDE5; + --color-workflow-block-border-highlight: #155AEF24; + + --color-workflow-canvas-workflow-dot-color: #8585AD26; + --color-workflow-canvas-workflow-bg: #F2F4F7; + + --color-workflow-link-line-active: #296DFF; + --color-workflow-link-line-normal: #D0D5DC; + --color-workflow-link-line-handle: #296DFF; + --color-workflow-link-line-normal-transparent: #D0D5DC33; + --color-workflow-link-line-failure-active: #F79009; + --color-workflow-link-line-failure-handle: #F79009; + --color-workflow-link-line-failure-button-bg: #DC6803; + --color-workflow-link-line-failure-button-hover: #B54708; + + --color-workflow-link-line-success-active: #17B26A; + --color-workflow-link-line-success-handle: #17B26A; + + --color-workflow-link-line-error-active: #F04438; + --color-workflow-link-line-error-handle: #F04438; + + --color-workflow-minimap-bg: #E9EBF0; + --color-workflow-minimap-block: #C8CEDA4D; + + --color-workflow-display-success-bg: #ECFDF3; + --color-workflow-display-success-border-1: #17B26ACC; + --color-workflow-display-success-border-2: #17B26A80; + --color-workflow-display-success-vignette-color: #17B26A33; + --color-workflow-display-success-bg-line-pattern: #17B26A4D; + + --color-workflow-display-glass-1: #FFFFFF1F; + --color-workflow-display-glass-2: #FFFFFF80; + --color-workflow-display-vignette-dark: #0000001F; + --color-workflow-display-highlight: #FFFFFF80; + --color-workflow-display-outline: #0000000D; + --color-workflow-display-error-bg: #FEF3F2; + --color-workflow-display-error-bg-line-pattern: #F044384D; + --color-workflow-display-error-border-1: #F04438CC; + --color-workflow-display-error-border-2: #F0443880; + --color-workflow-display-error-vignette-color: #F0443833; + + --color-workflow-display-warning-bg: #FFFAEB; + --color-workflow-display-warning-bg-line-pattern: #F790094D; + --color-workflow-display-warning-border-1: #F79009CC; + --color-workflow-display-warning-border-2: #F7900980; + --color-workflow-display-warning-vignette-color: #F7900933; + + --color-workflow-display-normal-bg: #F0F9FF; + --color-workflow-display-normal-bg-line-pattern: #0BA5EC4D; + --color-workflow-display-normal-border-1: #0BA5ECCC; + --color-workflow-display-normal-border-2: #0BA5EC80; + --color-workflow-display-normal-vignette-color: #0BA5EC33; + + --color-workflow-display-disabled-bg: #F9FAFB; + --color-workflow-display-disabled-bg-line-pattern: #C8CEDA4D; + --color-workflow-display-disabled-border-1: #C8CEDA99; + --color-workflow-display-disabled-border-2: #C8CEDA66; + --color-workflow-display-disabled-vignette-color: #C8CEDA66; + --color-workflow-display-disabled-outline: #00000000; + + --color-workflow-workflow-progress-bg-1: #C8CEDA33; + --color-workflow-workflow-progress-bg-2: #C8CEDA0A; + + --color-divider-subtle: #1018280A; + --color-divider-regular: #10182814; + --color-divider-deep: #10182824; + --color-divider-burn: #1018280A; + --color-divider-intense: #1018284D; + --color-divider-solid: #D0D5DC; + --color-divider-solid-alt: #98A2B2; + + --color-state-base-hover: #C8CEDA33; + --color-state-base-active: #C8CEDA66; + --color-state-base-hover-alt: #C8CEDA66; + --color-state-base-handle: #10182833; + --color-state-base-handle-hover: #1018284D; + + --color-state-accent-hover: #EFF4FF; + --color-state-accent-active: #155AEF14; + --color-state-accent-hover-alt: #D1E0FF; + --color-state-accent-solid: #296DFF; + --color-state-accent-active-alt: #155AEF24; + + --color-state-destructive-hover: #FEF3F2; + --color-state-destructive-hover-alt: #FEE4E2; + --color-state-destructive-active: #FECDCA; + --color-state-destructive-solid: #F04438; + --color-state-destructive-border: #FDA29B; + + --color-state-success-hover: #ECFDF3; + --color-state-success-hover-alt: #DCFAE6; + --color-state-success-active: #ABEFC6; + --color-state-success-solid: #17B26A; + + --color-state-warning-hover: #FFFAEB; + --color-state-warning-hover-alt: #FEF0C7; + --color-state-warning-active: #FEDF89; + --color-state-warning-solid: #F79009; + + --color-effects-highlight: #FFFFFF; + --color-effects-highlight-lightmode-off: #FFFFFF00; + --color-effects-image-frame: #FFFFFF; + + --color-util-colors-orange-dark-orange-dark-50: #FFF4ED; + --color-util-colors-orange-dark-orange-dark-100: #FFE6D5; + --color-util-colors-orange-dark-orange-dark-200: #FFD6AE; + --color-util-colors-orange-dark-orange-dark-300: #FF9C66; + --color-util-colors-orange-dark-orange-dark-400: #FF692E; + --color-util-colors-orange-dark-orange-dark-500: #FF4405; + --color-util-colors-orange-dark-orange-dark-600: #E62E05; + --color-util-colors-orange-dark-orange-dark-700: #BC1B06; + + --color-util-colors-orange-orange-50: #FEF6EE; + --color-util-colors-orange-orange-100: #FDEAD7; + --color-util-colors-orange-orange-200: #F9DBAF; + --color-util-colors-orange-orange-300: #F7B27A; + --color-util-colors-orange-orange-400: #F38744; + --color-util-colors-orange-orange-500: #EF6820; + --color-util-colors-orange-orange-600: #E04F16; + --color-util-colors-orange-orange-700: #B93815; + --color-util-colors-orange-orange-100-transparent: #FDEAD700; + + --color-util-colors-pink-pink-50: #FDF2FA; + --color-util-colors-pink-pink-100: #FCE7F6; + --color-util-colors-pink-pink-200: #FCCEEE; + --color-util-colors-pink-pink-300: #FAA7E0; + --color-util-colors-pink-pink-400: #F670C7; + --color-util-colors-pink-pink-500: #EE46BC; + --color-util-colors-pink-pink-600: #DD2590; + --color-util-colors-pink-pink-700: #C11574; + + --color-util-colors-fuchsia-fuchsia-50: #FDF4FF; + --color-util-colors-fuchsia-fuchsia-100: #FBE8FF; + --color-util-colors-fuchsia-fuchsia-200: #F6D0FE; + --color-util-colors-fuchsia-fuchsia-300: #EEAAFD; + --color-util-colors-fuchsia-fuchsia-400: #E478FA; + --color-util-colors-fuchsia-fuchsia-500: #D444F1; + --color-util-colors-fuchsia-fuchsia-600: #BA24D5; + --color-util-colors-fuchsia-fuchsia-700: #9F1AB1; + + --color-util-colors-purple-purple-50: #F4F3FF; + --color-util-colors-purple-purple-100: #EBE9FE; + --color-util-colors-purple-purple-200: #D9D6FE; + --color-util-colors-purple-purple-300: #BDB4FE; + --color-util-colors-purple-purple-400: #9B8AFB; + --color-util-colors-purple-purple-500: #7A5AF8; + --color-util-colors-purple-purple-600: #6938EF; + --color-util-colors-purple-purple-700: #5925DC; + + --color-util-colors-indigo-indigo-50: #EEF4FF; + --color-util-colors-indigo-indigo-100: #E0EAFF; + --color-util-colors-indigo-indigo-200: #C7D7FE; + --color-util-colors-indigo-indigo-300: #A4BCFD; + --color-util-colors-indigo-indigo-400: #8098F9; + --color-util-colors-indigo-indigo-500: #6172F3; + --color-util-colors-indigo-indigo-600: #444CE7; + --color-util-colors-indigo-indigo-700: #3538CD; + + --color-util-colors-blue-blue-50: #EFF8FF; + --color-util-colors-blue-blue-100: #D1E9FF; + --color-util-colors-blue-blue-200: #B2DDFF; + --color-util-colors-blue-blue-300: #84CAFF; + --color-util-colors-blue-blue-400: #53B1FD; + --color-util-colors-blue-blue-500: #2E90FA; + --color-util-colors-blue-blue-600: #1570EF; + --color-util-colors-blue-blue-700: #175CD3; + + --color-util-colors-blue-light-blue-light-50: #F0F9FF; + --color-util-colors-blue-light-blue-light-100: #E0F2FE; + --color-util-colors-blue-light-blue-light-200: #B9E6FE; + --color-util-colors-blue-light-blue-light-300: #7CD4FD; + --color-util-colors-blue-light-blue-light-400: #36BFFA; + --color-util-colors-blue-light-blue-light-500: #0BA5EC; + --color-util-colors-blue-light-blue-light-600: #0086C9; + --color-util-colors-blue-light-blue-light-700: #026AA2; + + --color-util-colors-gray-blue-gray-blue-50: #F8F9FC; + --color-util-colors-gray-blue-gray-blue-100: #EAECF5; + --color-util-colors-gray-blue-gray-blue-200: #D5D9EB; + --color-util-colors-gray-blue-gray-blue-300: #B3B8DB; + --color-util-colors-gray-blue-gray-blue-400: #717BBC; + --color-util-colors-gray-blue-gray-blue-500: #4E5BA6; + --color-util-colors-gray-blue-gray-blue-600: #3E4784; + --color-util-colors-gray-blue-gray-blue-700: #363F72; + + --color-util-colors-blue-brand-blue-brand-50: #F5F7FF; + --color-util-colors-blue-brand-blue-brand-100: #D1E0FF; + --color-util-colors-blue-brand-blue-brand-200: #B2CAFF; + --color-util-colors-blue-brand-blue-brand-300: #84ABFF; + --color-util-colors-blue-brand-blue-brand-400: #5289FF; + --color-util-colors-blue-brand-blue-brand-500: #296DFF; + --color-util-colors-blue-brand-blue-brand-600: #155AEF; + --color-util-colors-blue-brand-blue-brand-700: #004AEB; + + --color-util-colors-red-red-50: #FEF3F2; + --color-util-colors-red-red-100: #FEE4E2; + --color-util-colors-red-red-200: #FECDCA; + --color-util-colors-red-red-300: #FDA29B; + --color-util-colors-red-red-400: #F97066; + --color-util-colors-red-red-500: #F04438; + --color-util-colors-red-red-600: #D92D20; + --color-util-colors-red-red-700: #B42318; + + --color-util-colors-green-green-50: #ECFDF3; + --color-util-colors-green-green-100: #DCFAE6; + --color-util-colors-green-green-200: #ABEFC6; + --color-util-colors-green-green-300: #75E0A7; + --color-util-colors-green-green-400: #47CD89; + --color-util-colors-green-green-500: #17B26A; + --color-util-colors-green-green-600: #079455; + --color-util-colors-green-green-700: #067647; + + --color-util-colors-warning-warning-50: #FFFAEB; + --color-util-colors-warning-warning-100: #FEF0C7; + --color-util-colors-warning-warning-200: #FEDF89; + --color-util-colors-warning-warning-300: #FEC84B; + --color-util-colors-warning-warning-400: #FDB022; + --color-util-colors-warning-warning-500: #F79009; + --color-util-colors-warning-warning-600: #DC6803; + --color-util-colors-warning-warning-700: #B54708; + + --color-util-colors-yellow-yellow-50: #FEFBE8; + --color-util-colors-yellow-yellow-100: #FEF7C3; + --color-util-colors-yellow-yellow-200: #FEEE95; + --color-util-colors-yellow-yellow-300: #FDE272; + --color-util-colors-yellow-yellow-400: #FAC515; + --color-util-colors-yellow-yellow-500: #EAAA08; + --color-util-colors-yellow-yellow-600: #CA8504; + --color-util-colors-yellow-yellow-700: #A15C07; + + --color-util-colors-teal-teal-50: #F0FDF9; + --color-util-colors-teal-teal-100: #CCFBEF; + --color-util-colors-teal-teal-200: #99F6E0; + --color-util-colors-teal-teal-300: #5FE9D0; + --color-util-colors-teal-teal-400: #2ED3B7; + --color-util-colors-teal-teal-500: #15B79E; + --color-util-colors-teal-teal-600: #0E9384; + --color-util-colors-teal-teal-700: #107569; + + --color-util-colors-cyan-cyan-50: #ECFDFF; + --color-util-colors-cyan-cyan-100: #CFF9FE; + --color-util-colors-cyan-cyan-200: #A5F0FC; + --color-util-colors-cyan-cyan-300: #67E3F9; + --color-util-colors-cyan-cyan-400: #22CCEE; + --color-util-colors-cyan-cyan-500: #06AED4; + --color-util-colors-cyan-cyan-600: #088AB2; + --color-util-colors-cyan-cyan-700: #0E7090; + + --color-util-colors-violet-violet-50: #F5F3FF; + --color-util-colors-violet-violet-100: #ECE9FE; + --color-util-colors-violet-violet-200: #DDD6FE; + --color-util-colors-violet-violet-300: #C3B5FD; + --color-util-colors-violet-violet-400: #A48AFB; + --color-util-colors-violet-violet-500: #875BF7; + --color-util-colors-violet-violet-600: #7839EE; + --color-util-colors-violet-violet-700: #6927DA; + + --color-util-colors-gray-gray-50: #F9FAFB; + --color-util-colors-gray-gray-100: #F2F4F7; + --color-util-colors-gray-gray-200: #E9EBF0; + --color-util-colors-gray-gray-300: #D0D5DC; + --color-util-colors-gray-gray-400: #98A2B2; + --color-util-colors-gray-gray-500: #676F83; + --color-util-colors-gray-gray-600: #495464; + --color-util-colors-gray-gray-700: #354052; + + --color-util-colors-green-light-green-light-50: #F3FEE7; + --color-util-colors-green-light-green-light-100: #E3FBCC; + --color-util-colors-green-light-green-light-200: #D0F8AB; + --color-util-colors-green-light-green-light-300: #A6EF67; + --color-util-colors-green-light-green-light-500: #66C61C; + --color-util-colors-green-light-green-light-400: #85E13A; + --color-util-colors-green-light-green-light-600: #4CA30D; + --color-util-colors-green-light-green-light-700: #3B7C0F; + + --color-util-colors-rose-rose-50: #FFF1F3; + --color-util-colors-rose-rose-100: #FFE4E8; + --color-util-colors-rose-rose-200: #FECDD6; + --color-util-colors-rose-rose-300: #FEA3B4; + --color-util-colors-rose-rose-400: #FD6F8E; + --color-util-colors-rose-rose-500: #F63D68; + --color-util-colors-rose-rose-600: #E31B54; + --color-util-colors-rose-rose-700: #C01048; + + --color-util-colors-midnight-midnight-50: #FBFBFC; + --color-util-colors-midnight-midnight-100: #F0F2F5; + --color-util-colors-midnight-midnight-200: #DFE1EA; + --color-util-colors-midnight-midnight-300: #C6CBD9; + --color-util-colors-midnight-midnight-400: #A7AEC5; + --color-util-colors-midnight-midnight-500: #828DAD; + --color-util-colors-midnight-midnight-600: #5D698D; + --color-util-colors-midnight-midnight-700: #3E465E; + + --color-third-party-LangChain: #1C3C3C; + --color-third-party-Langfuse: #000000; + + --color-chatbot-bg: linear-gradient(180deg, rgba(249, 250, 251, 0.90) 0%, rgba(242, 244, 247, 0.90) 90.48%); + --color-chat-bubble-bg: linear-gradient(180deg, #FFF 0%, rgba(255, 255, 255, 0.60) 100%); + --color-third-party-Github: #1B1F24; + --color-third-party-Github-tertiary: #1B1F24; + --color-third-party-Github-secondary: #1B1F24; + --color-third-party-model-bg-openai: #E3E5E8; + --color-third-party-model-bg-anthropic: #EEEDE7; + --color-third-party-model-bg-default: #F9FAFB; + --color-workflow-process-bg: linear-gradient(90deg, rgba(200, 206, 218, 0.20) 0%, rgba(200, 206, 218, 0.04) 100%); + --color-marketplace-divider-bg: linear-gradient(90deg, rgba(16, 24, 40, 0.08) 0%, rgba(255, 255, 255, 0) 100%); + } +} + + html[data-theme="light"] { --color-components-input-bg-normal: #C8CEDA40; --color-components-input-text-placeholder: #98A2B2; From 1573f6f6aa97796866aab0a2d3caba9a1aa55994 Mon Sep 17 00:00:00 2001 From: Joel Date: Wed, 13 Nov 2024 14:07:56 +0800 Subject: [PATCH 33/68] feat: add tag and q filter --- .../workflow/block-selector/all-tools.tsx | 14 ++++--- .../market-place-plugin/list.tsx | 39 +++++++++++-------- .../workflow/block-selector/tool-picker.tsx | 6 ++- 3 files changed, 35 insertions(+), 24 deletions(-) diff --git a/web/app/components/workflow/block-selector/all-tools.tsx b/web/app/components/workflow/block-selector/all-tools.tsx index da7640439f..566950782a 100644 --- a/web/app/components/workflow/block-selector/all-tools.tsx +++ b/web/app/components/workflow/block-selector/all-tools.tsx @@ -23,6 +23,7 @@ import { useMarketplacePlugins } from '../../plugins/marketplace/hooks' type AllToolsProps = { className?: string searchText: string + tags: string[] buildInTools: ToolWithProvider[] customTools: ToolWithProvider[] workflowTools: ToolWithProvider[] @@ -34,6 +35,7 @@ type AllToolsProps = { const AllTools = ({ className, searchText, + tags = [], onSelect, buildInTools, workflowTools, @@ -45,7 +47,7 @@ const AllTools = ({ const tabs = useToolTabs() const [activeTab, setActiveTab] = useState(ToolTypeEnum.All) const [activeView, setActiveView] = useState(ViewType.flat) - + const hasFilter = searchText || tags.length > 0 const tools = useMemo(() => { let mergedTools: ToolWithProvider[] = [] if (activeTab === ToolTypeEnum.All) @@ -57,7 +59,7 @@ const AllTools = ({ if (activeTab === ToolTypeEnum.Workflow) mergedTools = workflowTools - if (!searchText) + if (!hasFilter) return mergedTools.filter(toolWithProvider => toolWithProvider.tools.length > 0) return mergedTools.filter((toolWithProvider) => { @@ -65,7 +67,7 @@ const AllTools = ({ return tool.label[language].toLowerCase().includes(searchText.toLowerCase()) }) }) - }, [activeTab, buildInTools, customTools, workflowTools, searchText, language]) + }, [activeTab, buildInTools, customTools, workflowTools, searchText, language, hasFilter]) const { queryPluginsWithDebounced: fetchPlugins, @@ -73,14 +75,15 @@ const AllTools = ({ } = useMarketplacePlugins() useEffect(() => { - if (searchText) { + if (searchText || tags.length > 0) { fetchPlugins({ query: searchText, + tags, category: PluginType.tool, }) } // eslint-disable-next-line react-hooks/exhaustive-deps - }, [searchText]) + }, [searchText, tags]) const pluginRef = useRef(null) const wrapElemRef = useRef(null) @@ -134,6 +137,7 @@ const AllTools = ({ wrapElemRef={wrapElemRef} list={notInstalledPlugins as any} ref={pluginRef} searchText={searchText} + tags={tags} />
diff --git a/web/app/components/workflow/block-selector/market-place-plugin/list.tsx b/web/app/components/workflow/block-selector/market-place-plugin/list.tsx index 6c82bd5c0c..2e7e13be9e 100644 --- a/web/app/components/workflow/block-selector/market-place-plugin/list.tsx +++ b/web/app/components/workflow/block-selector/market-place-plugin/list.tsx @@ -14,16 +14,19 @@ type Props = { wrapElemRef: React.RefObject list: Plugin[] searchText: string + tags: string[] } const List = ({ wrapElemRef, searchText, + tags, list, }: Props, ref: any) => { const { t } = useTranslation() - const hasSearchText = !searchText - const urlWithSearchText = `${marketplaceUrlPrefix}/plugins?q=${searchText}` + const hasFilter = !searchText + const hasRes = list.length > 0 + const urlWithSearchText = `${marketplaceUrlPrefix}/marketplace?q=${searchText}&tags=${tags.join(',')}` const nextToStickyELemRef = useRef(null) const { handleScroll, scrollPosition } = useStickyScroll({ @@ -58,7 +61,7 @@ const List = ({ window.open(urlWithSearchText, '_blank') } - if (hasSearchText) { + if (hasFilter) { return ( -
- {t('plugin.fromMarketplace')} - e.stopPropagation()} + {hasRes && ( +
- {t('plugin.searchInMarketplace')} - - -
+ {t('plugin.fromMarketplace')} + e.stopPropagation()} + > + {t('plugin.searchInMarketplace')} + + +
+ )}
{list.map((item, index) => ( = ({ }) => { const { t } = useTranslation() const [searchText, setSearchText] = useState('') + const [tags, setTags] = useState([]) const { data: buildInTools } = useAllBuiltInTools() const { data: customTools } = useAllCustomTools() @@ -111,14 +112,15 @@ const ToolPicker: FC = ({ { }} + tags={tags} + onTagsChange={setTags} size='small' placeholder={t('plugin.searchTools')!} />
Date: Wed, 13 Nov 2024 14:43:37 +0800 Subject: [PATCH 34/68] fix: resolve issue with dark mode --- web/themes/dark.css | 701 ------------------------------------------ web/themes/light.css | 702 ------------------------------------------- 2 files changed, 1403 deletions(-) diff --git a/web/themes/dark.css b/web/themes/dark.css index 6e645616fb..08994039eb 100644 --- a/web/themes/dark.css +++ b/web/themes/dark.css @@ -1,705 +1,4 @@ /* Attention: Generate by code. Don't update by hand!!! */ -@media (prefers-color-scheme: dark) { - html:not([data-theme="dark"]):not([data-theme="light"]) { - color-scheme: dark; - --color-components-input-bg-normal: #FFFFFF14; - --color-components-input-text-placeholder: #C8CEDA4D; - --color-components-input-bg-hover: #FFFFFF08; - --color-components-input-bg-active: #FFFFFF0D; - --color-components-input-border-active: #747481; - --color-components-input-border-destructive: #F97066; - --color-components-input-text-filled: #F4F4F5; - --color-components-input-bg-destructive: #FFFFFF03; - --color-components-input-bg-disabled: #FFFFFF08; - --color-components-input-text-disabled: #C8CEDA4D; - --color-components-input-text-filled-disabled: #C8CEDA99; - --color-components-input-border-hover: #3A3A40; - --color-components-input-border-active-prompt-1: #36BFFA; - --color-components-input-border-active-prompt-2: #296DFF; - - --color-components-kbd-bg-gray: #FFFFFF08; - --color-components-kbd-bg-white: #FFFFFF1F; - - --color-components-tooltip-bg: #18181BF2; - - --color-components-button-primary-text: #FFFFFFF2; - --color-components-button-primary-bg: #155AEF; - --color-components-button-primary-border: #FFFFFF1F; - --color-components-button-primary-bg-hover: #296DFF; - --color-components-button-primary-border-hover: #FFFFFF33; - --color-components-button-primary-bg-disabled: #FFFFFF08; - --color-components-button-primary-border-disabled: #FFFFFF14; - --color-components-button-primary-text-disabled: #FFFFFF33; - - --color-components-button-secondary-text: #FFFFFFCC; - --color-components-button-secondary-text-disabled: #FFFFFF33; - --color-components-button-secondary-bg: #FFFFFF1F; - --color-components-button-secondary-bg-hover: #FFFFFF33; - --color-components-button-secondary-bg-disabled: #FFFFFF08; - --color-components-button-secondary-border: #FFFFFF14; - --color-components-button-secondary-border-hover: #FFFFFF1F; - --color-components-button-secondary-border-disabled: #FFFFFF0D; - - --color-components-button-tertiary-text: #D9D9DE; - --color-components-button-tertiary-text-disabled: #FFFFFF33; - --color-components-button-tertiary-bg: #FFFFFF14; - --color-components-button-tertiary-bg-hover: #FFFFFF1F; - --color-components-button-tertiary-bg-disabled: #FFFFFF08; - - --color-components-button-ghost-text: #D9D9DE; - --color-components-button-ghost-text-disabled: #FFFFFF33; - --color-components-button-ghost-bg-hover: #C8CEDA14; - - --color-components-button-destructive-primary-text: #FFFFFFF2; - --color-components-button-destructive-primary-text-disabled: #FFFFFF33; - --color-components-button-destructive-primary-bg: #D92D20; - --color-components-button-destructive-primary-bg-hover: #F04438; - --color-components-button-destructive-primary-bg-disabled: #F0443824; - --color-components-button-destructive-primary-border: #FFFFFF1F; - --color-components-button-destructive-primary-border-hover: #FFFFFF33; - --color-components-button-destructive-primary-border-disabled: #FFFFFF14; - - --color-components-button-destructive-secondary-text: #F97066; - --color-components-button-destructive-secondary-text-disabled: #F0443833; - --color-components-button-destructive-secondary-bg: #FFFFFF1F; - --color-components-button-destructive-secondary-bg-hover: #F0443824; - --color-components-button-destructive-secondary-bg-disabled: #F0443814; - --color-components-button-destructive-secondary-border: #FFFFFF14; - --color-components-button-destructive-secondary-border-hover: #FFFFFF1F; - --color-components-button-destructive-secondary-border-disabled: #F0443814; - - --color-components-button-destructive-tertiary-text: #F97066; - --color-components-button-destructive-tertiary-text-disabled: #F0443833; - --color-components-button-destructive-tertiary-bg: #F0443824; - --color-components-button-destructive-tertiary-bg-hover: #F0443840; - --color-components-button-destructive-tertiary-bg-disabled: #F0443814; - - --color-components-button-destructive-ghost-text: #F97066; - --color-components-button-destructive-ghost-text-disabled: #F0443833; - --color-components-button-destructive-ghost-bg-hover: #F0443824; - - --color-components-button-secondary-accent-text: #FFFFFFCC; - --color-components-button-secondary-accent-text-disabled: #FFFFFF33; - --color-components-button-secondary-accent-bg: #FFFFFF0D; - --color-components-button-secondary-accent-bg-hover: #FFFFFF14; - --color-components-button-secondary-accent-bg-disabled: #FFFFFF08; - --color-components-button-secondary-accent-border: #FFFFFF14; - --color-components-button-secondary-accent-border-hover: #FFFFFF1F; - --color-components-button-secondary-accent-border-disabled: #FFFFFF0D; - - --color-components-checkbox-icon: #FFFFFFF2; - --color-components-checkbox-icon-disabled: #FFFFFF33; - --color-components-checkbox-bg: #296DFF; - --color-components-checkbox-bg-hover: #5289FF; - --color-components-checkbox-bg-disabled: #FFFFFF08; - --color-components-checkbox-border: #FFFFFF66; - --color-components-checkbox-border-hover: #FFFFFF99; - --color-components-checkbox-border-disabled: #FFFFFF03; - --color-components-checkbox-bg-unchecked: #FFFFFF08; - --color-components-checkbox-bg-unchecked-hover: #FFFFFF0D; - --color-components-checkbox-bg-disabled-checked: #155AEF33; - - --color-components-radio-border-checked: #296DFF; - --color-components-radio-border-checked-hover: #5289FF; - --color-components-radio-border-checked-disabled: #155AEF33; - --color-components-radio-bg-disabled: #FFFFFF08; - --color-components-radio-border: #FFFFFF66; - --color-components-radio-border-hover: #FFFFFF99; - --color-components-radio-border-disabled: #FFFFFF03; - --color-components-radio-bg: #FFFFFF00; - --color-components-radio-bg-hover: #FFFFFF0D; - - --color-components-toggle-knob: #F4F4F5; - --color-components-toggle-knob-disabled: #FFFFFF33; - --color-components-toggle-bg: #296DFF; - --color-components-toggle-bg-hover: #5289FF; - --color-components-toggle-bg-disabled: #FFFFFF14; - --color-components-toggle-bg-unchecked: #FFFFFF33; - --color-components-toggle-bg-unchecked-hover: #FFFFFF4D; - --color-components-toggle-bg-unchecked-disabled: #FFFFFF14; - --color-components-toggle-knob-hover: #FEFEFE; - - --color-components-card-bg: #222225; - --color-components-card-border: #FFFFFF08; - --color-components-card-bg-alt: #27272B; - - --color-components-menu-item-text: #C8CEDA99; - --color-components-menu-item-text-active: #FFFFFFF2; - --color-components-menu-item-text-hover: #C8CEDACC; - --color-components-menu-item-text-active-accent: #FFFFFFF2; - - --color-components-panel-bg: #222225; - --color-components-panel-bg-blur: #2C2C30F2; - --color-components-panel-border: #C8CEDA24; - --color-components-panel-border-subtle: #C8CEDA14; - --color-components-panel-gradient-2: #222225; - --color-components-panel-gradient-1: #27272B; - --color-components-panel-bg-alt: #222225; - --color-components-panel-on-panel-item-bg: #27272B; - --color-components-panel-on-panel-item-bg-hover: #3A3A40; - --color-components-panel-on-panel-item-bg-alt: #3A3A40; - --color-components-panel-on-panel-item-bg-transparent: #2C2C30F2; - --color-components-panel-on-panel-item-bg-hover-transparent: #3A3A4000; - --color-components-panel-on-panel-item-bg-destructive-hover-transparent: #FFFBFA00; - - --color-components-panel-bg-transparent: #22222500; - - --color-components-main-nav-nav-button-text: #C8CEDA99; - --color-components-main-nav-nav-button-text-active: #F4F4F5; - --color-components-main-nav-nav-button-bg: #FFFFFF00; - --color-components-main-nav-nav-button-bg-active: #C8CEDA24; - --color-components-main-nav-nav-button-border: #FFFFFF14; - --color-components-main-nav-nav-button-bg-hover: #C8CEDA0A; - - --color-components-main-nav-nav-user-border: #FFFFFF0D; - - --color-components-slider-knob: #F4F4F5; - --color-components-slider-knob-hover: #FEFEFE; - --color-components-slider-knob-disabled: #FFFFFF33; - --color-components-slider-range: #296DFF; - --color-components-slider-track: #FFFFFF33; - --color-components-slider-knob-border-hover: #1018284D; - --color-components-slider-knob-border: #10182833; - - --color-components-segmented-control-item-active-bg: #FFFFFF14; - --color-components-segmented-control-item-active-border: #C8CEDA14; - --color-components-segmented-control-bg-normal: #18181BB2; - --color-components-segmented-control-item-active-accent-bg: #155AEF33; - --color-components-segmented-control-item-active-accent-border: #155AEF4D; - - --color-components-option-card-option-bg: #C8CEDA0A; - --color-components-option-card-option-selected-bg: #FFFFFF0D; - --color-components-option-card-option-selected-border: #5289FF; - --color-components-option-card-option-border: #C8CEDA33; - --color-components-option-card-option-bg-hover: #C8CEDA24; - --color-components-option-card-option-border-hover: #C8CEDA4D; - - --color-components-tab-active: #296DFF; - - --color-components-badge-white-to-dark: #18181BCC; - --color-components-badge-status-light-success-bg: #17B26A; - --color-components-badge-status-light-success-border-inner: #47CD89; - --color-components-badge-status-light-success-halo: #17B26A4D; - - --color-components-badge-status-light-border-outer: #222225; - --color-components-badge-status-light-high-light: #FFFFFF4D; - --color-components-badge-status-light-warning-bg: #F79009; - --color-components-badge-status-light-warning-border-inner: #FDB022; - --color-components-badge-status-light-warning-halo: #F790094D; - - --color-components-badge-status-light-error-bg: #F04438; - --color-components-badge-status-light-error-border-inner: #F97066; - --color-components-badge-status-light-error-halo: #F044384D; - - --color-components-badge-status-light-normal-bg: #0BA5EC; - --color-components-badge-status-light-normal-border-inner: #36BFFA; - --color-components-badge-status-light-normal-halo: #0BA5EC4D; - - --color-components-badge-status-light-disabled-bg: #676F83; - --color-components-badge-status-light-disabled-border-inner: #98A2B2; - --color-components-badge-status-light-disabled-halo: #C8CEDA14; - - --color-components-badge-bg-green-soft: #17B26A24; - --color-components-badge-bg-orange-soft: #F7900924; - --color-components-badge-bg-red-soft: #F0443824; - --color-components-badge-bg-blue-light-soft: #0BA5EC24; - --color-components-badge-bg-gray-soft: #C8CEDA14; - - --color-components-chart-line: #5289FF; - --color-components-chart-area-1: #155AEF33; - --color-components-chart-area-2: #155AEF0A; - --color-components-chart-current-1: #5289FF; - --color-components-chart-current-2: #155AEF4D; - --color-components-chart-bg: #18181BF2; - - --color-components-actionbar-bg: #222225; - --color-components-actionbar-border: #C8CEDA14; - --color-components-actionbar-bg-accent: #27272B; - --color-components-actionbar-border-accent: #5289FF; - - --color-components-dropzone-bg-alt: #18181BCC; - --color-components-dropzone-bg: #18181B66; - --color-components-dropzone-bg-accent: #155AEF33; - --color-components-dropzone-border: #C8CEDA24; - --color-components-dropzone-border-alt: #C8CEDA33; - --color-components-dropzone-border-accent: #84ABFF; - - --color-components-progress-brand-progress: #5289FF; - --color-components-progress-brand-border: #5289FF; - --color-components-progress-brand-bg: #155AEF0A; - - --color-components-progress-white-progress: #FFFFFF; - --color-components-progress-white-border: #FFFFFFF2; - --color-components-progress-white-bg: #FFFFFF03; - - --color-components-progress-gray-progress: #98A2B2; - --color-components-progress-gray-border: #98A2B2; - --color-components-progress-gray-bg: #C8CEDA05; - - --color-components-progress-warning-progress: #FDB022; - --color-components-progress-warning-border: #FDB022; - --color-components-progress-warning-bg: #F790090A; - - --color-components-progress-error-progress: #F97066; - --color-components-progress-error-border: #F97066; - --color-components-progress-error-bg: #F044380A; - - --color-components-chat-input-audio-bg: #155AEF33; - --color-components-chat-input-audio-wave-default: #C8CEDA24; - --color-components-chat-input-bg-mask-1: #18181B0A; - --color-components-chat-input-bg-mask-2: #18181B99; - --color-components-chat-input-border: #C8CEDA33; - --color-components-chat-input-audio-wave-active: #84ABFF; - --color-components-chat-input-audio-bg-alt: #18181BE5; - - --color-components-avatar-shape-fill-stop-0: #FFFFFFF2; - --color-components-avatar-shape-fill-stop-100: #FFFFFFCC; - - --color-components-avatar-bg-mask-stop-0: #FFFFFF33; - --color-components-avatar-bg-mask-stop-100: #FFFFFF08; - - --color-components-avatar-default-avatar-bg: #222225; - --color-components-avatar-mask-darkmode-dimmed: #0000001F; - - --color-components-label-gray: #C8CEDA24; - - --color-components-premium-badge-blue-bg-stop-0: #5289FF; - --color-components-premium-badge-blue-bg-stop-100: #296DFF; - --color-components-premium-badge-blue-stroke-stop-0: #FFFFFF33; - --color-components-premium-badge-blue-stroke-stop-100: #296DFF; - --color-components-premium-badge-blue-text-stop-0: #EFF4FF; - --color-components-premium-badge-blue-text-stop-100: #B2CAFF; - --color-components-premium-badge-blue-glow: #004AEB; - --color-components-premium-badge-blue-bg-stop-0-hover: #84ABFF; - --color-components-premium-badge-blue-bg-stop-100-hover: #004AEB; - --color-components-premium-badge-blue-glow-hover: #D1E0FF; - --color-components-premium-badge-blue-stroke-stop-0-hover: #FFFFFF80; - --color-components-premium-badge-blue-stroke-stop-100-hover: #296DFF; - - --color-components-premium-badge-highlight-stop-0: #FFFFFF1F; - --color-components-premium-badge-highlight-stop-100: #FFFFFF33; - --color-components-premium-badge-indigo-bg-stop-0: #6172F3; - --color-components-premium-badge-indigo-bg-stop-100: #3538CD; - --color-components-premium-badge-indigo-stroke-stop-0: #FFFFFF33; - --color-components-premium-badge-indigo-stroke-stop-100: #444CE7; - --color-components-premium-badge-indigo-text-stop-0: #EEF4FF; - --color-components-premium-badge-indigo-text-stop-100: #C7D7FE; - --color-components-premium-badge-indigo-glow: #3538CD; - --color-components-premium-badge-indigo-glow-hover: #E0EAFF; - --color-components-premium-badge-indigo-bg-stop-0-hover: #A4BCFD; - --color-components-premium-badge-indigo-bg-stop-100-hover: #3538CD; - --color-components-premium-badge-indigo-stroke-stop-0-hover: #FFFFFF80; - --color-components-premium-badge-indigo-stroke-stop-100-hover: #444CE7; - - --color-components-premium-badge-grey-bg-stop-0: #676F83; - --color-components-premium-badge-grey-bg-stop-100: #495464; - --color-components-premium-badge-grey-stroke-stop-0: #FFFFFF1F; - --color-components-premium-badge-grey-stroke-stop-100: #495464; - --color-components-premium-badge-grey-text-stop-0: #F9FAFB; - --color-components-premium-badge-grey-text-stop-100: #E9EBF0; - --color-components-premium-badge-grey-glow: #354052; - --color-components-premium-badge-grey-glow-hover: #F2F4F7; - --color-components-premium-badge-grey-bg-stop-0-hover: #98A2B2; - --color-components-premium-badge-grey-bg-stop-100-hover: #354052; - --color-components-premium-badge-grey-stroke-stop-0-hover: #FFFFFF80; - --color-components-premium-badge-grey-stroke-stop-100-hover: #676F83; - - --color-components-premium-badge-orange-bg-stop-0: #FF692E; - --color-components-premium-badge-orange-bg-stop-100: #E04F16; - --color-components-premium-badge-orange-stroke-stop-0: #FFFFFF33; - --color-components-premium-badge-orange-stroke-stop-100: #FF4405; - --color-components-premium-badge-orange-text-stop-0: #FEF6EE; - --color-components-premium-badge-orange-text-stop-100: #F9DBAF; - --color-components-premium-badge-orange-glow: #B93815; - --color-components-premium-badge-orange-glow-hover: #FDEAD7; - --color-components-premium-badge-orange-bg-stop-0-hover: #FF692E; - --color-components-premium-badge-orange-bg-stop-100-hover: #B93815; - --color-components-premium-badge-orange-stroke-stop-0-hover: #FFFFFF80; - --color-components-premium-badge-orange-stroke-stop-100-hover: #FF4405; - - --color-text-primary: #FBFBFC; - --color-text-secondary: #D9D9DE; - --color-text-tertiary: #C8CEDA99; - --color-text-quaternary: #C8CEDA66; - --color-text-destructive: #F97066; - --color-text-success: #17B26A; - --color-text-warning: #F79009; - --color-text-destructive-secondary: #F97066; - --color-text-success-secondary: #47CD89; - --color-text-warning-secondary: #FDB022; - --color-text-accent: #5289FF; - --color-text-primary-on-surface: #FFFFFFF2; - --color-text-placeholder: #C8CEDA4D; - --color-text-disabled: #C8CEDA4D; - --color-text-accent-secondary: #84ABFF; - --color-text-accent-light-mode-only: #D9D9DE; - --color-text-text-selected: #155AEF4D; - --color-text-secondary-on-surface: #FFFFFFE5; - --color-text-logo-text: #E9E9EC; - --color-text-empty-state-icon: #C8CEDA4D; - --color-text-inverted: #FFFFFF; - --color-text-inverted-dimm: #FFFFFFCC; - - --color-background-body: #1D1D20; - --color-background-default-subtle: #222225; - --color-background-neutral-subtle: #1D1D20; - --color-background-sidenav-bg: #27272AEB; - --color-background-default: #222225; - --color-background-soft: #18181B40; - --color-background-gradient-bg-fill-chat-bg-1: #222225; - --color-background-gradient-bg-fill-chat-bg-2: #1D1D20; - --color-background-gradient-bg-fill-chat-bubble-bg-1: #C8CEDA14; - --color-background-gradient-bg-fill-chat-bubble-bg-2: #C8CEDA05; - --color-background-gradient-bg-fill-debug-bg-1: #C8CEDA14; - --color-background-gradient-bg-fill-debug-bg-2: #18181B0A; - - --color-background-gradient-mask-gray: #18181B14; - --color-background-gradient-mask-transparent: #00000000; - --color-background-gradient-mask-input-clear-2: #393A3E00; - --color-background-gradient-mask-input-clear-1: #393A3E; - --color-background-gradient-mask-transparent-dark: #00000000; - --color-background-gradient-mask-side-panel-2: #18181BE5; - --color-background-gradient-mask-side-panel-1: #18181B0A; - - --color-background-default-burn: #1D1D20; - --color-background-overlay-fullscreen: #27272AF7; - --color-background-default-lighter: #C8CEDA0A; - --color-background-section: #18181B66; - --color-background-interaction-from-bg-1: #18181B66; - --color-background-interaction-from-bg-2: #18181B24; - --color-background-section-burn: #18181B99; - --color-background-default-dodge: #3A3A40; - --color-background-overlay: #18181BCC; - --color-background-default-dimm: #27272B; - --color-background-default-hover: #27272B; - --color-background-overlay-alt: #18181B66; - --color-background-surface-white: #FFFFFFE5; - --color-background-overlay-destructive: #F044384D; - --color-background-overlay-backdrop: #18181BF2; - - --color-shadow-shadow-1: #0000000D; - --color-shadow-shadow-3: #0000001A; - --color-shadow-shadow-4: #0000001F; - --color-shadow-shadow-5: #00000029; - --color-shadow-shadow-6: #00000033; - --color-shadow-shadow-7: #0000003D; - --color-shadow-shadow-8: #00000047; - --color-shadow-shadow-9: #0000005C; - --color-shadow-shadow-2: #00000014; - --color-shadow-shadow-10: #00000066; - - --color-workflow-block-border: #FFFFFF14; - --color-workflow-block-parma-bg: #FFFFFF0D; - --color-workflow-block-bg: #27272B; - --color-workflow-block-bg-transparent: #27272BF5; - --color-workflow-block-border-highlight: #C8CEDA33; - - --color-workflow-canvas-workflow-dot-color: #8585AD26; - --color-workflow-canvas-workflow-bg: #1D1D20; - - --color-workflow-link-line-active: #5289FF; - --color-workflow-link-line-normal: #676F83; - --color-workflow-link-line-handle: #5289FF; - --color-workflow-link-line-normal-transparent: #676F8333; - --color-workflow-link-line-failure-active: #FDB022; - --color-workflow-link-line-failure-handle: #FDB022; - --color-workflow-link-line-failure-button-bg: #F79009; - --color-workflow-link-line-failure-button-hover: #DC6803; - - --color-workflow-link-line-success-active: #47CD89; - --color-workflow-link-line-success-handle: #47CD89; - - --color-workflow-link-line-error-active: #F97066; - --color-workflow-link-line-error-handle: #F97066; - - --color-workflow-minimap-bg: #27272B; - --color-workflow-minimap-block: #C8CEDA14; - - --color-workflow-display-success-bg: #17B26A33; - --color-workflow-display-success-border-1: #17B26AE5; - --color-workflow-display-success-border-2: #17B26ACC; - --color-workflow-display-success-vignette-color: #17B26A40; - --color-workflow-display-success-bg-line-pattern: #18181BCC; - - --color-workflow-display-glass-1: #FFFFFF08; - --color-workflow-display-glass-2: #FFFFFF0D; - --color-workflow-display-vignette-dark: #00000066; - --color-workflow-display-highlight: #FFFFFF1F; - --color-workflow-display-outline: #18181BF2; - --color-workflow-display-error-bg: #F0443833; - --color-workflow-display-error-bg-line-pattern: #18181BCC; - --color-workflow-display-error-border-1: #F04438E5; - --color-workflow-display-error-border-2: #F04438CC; - --color-workflow-display-error-vignette-color: #F0443840; - - --color-workflow-display-warning-bg: #F7900933; - --color-workflow-display-warning-bg-line-pattern: #18181BCC; - --color-workflow-display-warning-border-1: #F79009E5; - --color-workflow-display-warning-border-2: #F79009CC; - --color-workflow-display-warning-vignette-color: #F7900940; - - --color-workflow-display-normal-bg: #0BA5EC33; - --color-workflow-display-normal-bg-line-pattern: #18181BCC; - --color-workflow-display-normal-border-1: #0BA5ECE5; - --color-workflow-display-normal-border-2: #0BA5ECCC; - --color-workflow-display-normal-vignette-color: #0BA5EC40; - - --color-workflow-display-disabled-bg: #C8CEDA33; - --color-workflow-display-disabled-bg-line-pattern: #18181BCC; - --color-workflow-display-disabled-border-1: #C8CEDA99; - --color-workflow-display-disabled-border-2: #C8CEDA40; - --color-workflow-display-disabled-vignette-color: #C8CEDA40; - --color-workflow-display-disabled-outline: #18181BF2; - - --color-workflow-workflow-progress-bg-1: #18181B40; - --color-workflow-workflow-progress-bg-2: #18181B0A; - - --color-divider-subtle: #C8CEDA14; - --color-divider-regular: #C8CEDA24; - --color-divider-deep: #C8CEDA33; - --color-divider-burn: #18181BF2; - --color-divider-intense: #C8CEDA66; - --color-divider-solid: #3A3A40; - --color-divider-solid-alt: #747481; - - --color-state-base-hover: #C8CEDA14; - --color-state-base-active: #C8CEDA33; - --color-state-base-hover-alt: #C8CEDA24; - --color-state-base-handle: #C8CEDA4D; - --color-state-base-handle-hover: #C8CEDA80; - - --color-state-accent-hover: #155AEF24; - --color-state-accent-active: #155AEF24; - --color-state-accent-hover-alt: #155AEF40; - --color-state-accent-solid: #5289FF; - --color-state-accent-active-alt: #155AEF33; - - --color-state-destructive-hover: #F0443824; - --color-state-destructive-hover-alt: #F0443840; - --color-state-destructive-active: #F044384D; - --color-state-destructive-solid: #F97066; - --color-state-destructive-border: #F97066; - - --color-state-success-hover: #17B26A24; - --color-state-success-hover-alt: #17B26A40; - --color-state-success-active: #17B26A4D; - --color-state-success-solid: #47CD89; - - --color-state-warning-hover: #F7900924; - --color-state-warning-hover-alt: #F7900940; - --color-state-warning-active: #F790094D; - --color-state-warning-solid: #F79009; - - --color-effects-highlight: #C8CEDA14; - --color-effects-highlight-lightmode-off: #C8CEDA14; - --color-effects-image-frame: #FFFFFF; - - --color-util-colors-orange-dark-orange-dark-50: #57130A; - --color-util-colors-orange-dark-orange-dark-100: #771A0D; - --color-util-colors-orange-dark-orange-dark-200: #97180C; - --color-util-colors-orange-dark-orange-dark-300: #BC1B06; - --color-util-colors-orange-dark-orange-dark-400: #E62E05; - --color-util-colors-orange-dark-orange-dark-500: #FF4405; - --color-util-colors-orange-dark-orange-dark-600: #FF692E; - --color-util-colors-orange-dark-orange-dark-700: #FF9C66; - - --color-util-colors-orange-orange-50: #511C10; - --color-util-colors-orange-orange-100: #772917; - --color-util-colors-orange-orange-200: #932F19; - --color-util-colors-orange-orange-300: #B93815; - --color-util-colors-orange-orange-400: #E04F16; - --color-util-colors-orange-orange-500: #EF6820; - --color-util-colors-orange-orange-600: #F38744; - --color-util-colors-orange-orange-700: #F7B27A; - --color-util-colors-orange-orange-100-transparent: #77291700; - - --color-util-colors-pink-pink-50: #4E0D30; - --color-util-colors-pink-pink-100: #851651; - --color-util-colors-pink-pink-200: #9E165F; - --color-util-colors-pink-pink-300: #C11574; - --color-util-colors-pink-pink-400: #DD2590; - --color-util-colors-pink-pink-500: #EE46BC; - --color-util-colors-pink-pink-600: #F670C7; - --color-util-colors-pink-pink-700: #FAA7E0; - - --color-util-colors-fuchsia-fuchsia-50: #47104C; - --color-util-colors-fuchsia-fuchsia-100: #6F1877; - --color-util-colors-fuchsia-fuchsia-200: #821890; - --color-util-colors-fuchsia-fuchsia-300: #9F1AB1; - --color-util-colors-fuchsia-fuchsia-400: #BA24D5; - --color-util-colors-fuchsia-fuchsia-500: #D444F1; - --color-util-colors-fuchsia-fuchsia-600: #E478FA; - --color-util-colors-fuchsia-fuchsia-700: #EEAAFD; - - --color-util-colors-purple-purple-50: #27115F; - --color-util-colors-purple-purple-100: #3E1C96; - --color-util-colors-purple-purple-200: #4A1FB8; - --color-util-colors-purple-purple-300: #5925DC; - --color-util-colors-purple-purple-400: #6938EF; - --color-util-colors-purple-purple-500: #7A5AF8; - --color-util-colors-purple-purple-600: #9B8AFB; - --color-util-colors-purple-purple-700: #BDB4FE; - - --color-util-colors-indigo-indigo-50: #1F235B; - --color-util-colors-indigo-indigo-100: #2D3282; - --color-util-colors-indigo-indigo-200: #2D31A6; - --color-util-colors-indigo-indigo-300: #3538CD; - --color-util-colors-indigo-indigo-400: #444CE7; - --color-util-colors-indigo-indigo-500: #6172F3; - --color-util-colors-indigo-indigo-600: #8098F9; - --color-util-colors-indigo-indigo-700: #A4BCFD; - - --color-util-colors-blue-blue-50: #102A56; - --color-util-colors-blue-blue-100: #194185; - --color-util-colors-blue-blue-200: #1849A9; - --color-util-colors-blue-blue-300: #175CD3; - --color-util-colors-blue-blue-400: #1570EF; - --color-util-colors-blue-blue-500: #2E90FA; - --color-util-colors-blue-blue-600: #53B1FD; - --color-util-colors-blue-blue-700: #84CAFF; - - --color-util-colors-blue-light-blue-light-50: #062C41; - --color-util-colors-blue-light-blue-light-100: #0B4A6F; - --color-util-colors-blue-light-blue-light-200: #065986; - --color-util-colors-blue-light-blue-light-300: #026AA2; - --color-util-colors-blue-light-blue-light-400: #0086C9; - --color-util-colors-blue-light-blue-light-500: #0BA5EC; - --color-util-colors-blue-light-blue-light-600: #36BFFA; - --color-util-colors-blue-light-blue-light-700: #7CD4FD; - - --color-util-colors-gray-blue-gray-blue-50: #0D0F1C; - --color-util-colors-gray-blue-gray-blue-100: #101323; - --color-util-colors-gray-blue-gray-blue-200: #293056; - --color-util-colors-gray-blue-gray-blue-300: #363F72; - --color-util-colors-gray-blue-gray-blue-400: #3E4784; - --color-util-colors-gray-blue-gray-blue-500: #4E5BA6; - --color-util-colors-gray-blue-gray-blue-600: #717BBC; - --color-util-colors-gray-blue-gray-blue-700: #B3B8DB; - - --color-util-colors-blue-brand-blue-brand-50: #002066; - --color-util-colors-blue-brand-blue-brand-100: #00329E; - --color-util-colors-blue-brand-blue-brand-200: #003DC1; - --color-util-colors-blue-brand-blue-brand-300: #004AEB; - --color-util-colors-blue-brand-blue-brand-400: #155AEF; - --color-util-colors-blue-brand-blue-brand-500: #296DFF; - --color-util-colors-blue-brand-blue-brand-600: #5289FF; - --color-util-colors-blue-brand-blue-brand-700: #84ABFF; - - --color-util-colors-red-red-50: #55160C; - --color-util-colors-red-red-100: #7A271A; - --color-util-colors-red-red-200: #912018; - --color-util-colors-red-red-300: #B42318; - --color-util-colors-red-red-400: #D92D20; - --color-util-colors-red-red-500: #F04438; - --color-util-colors-red-red-600: #F97066; - --color-util-colors-red-red-700: #FDA29B; - - --color-util-colors-green-green-50: #053321; - --color-util-colors-green-green-100: #074D31; - --color-util-colors-green-green-200: #085D3A; - --color-util-colors-green-green-300: #067647; - --color-util-colors-green-green-400: #079455; - --color-util-colors-green-green-500: #17B26A; - --color-util-colors-green-green-600: #47CD89; - --color-util-colors-green-green-700: #75E0A7; - - --color-util-colors-warning-warning-50: #4E1D09; - --color-util-colors-warning-warning-100: #7A2E0E; - --color-util-colors-warning-warning-200: #93370D; - --color-util-colors-warning-warning-300: #B54708; - --color-util-colors-warning-warning-400: #DC6803; - --color-util-colors-warning-warning-500: #F79009; - --color-util-colors-warning-warning-600: #FDB022; - --color-util-colors-warning-warning-700: #FEC84B; - - --color-util-colors-yellow-yellow-50: #542C0D; - --color-util-colors-yellow-yellow-100: #713B12; - --color-util-colors-yellow-yellow-200: #854A0E; - --color-util-colors-yellow-yellow-300: #A15C07; - --color-util-colors-yellow-yellow-400: #CA8504; - --color-util-colors-yellow-yellow-500: #EAAA08; - --color-util-colors-yellow-yellow-600: #FAC515; - --color-util-colors-yellow-yellow-700: #FDE272; - - --color-util-colors-teal-teal-50: #0A2926; - --color-util-colors-teal-teal-100: #134E48; - --color-util-colors-teal-teal-200: #125D56; - --color-util-colors-teal-teal-300: #107569; - --color-util-colors-teal-teal-400: #0E9384; - --color-util-colors-teal-teal-500: #15B79E; - --color-util-colors-teal-teal-600: #2ED3B7; - --color-util-colors-teal-teal-700: #5FE9D0; - - --color-util-colors-cyan-cyan-50: #0D2D3A; - --color-util-colors-cyan-cyan-100: #164C63; - --color-util-colors-cyan-cyan-200: #155B75; - --color-util-colors-cyan-cyan-300: #0E7090; - --color-util-colors-cyan-cyan-400: #088AB2; - --color-util-colors-cyan-cyan-500: #06AED4; - --color-util-colors-cyan-cyan-600: #22CCEE; - --color-util-colors-cyan-cyan-700: #67E3F9; - - --color-util-colors-violet-violet-50: #2E125E; - --color-util-colors-violet-violet-100: #491C96; - --color-util-colors-violet-violet-200: #5720B7; - --color-util-colors-violet-violet-300: #6927DA; - --color-util-colors-violet-violet-400: #7839EE; - --color-util-colors-violet-violet-500: #875BF7; - --color-util-colors-violet-violet-600: #A48AFB; - --color-util-colors-violet-violet-700: #C3B5FD; - - --color-util-colors-gray-gray-50: #0C111C; - --color-util-colors-gray-gray-100: #101828; - --color-util-colors-gray-gray-200: #18222F; - --color-util-colors-gray-gray-300: #354052; - --color-util-colors-gray-gray-400: #495464; - --color-util-colors-gray-gray-500: #676F83; - --color-util-colors-gray-gray-600: #98A2B2; - --color-util-colors-gray-gray-700: #D0D5DC; - - --color-util-colors-green-light-green-light-50: #15290A; - --color-util-colors-green-light-green-light-100: #2B5314; - --color-util-colors-green-light-green-light-200: #326212; - --color-util-colors-green-light-green-light-300: #3B7C0F; - --color-util-colors-green-light-green-light-500: #66C61C; - --color-util-colors-green-light-green-light-400: #4CA30D; - --color-util-colors-green-light-green-light-600: #85E13A; - --color-util-colors-green-light-green-light-700: #A6EF67; - - --color-util-colors-rose-rose-50: #510B24; - --color-util-colors-rose-rose-100: #89123E; - --color-util-colors-rose-rose-200: #A11043; - --color-util-colors-rose-rose-300: #C01048; - --color-util-colors-rose-rose-400: #E31B54; - --color-util-colors-rose-rose-500: #F63D68; - --color-util-colors-rose-rose-600: #FD6F8E; - --color-util-colors-rose-rose-700: #FEA3B4; - - --color-util-colors-midnight-midnight-50: #171C22; - --color-util-colors-midnight-midnight-100: #202431; - --color-util-colors-midnight-midnight-200: #2F3648; - --color-util-colors-midnight-midnight-300: #3E465E; - --color-util-colors-midnight-midnight-400: #5D698D; - --color-util-colors-midnight-midnight-500: #828DAD; - --color-util-colors-midnight-midnight-600: #A7AEC5; - --color-util-colors-midnight-midnight-700: #C6CBD9; - - --color-third-party-LangChain: #FFFFFF; - --color-third-party-Langfuse: #FFFFFF; - - --color-chatbot-bg: linear-gradient(180deg, rgba(34, 34, 37, 0.90) 0%, rgba(29, 29, 32, 0.90) 90.48%); - --color-chat-bubble-bg: linear-gradient(180deg, rgba(200, 206, 218, 0.08) 0%, rgba(200, 206, 218, 0.02) 100%); - --color-third-party-Github: #FFFFFF; - --color-third-party-Github-tertiary: #C8CEDA99; - --color-third-party-Github-secondary: #D9D9DE; - --color-third-party-model-bg-openai: #121212; - --color-third-party-model-bg-anthropic: #1D1917; - --color-third-party-model-bg-default: #0B0B0E; - --color-workflow-process-bg: linear-gradient(90deg, rgba(24, 24, 27, 0.25) 0%, rgba(24, 24, 27, 0.04) 100%); - --color-marketplace-divider-bg: linear-gradient(90deg, rgba(200, 206, 218, 0.14) 0%, rgba(0, 0, 0, 0) 100%); - } -} - html[data-theme="dark"] { --color-components-input-bg-normal: #FFFFFF14; --color-components-input-text-placeholder: #C8CEDA4D; diff --git a/web/themes/light.css b/web/themes/light.css index 4e0ee8ae3e..ed563ad594 100644 --- a/web/themes/light.css +++ b/web/themes/light.css @@ -1,706 +1,4 @@ /* Attention: Generate by code. Don't update by hand!!! */ -@media (prefers-color-scheme: light) { - html:not([data-theme="light"]):not([data-theme="dark"]) { - color-scheme: light; - --color-components-input-bg-normal: #C8CEDA40; - --color-components-input-text-placeholder: #98A2B2; - --color-components-input-bg-hover: #C8CEDA24; - --color-components-input-bg-active: #F9FAFB; - --color-components-input-border-active: #D0D5DC; - --color-components-input-border-destructive: #FDA29B; - --color-components-input-text-filled: #101828; - --color-components-input-bg-destructive: #FFFFFF; - --color-components-input-bg-disabled: #C8CEDA24; - --color-components-input-text-disabled: #D0D5DC; - --color-components-input-text-filled-disabled: #676F83; - --color-components-input-border-hover: #D0D5DC; - --color-components-input-border-active-prompt-1: #0BA5EC; - --color-components-input-border-active-prompt-2: #155AEF; - - --color-components-kbd-bg-gray: #1018280A; - --color-components-kbd-bg-white: #FFFFFF1F; - - --color-components-tooltip-bg: #FFFFFFF2; - - --color-components-button-primary-text: #FFFFFF; - --color-components-button-primary-bg: #155AEF; - --color-components-button-primary-border: #1018280A; - --color-components-button-primary-bg-hover: #004AEB; - --color-components-button-primary-border-hover: #10182814; - --color-components-button-primary-bg-disabled: #155AEF24; - --color-components-button-primary-border-disabled: #FFFFFF00; - --color-components-button-primary-text-disabled: #FFFFFF99; - - --color-components-button-secondary-text: #354052; - --color-components-button-secondary-text-disabled: #10182840; - --color-components-button-secondary-bg: #FFFFFF; - --color-components-button-secondary-bg-hover: #F9FAFB; - --color-components-button-secondary-bg-disabled: #F9FAFB; - --color-components-button-secondary-border: #10182824; - --color-components-button-secondary-border-hover: #10182833; - --color-components-button-secondary-border-disabled: #1018280A; - - --color-components-button-tertiary-text: #354052; - --color-components-button-tertiary-text-disabled: #10182840; - --color-components-button-tertiary-bg: #F2F4F7; - --color-components-button-tertiary-bg-hover: #E9EBF0; - --color-components-button-tertiary-bg-disabled: #F9FAFB; - - --color-components-button-ghost-text: #354052; - --color-components-button-ghost-text-disabled: #10182840; - --color-components-button-ghost-bg-hover: #C8CEDA33; - - --color-components-button-destructive-primary-text: #FFFFFF; - --color-components-button-destructive-primary-text-disabled: #FFFFFF99; - --color-components-button-destructive-primary-bg: #D92D20; - --color-components-button-destructive-primary-bg-hover: #B42318; - --color-components-button-destructive-primary-bg-disabled: #FEE4E2; - --color-components-button-destructive-primary-border: #18181B0A; - --color-components-button-destructive-primary-border-hover: #18181B14; - --color-components-button-destructive-primary-border-disabled: #FFFFFF00; - - --color-components-button-destructive-secondary-text: #D92D20; - --color-components-button-destructive-secondary-text-disabled: #F0443833; - --color-components-button-destructive-secondary-bg: #FFFFFF; - --color-components-button-destructive-secondary-bg-hover: #FEF3F2; - --color-components-button-destructive-secondary-bg-disabled: #FEF3F2; - --color-components-button-destructive-secondary-border: #18181B14; - --color-components-button-destructive-secondary-border-hover: #F0443840; - --color-components-button-destructive-secondary-border-disabled: #F044380A; - - --color-components-button-destructive-tertiary-text: #D92D20; - --color-components-button-destructive-tertiary-text-disabled: #F0443833; - --color-components-button-destructive-tertiary-bg: #FEE4E2; - --color-components-button-destructive-tertiary-bg-hover: #FECDCA; - --color-components-button-destructive-tertiary-bg-disabled: #F044380A; - - --color-components-button-destructive-ghost-text: #D92D20; - --color-components-button-destructive-ghost-text-disabled: #F0443833; - --color-components-button-destructive-ghost-bg-hover: #FEE4E2; - - --color-components-button-secondary-accent-text: #155AEF; - --color-components-button-secondary-accent-text-disabled: #B2CAFF; - --color-components-button-secondary-accent-bg: #FFFFFF; - --color-components-button-secondary-accent-bg-hover: #F2F4F7; - --color-components-button-secondary-accent-bg-disabled: #F9FAFB; - --color-components-button-secondary-accent-border: #10182824; - --color-components-button-secondary-accent-border-hover: #10182824; - --color-components-button-secondary-accent-border-disabled: #1018280A; - - --color-components-checkbox-icon: #FFFFFF; - --color-components-checkbox-icon-disabled: #FFFFFF80; - --color-components-checkbox-bg: #155AEF; - --color-components-checkbox-bg-hover: #004AEB; - --color-components-checkbox-bg-disabled: #F2F4F7; - --color-components-checkbox-border: #D0D5DC; - --color-components-checkbox-border-hover: #98A2B2; - --color-components-checkbox-border-disabled: #18181B0A; - --color-components-checkbox-bg-unchecked: #FFFFFF; - --color-components-checkbox-bg-unchecked-hover: #FFFFFF; - --color-components-checkbox-bg-disabled-checked: #B2CAFF; - - --color-components-radio-border-checked: #155AEF; - --color-components-radio-border-checked-hover: #004AEB; - --color-components-radio-border-checked-disabled: #B2CAFF; - --color-components-radio-bg-disabled: #FFFFFF00; - --color-components-radio-border: #D0D5DC; - --color-components-radio-border-hover: #98A2B2; - --color-components-radio-border-disabled: #18181B0A; - --color-components-radio-bg: #FFFFFF00; - --color-components-radio-bg-hover: #FFFFFF00; - - --color-components-toggle-knob: #FFFFFF; - --color-components-toggle-knob-disabled: #FFFFFFF2; - --color-components-toggle-bg: #155AEF; - --color-components-toggle-bg-hover: #004AEB; - --color-components-toggle-bg-disabled: #D1E0FF; - --color-components-toggle-bg-unchecked: #E9EBF0; - --color-components-toggle-bg-unchecked-hover: #D0D5DC; - --color-components-toggle-bg-unchecked-disabled: #F2F4F7; - --color-components-toggle-knob-hover: #FFFFFF; - - --color-components-card-bg: #FCFCFD; - --color-components-card-border: #FFFFFF; - --color-components-card-bg-alt: #FFFFFF; - - --color-components-menu-item-text: #495464; - --color-components-menu-item-text-active: #18222F; - --color-components-menu-item-text-hover: #354052; - --color-components-menu-item-text-active-accent: #18222F; - - --color-components-panel-bg: #FFFFFF; - --color-components-panel-bg-blur: #FFFFFFF2; - --color-components-panel-border: #10182814; - --color-components-panel-border-subtle: #10182814; - --color-components-panel-gradient-2: #F9FAFB; - --color-components-panel-gradient-1: #FFFFFF; - --color-components-panel-bg-alt: #F9FAFB; - --color-components-panel-on-panel-item-bg: #FFFFFF; - --color-components-panel-on-panel-item-bg-hover: #F9FAFB; - --color-components-panel-on-panel-item-bg-alt: #F9FAFB; - --color-components-panel-on-panel-item-bg-transparent: #FFFFFFF2; - --color-components-panel-on-panel-item-bg-hover-transparent: #F9FAFB00; - --color-components-panel-on-panel-item-bg-destructive-hover-transparent: #FEF3F200; - - --color-components-panel-bg-transparent: #FFFFFF00; - - --color-components-main-nav-nav-button-text: #495464; - --color-components-main-nav-nav-button-text-active: #155AEF; - --color-components-main-nav-nav-button-bg: #FFFFFF00; - --color-components-main-nav-nav-button-bg-active: #FCFCFD; - --color-components-main-nav-nav-button-border: #FFFFFFF2; - --color-components-main-nav-nav-button-bg-hover: #1018280A; - - --color-components-main-nav-nav-user-border: #FFFFFF; - - --color-components-slider-knob: #FFFFFF; - --color-components-slider-knob-hover: #FFFFFF; - --color-components-slider-knob-disabled: #FFFFFFF2; - --color-components-slider-range: #296DFF; - --color-components-slider-track: #E9EBF0; - --color-components-slider-knob-border-hover: #10182833; - --color-components-slider-knob-border: #10182824; - - --color-components-segmented-control-item-active-bg: #FFFFFF; - --color-components-segmented-control-item-active-border: #FFFFFF; - --color-components-segmented-control-bg-normal: #C8CEDA33; - --color-components-segmented-control-item-active-accent-bg: #FFFFFF; - --color-components-segmented-control-item-active-accent-border: #FFFFFF; - - --color-components-option-card-option-bg: #FCFCFD; - --color-components-option-card-option-selected-bg: #FFFFFF; - --color-components-option-card-option-selected-border: #296DFF; - --color-components-option-card-option-border: #E9EBF0; - --color-components-option-card-option-bg-hover: #FFFFFF; - --color-components-option-card-option-border-hover: #D0D5DC; - - --color-components-tab-active: #155AEF; - - --color-components-badge-white-to-dark: #FFFFFF; - --color-components-badge-status-light-success-bg: #47CD89; - --color-components-badge-status-light-success-border-inner: #17B26A; - --color-components-badge-status-light-success-halo: #17B26A40; - - --color-components-badge-status-light-border-outer: #FFFFFF; - --color-components-badge-status-light-high-light: #FFFFFF4D; - --color-components-badge-status-light-warning-bg: #FDB022; - --color-components-badge-status-light-warning-border-inner: #F79009; - --color-components-badge-status-light-warning-halo: #F7900940; - - --color-components-badge-status-light-error-bg: #F97066; - --color-components-badge-status-light-error-border-inner: #F04438; - --color-components-badge-status-light-error-halo: #F0443840; - - --color-components-badge-status-light-normal-bg: #36BFFA; - --color-components-badge-status-light-normal-border-inner: #0BA5EC; - --color-components-badge-status-light-normal-halo: #0BA5EC40; - - --color-components-badge-status-light-disabled-bg: #98A2B2; - --color-components-badge-status-light-disabled-border-inner: #676F83; - --color-components-badge-status-light-disabled-halo: #1018280A; - - --color-components-badge-bg-green-soft: #17B26A14; - --color-components-badge-bg-orange-soft: #F7900914; - --color-components-badge-bg-red-soft: #F0443814; - --color-components-badge-bg-blue-light-soft: #0BA5EC14; - --color-components-badge-bg-gray-soft: #1018280A; - - --color-components-chart-line: #296DFF; - --color-components-chart-area-1: #155AEF24; - --color-components-chart-area-2: #155AEF0A; - --color-components-chart-current-1: #155AEF; - --color-components-chart-current-2: #D1E0FF; - --color-components-chart-bg: #FFFFFF; - - --color-components-actionbar-bg: #FFFFFFF2; - --color-components-actionbar-border: #1018280A; - --color-components-actionbar-bg-accent: #F5F7FF; - --color-components-actionbar-border-accent: #B2CAFF; - - --color-components-dropzone-bg-alt: #F2F4F7; - --color-components-dropzone-bg: #F9FAFB; - --color-components-dropzone-bg-accent: #155AEF24; - --color-components-dropzone-border: #10182814; - --color-components-dropzone-border-alt: #10182833; - --color-components-dropzone-border-accent: #84ABFF; - - --color-components-progress-brand-progress: #296DFF; - --color-components-progress-brand-border: #296DFF; - --color-components-progress-brand-bg: #155AEF0A; - - --color-components-progress-white-progress: #FFFFFF; - --color-components-progress-white-border: #FFFFFFF2; - --color-components-progress-white-bg: #FFFFFF03; - - --color-components-progress-gray-progress: #98A2B2; - --color-components-progress-gray-border: #98A2B2; - --color-components-progress-gray-bg: #C8CEDA05; - - --color-components-progress-warning-progress: #F79009; - --color-components-progress-warning-border: #F79009; - --color-components-progress-warning-bg: #F790090A; - - --color-components-progress-error-progress: #F04438; - --color-components-progress-error-border: #F04438; - --color-components-progress-error-bg: #F044380A; - - --color-components-chat-input-audio-bg: #EFF4FF; - --color-components-chat-input-audio-wave-default: #155AEF33; - --color-components-chat-input-bg-mask-1: #FFFFFF03; - --color-components-chat-input-bg-mask-2: #F2F4F7; - --color-components-chat-input-border: #FFFFFF; - --color-components-chat-input-audio-wave-active: #296DFF; - --color-components-chat-input-audio-bg-alt: #FCFCFD; - - --color-components-avatar-shape-fill-stop-0: #FFFFFF; - --color-components-avatar-shape-fill-stop-100: #FFFFFFE5; - - --color-components-avatar-bg-mask-stop-0: #FFFFFF1F; - --color-components-avatar-bg-mask-stop-100: #FFFFFF14; - - --color-components-avatar-default-avatar-bg: #D0D5DC; - --color-components-avatar-mask-darkmode-dimmed: #FFFFFF00; - - --color-components-label-gray: #F2F4F7; - - --color-components-premium-badge-blue-bg-stop-0: #5289FF; - --color-components-premium-badge-blue-bg-stop-100: #155AEF; - --color-components-premium-badge-blue-stroke-stop-0: #FFFFFFF2; - --color-components-premium-badge-blue-stroke-stop-100: #155AEF; - --color-components-premium-badge-blue-text-stop-0: #F5F7FF; - --color-components-premium-badge-blue-text-stop-100: #D1E0FF; - --color-components-premium-badge-blue-glow: #00329E; - --color-components-premium-badge-blue-bg-stop-0-hover: #296DFF; - --color-components-premium-badge-blue-bg-stop-100-hover: #004AEB; - --color-components-premium-badge-blue-glow-hover: #84ABFF; - --color-components-premium-badge-blue-stroke-stop-0-hover: #FFFFFFF2; - --color-components-premium-badge-blue-stroke-stop-100-hover: #00329E; - - --color-components-premium-badge-highlight-stop-0: #FFFFFF1F; - --color-components-premium-badge-highlight-stop-100: #FFFFFF4D; - --color-components-premium-badge-indigo-bg-stop-0: #8098F9; - --color-components-premium-badge-indigo-bg-stop-100: #444CE7; - --color-components-premium-badge-indigo-stroke-stop-0: #FFFFFFF2; - --color-components-premium-badge-indigo-stroke-stop-100: #6172F3; - --color-components-premium-badge-indigo-text-stop-0: #F5F8FF; - --color-components-premium-badge-indigo-text-stop-100: #E0EAFF; - --color-components-premium-badge-indigo-glow: #2D3282; - --color-components-premium-badge-indigo-glow-hover: #A4BCFD; - --color-components-premium-badge-indigo-bg-stop-0-hover: #6172F3; - --color-components-premium-badge-indigo-bg-stop-100-hover: #2D31A6; - --color-components-premium-badge-indigo-stroke-stop-0-hover: #FFFFFFF2; - --color-components-premium-badge-indigo-stroke-stop-100-hover: #2D31A6; - - --color-components-premium-badge-grey-bg-stop-0: #98A2B2; - --color-components-premium-badge-grey-bg-stop-100: #676F83; - --color-components-premium-badge-grey-stroke-stop-0: #FFFFFFF2; - --color-components-premium-badge-grey-stroke-stop-100: #676F83; - --color-components-premium-badge-grey-text-stop-0: #FCFCFD; - --color-components-premium-badge-grey-text-stop-100: #F2F4F7; - --color-components-premium-badge-grey-glow: #101828; - --color-components-premium-badge-grey-glow-hover: #D0D5DC; - --color-components-premium-badge-grey-bg-stop-0-hover: #676F83; - --color-components-premium-badge-grey-bg-stop-100-hover: #354052; - --color-components-premium-badge-grey-stroke-stop-0-hover: #FFFFFFF2; - --color-components-premium-badge-grey-stroke-stop-100-hover: #354052; - - --color-components-premium-badge-orange-bg-stop-0: #FF692E; - --color-components-premium-badge-orange-bg-stop-100: #E04F16; - --color-components-premium-badge-orange-stroke-stop-0: #FFFFFFF2; - --color-components-premium-badge-orange-stroke-stop-100: #E62E05; - --color-components-premium-badge-orange-text-stop-0: #FEFAF5; - --color-components-premium-badge-orange-text-stop-100: #FDEAD7; - --color-components-premium-badge-orange-glow: #772917; - --color-components-premium-badge-orange-glow-hover: #F7B27A; - --color-components-premium-badge-orange-bg-stop-0-hover: #FF4405; - --color-components-premium-badge-orange-bg-stop-100-hover: #B93815; - --color-components-premium-badge-orange-stroke-stop-0-hover: #FFFFFFF2; - --color-components-premium-badge-orange-stroke-stop-100-hover: #BC1B06; - - --color-text-primary: #101828; - --color-text-secondary: #354052; - --color-text-tertiary: #676F83; - --color-text-quaternary: #1018284D; - --color-text-destructive: #D92D20; - --color-text-success: #079455; - --color-text-warning: #DC6803; - --color-text-destructive-secondary: #F04438; - --color-text-success-secondary: #17B26A; - --color-text-warning-secondary: #F79009; - --color-text-accent: #155AEF; - --color-text-primary-on-surface: #FFFFFF; - --color-text-placeholder: #98A2B2; - --color-text-disabled: #D0D5DC; - --color-text-accent-secondary: #296DFF; - --color-text-accent-light-mode-only: #155AEF; - --color-text-text-selected: #155AEF24; - --color-text-secondary-on-surface: #FFFFFFE5; - --color-text-logo-text: #18222F; - --color-text-empty-state-icon: #D0D5DC; - --color-text-inverted: #000000; - --color-text-inverted-dimm: #000000F2; - - --color-background-body: #F2F4F7; - --color-background-default-subtle: #FCFCFD; - --color-background-neutral-subtle: #F9FAFB; - --color-background-sidenav-bg: #FFFFFFCC; - --color-background-default: #FFFFFF; - --color-background-soft: #F9FAFB; - --color-background-gradient-bg-fill-chat-bg-1: #F9FAFB; - --color-background-gradient-bg-fill-chat-bg-2: #F2F4F7; - --color-background-gradient-bg-fill-chat-bubble-bg-1: #FFFFFF; - --color-background-gradient-bg-fill-chat-bubble-bg-2: #FFFFFF99; - --color-background-gradient-bg-fill-debug-bg-1: #FFFFFF00; - --color-background-gradient-bg-fill-debug-bg-2: #C8CEDA24; - - --color-background-gradient-mask-gray: #C8CEDA33; - --color-background-gradient-mask-transparent: #FFFFFF00; - --color-background-gradient-mask-input-clear-2: #E9EBF000; - --color-background-gradient-mask-input-clear-1: #E9EBF0; - --color-background-gradient-mask-transparent-dark: #00000000; - --color-background-gradient-mask-side-panel-2: #1018284D; - --color-background-gradient-mask-side-panel-1: #10182805; - - --color-background-default-burn: #E9EBF0; - --color-background-overlay-fullscreen: #F9FAFBF2; - --color-background-default-lighter: #FFFFFF80; - --color-background-section: #F9FAFB; - --color-background-interaction-from-bg-1: #C8CEDA33; - --color-background-interaction-from-bg-2: #C8CEDA24; - --color-background-section-burn: #F2F4F7; - --color-background-default-dodge: #FFFFFF; - --color-background-overlay: #10182899; - --color-background-default-dimm: #E9EBF0; - --color-background-default-hover: #F9FAFB; - --color-background-overlay-alt: #10182866; - --color-background-surface-white: #FFFFFFF2; - --color-background-overlay-destructive: #F044384D; - --color-background-overlay-backdrop: #F2F4F7F2; - - --color-shadow-shadow-1: #09090B08; - --color-shadow-shadow-3: #09090B0D; - --color-shadow-shadow-4: #09090B0F; - --color-shadow-shadow-5: #09090B14; - --color-shadow-shadow-6: #09090B1A; - --color-shadow-shadow-7: #09090B1F; - --color-shadow-shadow-8: #09090B24; - --color-shadow-shadow-9: #09090B2E; - --color-shadow-shadow-2: #09090B0A; - --color-shadow-shadow-10: #09090B0D; - - --color-workflow-block-border: #FFFFFF; - --color-workflow-block-parma-bg: #F2F4F7; - --color-workflow-block-bg: #FCFCFD; - --color-workflow-block-bg-transparent: #FCFCFDE5; - --color-workflow-block-border-highlight: #155AEF24; - - --color-workflow-canvas-workflow-dot-color: #8585AD26; - --color-workflow-canvas-workflow-bg: #F2F4F7; - - --color-workflow-link-line-active: #296DFF; - --color-workflow-link-line-normal: #D0D5DC; - --color-workflow-link-line-handle: #296DFF; - --color-workflow-link-line-normal-transparent: #D0D5DC33; - --color-workflow-link-line-failure-active: #F79009; - --color-workflow-link-line-failure-handle: #F79009; - --color-workflow-link-line-failure-button-bg: #DC6803; - --color-workflow-link-line-failure-button-hover: #B54708; - - --color-workflow-link-line-success-active: #17B26A; - --color-workflow-link-line-success-handle: #17B26A; - - --color-workflow-link-line-error-active: #F04438; - --color-workflow-link-line-error-handle: #F04438; - - --color-workflow-minimap-bg: #E9EBF0; - --color-workflow-minimap-block: #C8CEDA4D; - - --color-workflow-display-success-bg: #ECFDF3; - --color-workflow-display-success-border-1: #17B26ACC; - --color-workflow-display-success-border-2: #17B26A80; - --color-workflow-display-success-vignette-color: #17B26A33; - --color-workflow-display-success-bg-line-pattern: #17B26A4D; - - --color-workflow-display-glass-1: #FFFFFF1F; - --color-workflow-display-glass-2: #FFFFFF80; - --color-workflow-display-vignette-dark: #0000001F; - --color-workflow-display-highlight: #FFFFFF80; - --color-workflow-display-outline: #0000000D; - --color-workflow-display-error-bg: #FEF3F2; - --color-workflow-display-error-bg-line-pattern: #F044384D; - --color-workflow-display-error-border-1: #F04438CC; - --color-workflow-display-error-border-2: #F0443880; - --color-workflow-display-error-vignette-color: #F0443833; - - --color-workflow-display-warning-bg: #FFFAEB; - --color-workflow-display-warning-bg-line-pattern: #F790094D; - --color-workflow-display-warning-border-1: #F79009CC; - --color-workflow-display-warning-border-2: #F7900980; - --color-workflow-display-warning-vignette-color: #F7900933; - - --color-workflow-display-normal-bg: #F0F9FF; - --color-workflow-display-normal-bg-line-pattern: #0BA5EC4D; - --color-workflow-display-normal-border-1: #0BA5ECCC; - --color-workflow-display-normal-border-2: #0BA5EC80; - --color-workflow-display-normal-vignette-color: #0BA5EC33; - - --color-workflow-display-disabled-bg: #F9FAFB; - --color-workflow-display-disabled-bg-line-pattern: #C8CEDA4D; - --color-workflow-display-disabled-border-1: #C8CEDA99; - --color-workflow-display-disabled-border-2: #C8CEDA66; - --color-workflow-display-disabled-vignette-color: #C8CEDA66; - --color-workflow-display-disabled-outline: #00000000; - - --color-workflow-workflow-progress-bg-1: #C8CEDA33; - --color-workflow-workflow-progress-bg-2: #C8CEDA0A; - - --color-divider-subtle: #1018280A; - --color-divider-regular: #10182814; - --color-divider-deep: #10182824; - --color-divider-burn: #1018280A; - --color-divider-intense: #1018284D; - --color-divider-solid: #D0D5DC; - --color-divider-solid-alt: #98A2B2; - - --color-state-base-hover: #C8CEDA33; - --color-state-base-active: #C8CEDA66; - --color-state-base-hover-alt: #C8CEDA66; - --color-state-base-handle: #10182833; - --color-state-base-handle-hover: #1018284D; - - --color-state-accent-hover: #EFF4FF; - --color-state-accent-active: #155AEF14; - --color-state-accent-hover-alt: #D1E0FF; - --color-state-accent-solid: #296DFF; - --color-state-accent-active-alt: #155AEF24; - - --color-state-destructive-hover: #FEF3F2; - --color-state-destructive-hover-alt: #FEE4E2; - --color-state-destructive-active: #FECDCA; - --color-state-destructive-solid: #F04438; - --color-state-destructive-border: #FDA29B; - - --color-state-success-hover: #ECFDF3; - --color-state-success-hover-alt: #DCFAE6; - --color-state-success-active: #ABEFC6; - --color-state-success-solid: #17B26A; - - --color-state-warning-hover: #FFFAEB; - --color-state-warning-hover-alt: #FEF0C7; - --color-state-warning-active: #FEDF89; - --color-state-warning-solid: #F79009; - - --color-effects-highlight: #FFFFFF; - --color-effects-highlight-lightmode-off: #FFFFFF00; - --color-effects-image-frame: #FFFFFF; - - --color-util-colors-orange-dark-orange-dark-50: #FFF4ED; - --color-util-colors-orange-dark-orange-dark-100: #FFE6D5; - --color-util-colors-orange-dark-orange-dark-200: #FFD6AE; - --color-util-colors-orange-dark-orange-dark-300: #FF9C66; - --color-util-colors-orange-dark-orange-dark-400: #FF692E; - --color-util-colors-orange-dark-orange-dark-500: #FF4405; - --color-util-colors-orange-dark-orange-dark-600: #E62E05; - --color-util-colors-orange-dark-orange-dark-700: #BC1B06; - - --color-util-colors-orange-orange-50: #FEF6EE; - --color-util-colors-orange-orange-100: #FDEAD7; - --color-util-colors-orange-orange-200: #F9DBAF; - --color-util-colors-orange-orange-300: #F7B27A; - --color-util-colors-orange-orange-400: #F38744; - --color-util-colors-orange-orange-500: #EF6820; - --color-util-colors-orange-orange-600: #E04F16; - --color-util-colors-orange-orange-700: #B93815; - --color-util-colors-orange-orange-100-transparent: #FDEAD700; - - --color-util-colors-pink-pink-50: #FDF2FA; - --color-util-colors-pink-pink-100: #FCE7F6; - --color-util-colors-pink-pink-200: #FCCEEE; - --color-util-colors-pink-pink-300: #FAA7E0; - --color-util-colors-pink-pink-400: #F670C7; - --color-util-colors-pink-pink-500: #EE46BC; - --color-util-colors-pink-pink-600: #DD2590; - --color-util-colors-pink-pink-700: #C11574; - - --color-util-colors-fuchsia-fuchsia-50: #FDF4FF; - --color-util-colors-fuchsia-fuchsia-100: #FBE8FF; - --color-util-colors-fuchsia-fuchsia-200: #F6D0FE; - --color-util-colors-fuchsia-fuchsia-300: #EEAAFD; - --color-util-colors-fuchsia-fuchsia-400: #E478FA; - --color-util-colors-fuchsia-fuchsia-500: #D444F1; - --color-util-colors-fuchsia-fuchsia-600: #BA24D5; - --color-util-colors-fuchsia-fuchsia-700: #9F1AB1; - - --color-util-colors-purple-purple-50: #F4F3FF; - --color-util-colors-purple-purple-100: #EBE9FE; - --color-util-colors-purple-purple-200: #D9D6FE; - --color-util-colors-purple-purple-300: #BDB4FE; - --color-util-colors-purple-purple-400: #9B8AFB; - --color-util-colors-purple-purple-500: #7A5AF8; - --color-util-colors-purple-purple-600: #6938EF; - --color-util-colors-purple-purple-700: #5925DC; - - --color-util-colors-indigo-indigo-50: #EEF4FF; - --color-util-colors-indigo-indigo-100: #E0EAFF; - --color-util-colors-indigo-indigo-200: #C7D7FE; - --color-util-colors-indigo-indigo-300: #A4BCFD; - --color-util-colors-indigo-indigo-400: #8098F9; - --color-util-colors-indigo-indigo-500: #6172F3; - --color-util-colors-indigo-indigo-600: #444CE7; - --color-util-colors-indigo-indigo-700: #3538CD; - - --color-util-colors-blue-blue-50: #EFF8FF; - --color-util-colors-blue-blue-100: #D1E9FF; - --color-util-colors-blue-blue-200: #B2DDFF; - --color-util-colors-blue-blue-300: #84CAFF; - --color-util-colors-blue-blue-400: #53B1FD; - --color-util-colors-blue-blue-500: #2E90FA; - --color-util-colors-blue-blue-600: #1570EF; - --color-util-colors-blue-blue-700: #175CD3; - - --color-util-colors-blue-light-blue-light-50: #F0F9FF; - --color-util-colors-blue-light-blue-light-100: #E0F2FE; - --color-util-colors-blue-light-blue-light-200: #B9E6FE; - --color-util-colors-blue-light-blue-light-300: #7CD4FD; - --color-util-colors-blue-light-blue-light-400: #36BFFA; - --color-util-colors-blue-light-blue-light-500: #0BA5EC; - --color-util-colors-blue-light-blue-light-600: #0086C9; - --color-util-colors-blue-light-blue-light-700: #026AA2; - - --color-util-colors-gray-blue-gray-blue-50: #F8F9FC; - --color-util-colors-gray-blue-gray-blue-100: #EAECF5; - --color-util-colors-gray-blue-gray-blue-200: #D5D9EB; - --color-util-colors-gray-blue-gray-blue-300: #B3B8DB; - --color-util-colors-gray-blue-gray-blue-400: #717BBC; - --color-util-colors-gray-blue-gray-blue-500: #4E5BA6; - --color-util-colors-gray-blue-gray-blue-600: #3E4784; - --color-util-colors-gray-blue-gray-blue-700: #363F72; - - --color-util-colors-blue-brand-blue-brand-50: #F5F7FF; - --color-util-colors-blue-brand-blue-brand-100: #D1E0FF; - --color-util-colors-blue-brand-blue-brand-200: #B2CAFF; - --color-util-colors-blue-brand-blue-brand-300: #84ABFF; - --color-util-colors-blue-brand-blue-brand-400: #5289FF; - --color-util-colors-blue-brand-blue-brand-500: #296DFF; - --color-util-colors-blue-brand-blue-brand-600: #155AEF; - --color-util-colors-blue-brand-blue-brand-700: #004AEB; - - --color-util-colors-red-red-50: #FEF3F2; - --color-util-colors-red-red-100: #FEE4E2; - --color-util-colors-red-red-200: #FECDCA; - --color-util-colors-red-red-300: #FDA29B; - --color-util-colors-red-red-400: #F97066; - --color-util-colors-red-red-500: #F04438; - --color-util-colors-red-red-600: #D92D20; - --color-util-colors-red-red-700: #B42318; - - --color-util-colors-green-green-50: #ECFDF3; - --color-util-colors-green-green-100: #DCFAE6; - --color-util-colors-green-green-200: #ABEFC6; - --color-util-colors-green-green-300: #75E0A7; - --color-util-colors-green-green-400: #47CD89; - --color-util-colors-green-green-500: #17B26A; - --color-util-colors-green-green-600: #079455; - --color-util-colors-green-green-700: #067647; - - --color-util-colors-warning-warning-50: #FFFAEB; - --color-util-colors-warning-warning-100: #FEF0C7; - --color-util-colors-warning-warning-200: #FEDF89; - --color-util-colors-warning-warning-300: #FEC84B; - --color-util-colors-warning-warning-400: #FDB022; - --color-util-colors-warning-warning-500: #F79009; - --color-util-colors-warning-warning-600: #DC6803; - --color-util-colors-warning-warning-700: #B54708; - - --color-util-colors-yellow-yellow-50: #FEFBE8; - --color-util-colors-yellow-yellow-100: #FEF7C3; - --color-util-colors-yellow-yellow-200: #FEEE95; - --color-util-colors-yellow-yellow-300: #FDE272; - --color-util-colors-yellow-yellow-400: #FAC515; - --color-util-colors-yellow-yellow-500: #EAAA08; - --color-util-colors-yellow-yellow-600: #CA8504; - --color-util-colors-yellow-yellow-700: #A15C07; - - --color-util-colors-teal-teal-50: #F0FDF9; - --color-util-colors-teal-teal-100: #CCFBEF; - --color-util-colors-teal-teal-200: #99F6E0; - --color-util-colors-teal-teal-300: #5FE9D0; - --color-util-colors-teal-teal-400: #2ED3B7; - --color-util-colors-teal-teal-500: #15B79E; - --color-util-colors-teal-teal-600: #0E9384; - --color-util-colors-teal-teal-700: #107569; - - --color-util-colors-cyan-cyan-50: #ECFDFF; - --color-util-colors-cyan-cyan-100: #CFF9FE; - --color-util-colors-cyan-cyan-200: #A5F0FC; - --color-util-colors-cyan-cyan-300: #67E3F9; - --color-util-colors-cyan-cyan-400: #22CCEE; - --color-util-colors-cyan-cyan-500: #06AED4; - --color-util-colors-cyan-cyan-600: #088AB2; - --color-util-colors-cyan-cyan-700: #0E7090; - - --color-util-colors-violet-violet-50: #F5F3FF; - --color-util-colors-violet-violet-100: #ECE9FE; - --color-util-colors-violet-violet-200: #DDD6FE; - --color-util-colors-violet-violet-300: #C3B5FD; - --color-util-colors-violet-violet-400: #A48AFB; - --color-util-colors-violet-violet-500: #875BF7; - --color-util-colors-violet-violet-600: #7839EE; - --color-util-colors-violet-violet-700: #6927DA; - - --color-util-colors-gray-gray-50: #F9FAFB; - --color-util-colors-gray-gray-100: #F2F4F7; - --color-util-colors-gray-gray-200: #E9EBF0; - --color-util-colors-gray-gray-300: #D0D5DC; - --color-util-colors-gray-gray-400: #98A2B2; - --color-util-colors-gray-gray-500: #676F83; - --color-util-colors-gray-gray-600: #495464; - --color-util-colors-gray-gray-700: #354052; - - --color-util-colors-green-light-green-light-50: #F3FEE7; - --color-util-colors-green-light-green-light-100: #E3FBCC; - --color-util-colors-green-light-green-light-200: #D0F8AB; - --color-util-colors-green-light-green-light-300: #A6EF67; - --color-util-colors-green-light-green-light-500: #66C61C; - --color-util-colors-green-light-green-light-400: #85E13A; - --color-util-colors-green-light-green-light-600: #4CA30D; - --color-util-colors-green-light-green-light-700: #3B7C0F; - - --color-util-colors-rose-rose-50: #FFF1F3; - --color-util-colors-rose-rose-100: #FFE4E8; - --color-util-colors-rose-rose-200: #FECDD6; - --color-util-colors-rose-rose-300: #FEA3B4; - --color-util-colors-rose-rose-400: #FD6F8E; - --color-util-colors-rose-rose-500: #F63D68; - --color-util-colors-rose-rose-600: #E31B54; - --color-util-colors-rose-rose-700: #C01048; - - --color-util-colors-midnight-midnight-50: #FBFBFC; - --color-util-colors-midnight-midnight-100: #F0F2F5; - --color-util-colors-midnight-midnight-200: #DFE1EA; - --color-util-colors-midnight-midnight-300: #C6CBD9; - --color-util-colors-midnight-midnight-400: #A7AEC5; - --color-util-colors-midnight-midnight-500: #828DAD; - --color-util-colors-midnight-midnight-600: #5D698D; - --color-util-colors-midnight-midnight-700: #3E465E; - - --color-third-party-LangChain: #1C3C3C; - --color-third-party-Langfuse: #000000; - - --color-chatbot-bg: linear-gradient(180deg, rgba(249, 250, 251, 0.90) 0%, rgba(242, 244, 247, 0.90) 90.48%); - --color-chat-bubble-bg: linear-gradient(180deg, #FFF 0%, rgba(255, 255, 255, 0.60) 100%); - --color-third-party-Github: #1B1F24; - --color-third-party-Github-tertiary: #1B1F24; - --color-third-party-Github-secondary: #1B1F24; - --color-third-party-model-bg-openai: #E3E5E8; - --color-third-party-model-bg-anthropic: #EEEDE7; - --color-third-party-model-bg-default: #F9FAFB; - --color-workflow-process-bg: linear-gradient(90deg, rgba(200, 206, 218, 0.20) 0%, rgba(200, 206, 218, 0.04) 100%); - --color-marketplace-divider-bg: linear-gradient(90deg, rgba(16, 24, 40, 0.08) 0%, rgba(255, 255, 255, 0) 100%); - } -} - - html[data-theme="light"] { --color-components-input-bg-normal: #C8CEDA40; --color-components-input-text-placeholder: #98A2B2; From 19dc983d3092acb06922a0588b3020048830365d Mon Sep 17 00:00:00 2001 From: Joel Date: Wed, 13 Nov 2024 14:54:27 +0800 Subject: [PATCH 35/68] feat: support toggle set tool when the texts changes --- .../workflow/block-selector/all-tools.tsx | 1 + .../tool/tool-list-flat-view/list.tsx | 16 +++++++++++++++- .../tool/tool-list-tree-view/item.tsx | 16 +++++++++++++++- .../tool/tool-list-tree-view/list.tsx | 3 +++ .../workflow/block-selector/tool/tool.tsx | 16 ++++++++-------- .../components/workflow/block-selector/tools.tsx | 4 ++++ 6 files changed, 46 insertions(+), 10 deletions(-) diff --git a/web/app/components/workflow/block-selector/all-tools.tsx b/web/app/components/workflow/block-selector/all-tools.tsx index 566950782a..b93d68c019 100644 --- a/web/app/components/workflow/block-selector/all-tools.tsx +++ b/web/app/components/workflow/block-selector/all-tools.tsx @@ -131,6 +131,7 @@ const AllTools = ({ tools={tools} onSelect={onSelect} viewType={activeView} + hasSearchText={!!searchText} /> {/* Plugins from marketplace */} void } const ToolViewFlatView: FC = ({ payload, isShowLetterIndex, + hasSearchText, onSelect, }) => { + const [fold, setFold] = React.useState(true) + useEffect(() => { + if (hasSearchText && fold) { + setFold(false) + return + } + if (!hasSearchText && !fold) + setFold(true) + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [hasSearchText]) return (
{payload.map(tool => ( @@ -26,6 +38,8 @@ const ToolViewFlatView: FC = ({ payload={tool} viewType={ViewType.flat} isShowLetterIndex={isShowLetterIndex} + isFold={fold} + onFoldChange={setFold} onSelect={onSelect} /> ))} diff --git a/web/app/components/workflow/block-selector/tool/tool-list-tree-view/item.tsx b/web/app/components/workflow/block-selector/tool/tool-list-tree-view/item.tsx index 156bede917..f74602c901 100644 --- a/web/app/components/workflow/block-selector/tool/tool-list-tree-view/item.tsx +++ b/web/app/components/workflow/block-selector/tool/tool-list-tree-view/item.tsx @@ -1,6 +1,6 @@ 'use client' import type { FC } from 'react' -import React from 'react' +import React, { useEffect } from 'react' import type { ToolWithProvider } from '../../../types' import Tool from '../tool' import type { BlockEnum } from '../../../types' @@ -10,14 +10,26 @@ import type { ToolDefaultValue } from '../../types' type Props = { groupName: string toolList: ToolWithProvider[] + hasSearchText: boolean onSelect: (type: BlockEnum, tool?: ToolDefaultValue) => void } const Item: FC = ({ groupName, toolList, + hasSearchText, onSelect, }) => { + const [fold, setFold] = React.useState(true) + useEffect(() => { + if (hasSearchText && fold) { + setFold(false) + return + } + if (!hasSearchText && !fold) + setFold(true) + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [hasSearchText]) return (
@@ -30,6 +42,8 @@ const Item: FC = ({ payload={tool} viewType={ViewType.tree} isShowLetterIndex={false} + isFold={fold} + onFoldChange={setFold} onSelect={onSelect} /> ))} diff --git a/web/app/components/workflow/block-selector/tool/tool-list-tree-view/list.tsx b/web/app/components/workflow/block-selector/tool/tool-list-tree-view/list.tsx index 1b0dbddca6..8bf5095833 100644 --- a/web/app/components/workflow/block-selector/tool/tool-list-tree-view/list.tsx +++ b/web/app/components/workflow/block-selector/tool/tool-list-tree-view/list.tsx @@ -10,11 +10,13 @@ import { CUSTOM_GROUP_NAME, WORKFLOW_GROUP_NAME } from '../../index-bar' type Props = { payload: Record + hasSearchText: boolean onSelect: (type: BlockEnum, tool?: ToolDefaultValue) => void } const ToolListTreeView: FC = ({ payload, + hasSearchText, onSelect, }) => { const { t } = useTranslation() @@ -37,6 +39,7 @@ const ToolListTreeView: FC = ({ key={groupName} groupName={getI18nGroupName(groupName)} toolList={payload[groupName]} + hasSearchText={hasSearchText} onSelect={onSelect} /> ))} diff --git a/web/app/components/workflow/block-selector/tool/tool.tsx b/web/app/components/workflow/block-selector/tool/tool.tsx index 3ce6bdcf7d..658bccd630 100644 --- a/web/app/components/workflow/block-selector/tool/tool.tsx +++ b/web/app/components/workflow/block-selector/tool/tool.tsx @@ -11,8 +11,6 @@ import type { ToolDefaultValue } from '../types' import { ViewType } from '../view-type-select' import ActonItem from './action-item' import BlockIcon from '../../block-icon' - -import { useBoolean } from 'ahooks' import { useTranslation } from 'react-i18next' type Props = { @@ -20,6 +18,8 @@ type Props = { payload: ToolWithProvider viewType: ViewType isShowLetterIndex: boolean + isFold: boolean + onFoldChange: (fold: boolean) => void onSelect: (type: BlockEnum, tool?: ToolDefaultValue) => void } @@ -28,6 +28,8 @@ const Tool: FC = ({ payload, viewType, isShowLetterIndex, + isFold, + onFoldChange, onSelect, }) => { const { t } = useTranslation() @@ -35,10 +37,8 @@ const Tool: FC = ({ const isFlatView = viewType === ViewType.flat const actions = payload.tools const hasAction = true // Now always support actions - const [isFold, { - toggle: toggleFold, - }] = useBoolean(false) - const FoldIcon = isFold ? RiArrowDownSLine : RiArrowRightSLine + + const FoldIcon = isFold ? RiArrowRightSLine : RiArrowDownSLine const groupName = useMemo(() => { if (payload.type === CollectionType.builtIn) @@ -63,7 +63,7 @@ const Tool: FC = ({ className='flex items-center justify-between pl-3 pr-1 w-full rounded-lg hover:bg-gray-50 cursor-pointer select-none' onClick={() => { if (hasAction) - toggleFold() + onFoldChange(!isFold) // Now always support actions // if (payload.parameters) { @@ -101,7 +101,7 @@ const Tool: FC = ({
- {hasAction && isFold && ( + {hasAction && !isFold && ( actions.map(action => ( void tools: ToolWithProvider[] viewType: ViewType + hasSearchText: boolean } const Blocks = ({ showWorkflowEmpty, onSelect, tools, viewType, + hasSearchText, }: ToolsProps) => { const { t } = useTranslation() const language = useGetLanguage() @@ -89,11 +91,13 @@ const Blocks = ({ ) : ( ) From 89b470d0d5700888b94a462e3affdc29f389c273 Mon Sep 17 00:00:00 2001 From: Joel Date: Wed, 13 Nov 2024 15:04:23 +0800 Subject: [PATCH 36/68] fix: toggle tool --- .../tool/tool-list-flat-view/list.tsx | 15 ++------------ .../tool/tool-list-tree-view/item.tsx | 15 ++------------ .../workflow/block-selector/tool/tool.tsx | 20 +++++++++++++------ 3 files changed, 18 insertions(+), 32 deletions(-) diff --git a/web/app/components/workflow/block-selector/tool/tool-list-flat-view/list.tsx b/web/app/components/workflow/block-selector/tool/tool-list-flat-view/list.tsx index 9c624373d4..8e07eb5650 100644 --- a/web/app/components/workflow/block-selector/tool/tool-list-flat-view/list.tsx +++ b/web/app/components/workflow/block-selector/tool/tool-list-flat-view/list.tsx @@ -1,6 +1,6 @@ 'use client' import type { FC } from 'react' -import React, { useEffect } from 'react' +import React from 'react' import type { ToolWithProvider } from '../../../types' import type { BlockEnum } from '../../../types' import type { ToolDefaultValue } from '../../types' @@ -20,16 +20,6 @@ const ToolViewFlatView: FC = ({ hasSearchText, onSelect, }) => { - const [fold, setFold] = React.useState(true) - useEffect(() => { - if (hasSearchText && fold) { - setFold(false) - return - } - if (!hasSearchText && !fold) - setFold(true) - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [hasSearchText]) return (
{payload.map(tool => ( @@ -38,8 +28,7 @@ const ToolViewFlatView: FC = ({ payload={tool} viewType={ViewType.flat} isShowLetterIndex={isShowLetterIndex} - isFold={fold} - onFoldChange={setFold} + hasSearchText={hasSearchText} onSelect={onSelect} /> ))} diff --git a/web/app/components/workflow/block-selector/tool/tool-list-tree-view/item.tsx b/web/app/components/workflow/block-selector/tool/tool-list-tree-view/item.tsx index f74602c901..bf90c72aad 100644 --- a/web/app/components/workflow/block-selector/tool/tool-list-tree-view/item.tsx +++ b/web/app/components/workflow/block-selector/tool/tool-list-tree-view/item.tsx @@ -1,6 +1,6 @@ 'use client' import type { FC } from 'react' -import React, { useEffect } from 'react' +import React from 'react' import type { ToolWithProvider } from '../../../types' import Tool from '../tool' import type { BlockEnum } from '../../../types' @@ -20,16 +20,6 @@ const Item: FC = ({ hasSearchText, onSelect, }) => { - const [fold, setFold] = React.useState(true) - useEffect(() => { - if (hasSearchText && fold) { - setFold(false) - return - } - if (!hasSearchText && !fold) - setFold(true) - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [hasSearchText]) return (
@@ -42,8 +32,7 @@ const Item: FC = ({ payload={tool} viewType={ViewType.tree} isShowLetterIndex={false} - isFold={fold} - onFoldChange={setFold} + hasSearchText={hasSearchText} onSelect={onSelect} /> ))} diff --git a/web/app/components/workflow/block-selector/tool/tool.tsx b/web/app/components/workflow/block-selector/tool/tool.tsx index 658bccd630..a604f4f211 100644 --- a/web/app/components/workflow/block-selector/tool/tool.tsx +++ b/web/app/components/workflow/block-selector/tool/tool.tsx @@ -1,6 +1,6 @@ 'use client' import type { FC } from 'react' -import React, { useMemo } from 'react' +import React, { useEffect, useMemo } from 'react' import cn from '@/utils/classnames' import { RiArrowDownSLine, RiArrowRightSLine } from '@remixicon/react' import { useGetLanguage } from '@/context/i18n' @@ -18,8 +18,7 @@ type Props = { payload: ToolWithProvider viewType: ViewType isShowLetterIndex: boolean - isFold: boolean - onFoldChange: (fold: boolean) => void + hasSearchText: boolean onSelect: (type: BlockEnum, tool?: ToolDefaultValue) => void } @@ -28,8 +27,7 @@ const Tool: FC = ({ payload, viewType, isShowLetterIndex, - isFold, - onFoldChange, + hasSearchText, onSelect, }) => { const { t } = useTranslation() @@ -37,6 +35,16 @@ const Tool: FC = ({ const isFlatView = viewType === ViewType.flat const actions = payload.tools const hasAction = true // Now always support actions + const [isFold, setFold] = React.useState(true) + useEffect(() => { + if (hasSearchText && isFold) { + setFold(false) + return + } + if (!hasSearchText && !isFold) + setFold(true) + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [hasSearchText]) const FoldIcon = isFold ? RiArrowRightSLine : RiArrowDownSLine @@ -63,7 +71,7 @@ const Tool: FC = ({ className='flex items-center justify-between pl-3 pr-1 w-full rounded-lg hover:bg-gray-50 cursor-pointer select-none' onClick={() => { if (hasAction) - onFoldChange(!isFold) + setFold(!isFold) // Now always support actions // if (payload.parameters) { From 5c98d80fdfeef4cf7fc614a7f0759f79b31275c6 Mon Sep 17 00:00:00 2001 From: Joel Date: Wed, 13 Nov 2024 15:12:58 +0800 Subject: [PATCH 37/68] chore: more filter text content --- web/app/components/workflow/block-selector/all-tools.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/app/components/workflow/block-selector/all-tools.tsx b/web/app/components/workflow/block-selector/all-tools.tsx index b93d68c019..13ac91aece 100644 --- a/web/app/components/workflow/block-selector/all-tools.tsx +++ b/web/app/components/workflow/block-selector/all-tools.tsx @@ -64,7 +64,7 @@ const AllTools = ({ return mergedTools.filter((toolWithProvider) => { return toolWithProvider.tools.some((tool) => { - return tool.label[language].toLowerCase().includes(searchText.toLowerCase()) + return tool.label[language].toLowerCase().includes(searchText.toLowerCase()) || tool.name.toLowerCase().includes(searchText.toLowerCase()) }) }) }, [activeTab, buildInTools, customTools, workflowTools, searchText, language, hasFilter]) From edbfe27eb18400158a5f5b753ba6102df6489a32 Mon Sep 17 00:00:00 2001 From: Joel Date: Wed, 13 Nov 2024 15:17:22 +0800 Subject: [PATCH 38/68] chore: add invalid all built in tools --- web/service/use-tools.ts | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/web/service/use-tools.ts b/web/service/use-tools.ts index 3c34de3be9..ee2af1f398 100644 --- a/web/service/use-tools.ts +++ b/web/service/use-tools.ts @@ -12,13 +12,24 @@ import { const NAME_SPACE = 'tools' +const useAllBuiltInToolsKey = [NAME_SPACE, 'builtIn'] export const useAllBuiltInTools = () => { return useQuery({ - queryKey: [NAME_SPACE, 'builtIn'], + queryKey: useAllBuiltInToolsKey, queryFn: () => get('/workspaces/current/tools/builtin'), }) } +export const useInvalidateAllBuiltInTools = () => { + const queryClient = useQueryClient() + return () => { + queryClient.invalidateQueries( + { + queryKey: useAllBuiltInToolsKey, + }) + } +} + const useAllCustomToolsKey = [NAME_SPACE, 'customTools'] export const useAllCustomTools = () => { return useQuery({ From 577a948f42e6a9e7d8ab764d03a2a5abe0c640b3 Mon Sep 17 00:00:00 2001 From: StyleZhang Date: Wed, 13 Nov 2024 15:48:06 +0800 Subject: [PATCH 39/68] feat: dsl check plugin --- .../app/create-from-dsl-modal/index.tsx | 14 +++++++- web/app/components/plugins/types.ts | 12 +++++++ web/app/components/workflow/index.tsx | 4 ++- .../workflow/plugin-dependency/index.tsx | 14 ++++++++ .../workflow/plugin-dependency/store.ts | 11 +++++++ .../components/workflow/update-dsl-modal.tsx | 11 +++++-- web/service/use-plugins.ts | 32 +++++++++++++++++++ 7 files changed, 94 insertions(+), 4 deletions(-) create mode 100644 web/app/components/workflow/plugin-dependency/index.tsx create mode 100644 web/app/components/workflow/plugin-dependency/store.ts diff --git a/web/app/components/app/create-from-dsl-modal/index.tsx b/web/app/components/app/create-from-dsl-modal/index.tsx index a97ca97bbe..45ef8dbde6 100644 --- a/web/app/components/app/create-from-dsl-modal/index.tsx +++ b/web/app/components/app/create-from-dsl-modal/index.tsx @@ -21,8 +21,9 @@ import AppsFull from '@/app/components/billing/apps-full-in-dialog' import { NEED_REFRESH_APP_LIST_KEY } from '@/config' import { getRedirection } from '@/utils/app-redirection' import cn from '@/utils/classnames' +import { useMutationCheckDependenciesBeforeImportDSL } from '@/service/use-plugins' -interface CreateFromDSLModalProps { +type CreateFromDSLModalProps = { show: boolean onSuccess?: () => void onClose: () => void @@ -43,6 +44,7 @@ const CreateFromDSLModal = ({ show, onSuccess, onClose, activeTab = CreateFromDS const [fileContent, setFileContent] = useState() const [currentTab, setCurrentTab] = useState(activeTab) const [dslUrlValue, setDslUrlValue] = useState(dslUrl) + const { mutateAsync } = useMutationCheckDependenciesBeforeImportDSL() const readFile = (file: File) => { const reader = new FileReader() @@ -78,11 +80,21 @@ const CreateFromDSLModal = ({ show, onSuccess, onClose, activeTab = CreateFromDS let app if (currentTab === CreateFromDSLModalTab.FROM_FILE) { + const leakedData = await mutateAsync({ dslString: fileContent }) + if (leakedData?.leaked.length) { + isCreatingRef.current = false + return + } app = await importApp({ data: fileContent || '', }) } if (currentTab === CreateFromDSLModalTab.FROM_URL) { + const leakedData = await mutateAsync({ url: dslUrlValue }) + if (leakedData?.leaked.length) { + isCreatingRef.current = false + return + } app = await importAppFromUrl({ url: dslUrlValue || '', }) diff --git a/web/app/components/plugins/types.ts b/web/app/components/plugins/types.ts index 4d9ae8ca35..e42dff0f5c 100644 --- a/web/app/components/plugins/types.ts +++ b/web/app/components/plugins/types.ts @@ -305,3 +305,15 @@ export type UninstallPluginResponse = { export type PluginsFromMarketplaceResponse = { plugins: Plugin[] } + +export type Dependency = { + type: 'github' | 'marketplace' | 'package' + value: { + repo?: string + version?: string + package?: string + github_plugin_unique_identifier?: string + marketplace_plugin_unique_identifier?: string + plugin_unique_identifier?: string + } +} diff --git a/web/app/components/workflow/index.tsx b/web/app/components/workflow/index.tsx index 3a5a790919..2eccb38e47 100644 --- a/web/app/components/workflow/index.tsx +++ b/web/app/components/workflow/index.tsx @@ -72,6 +72,7 @@ import SyncingDataModal from './syncing-data-modal' import UpdateDSLModal from './update-dsl-modal' import DSLExportConfirmModal from './dsl-export-confirm-modal' import LimitTips from './limit-tips' +import PluginDependency from './plugin-dependency' import { useStore, useWorkflowStore, @@ -105,7 +106,7 @@ const edgeTypes = { [CUSTOM_NODE]: CustomEdge, } -interface WorkflowProps { +type WorkflowProps = { nodes: Node[] edges: Edge[] viewport?: Viewport @@ -326,6 +327,7 @@ const Workflow: FC = memo(({ /> ) } + { + const dependencies = useStore(s => s.dependencies) + + if (!dependencies.length) + return null + + return ( +
a
+ ) +} + +export default PluginDependency diff --git a/web/app/components/workflow/plugin-dependency/store.ts b/web/app/components/workflow/plugin-dependency/store.ts new file mode 100644 index 0000000000..a8e1d8171a --- /dev/null +++ b/web/app/components/workflow/plugin-dependency/store.ts @@ -0,0 +1,11 @@ +import { create } from 'zustand' +import type { Dependency } from '@/app/components/plugins/types' + +type Shape = { + dependencies: Dependency[] + setDependencies: (dependencies: Dependency[]) => void +} +export const useStore = create(set => ({ + dependencies: [], + setDependencies: dependencies => set({ dependencies }), +})) diff --git a/web/app/components/workflow/update-dsl-modal.tsx b/web/app/components/workflow/update-dsl-modal.tsx index d91b7ca04b..86a3648c4e 100644 --- a/web/app/components/workflow/update-dsl-modal.tsx +++ b/web/app/components/workflow/update-dsl-modal.tsx @@ -29,8 +29,9 @@ import { updateWorkflowDraftFromDSL } from '@/service/workflow' import { useEventEmitterContextContext } from '@/context/event-emitter' import { useStore as useAppStore } from '@/app/components/app/store' import { FILE_EXTS } from '@/app/components/base/prompt-editor/constants' +import { useMutationCheckDependenciesBeforeImportDSL } from '@/service/use-plugins' -interface UpdateDSLModalProps { +type UpdateDSLModalProps = { onCancel: () => void onBackup: () => void onImport?: () => void @@ -48,6 +49,7 @@ const UpdateDSLModal = ({ const [fileContent, setFileContent] = useState() const [loading, setLoading] = useState(false) const { eventEmitter } = useEventEmitterContextContext() + const { mutateAsync, mutate } = useMutationCheckDependenciesBeforeImportDSL() const readFile = (file: File) => { const reader = new FileReader() @@ -75,6 +77,11 @@ const UpdateDSLModal = ({ return try { if (appDetail && fileContent) { + const leakedData = await mutateAsync({ dslString: fileContent }) + if (leakedData?.leaked.length) { + isCreatingRef.current = false + return + } setLoading(true) const { graph, @@ -128,7 +135,7 @@ const UpdateDSLModal = ({ notify({ type: 'error', message: t('workflow.common.importFailure') }) } isCreatingRef.current = false - }, [currentFile, fileContent, onCancel, notify, t, eventEmitter, appDetail, onImport]) + }, [currentFile, fileContent, onCancel, notify, t, eventEmitter, appDetail, onImport, mutateAsync]) return ( { }, }) } + +export const useMutationCheckDependenciesBeforeImportDSL = () => { + const mutation = useMutation({ + mutationFn: ({ dslString, url }: { dslString?: string, url?: string }) => { + if (url) { + return post<{ leaked: Dependency[] }>( + '/apps/import/url/dependencies/check', + { + body: { + url, + }, + }, + ) + } + return post<{ leaked: Dependency[] }>( + '/apps/import/dependencies/check', + { + body: { + data: dslString, + }, + }) + }, + onSuccess: (data) => { + const { setDependencies } = usePluginDependencyStore.getState() + setDependencies(data.leaked || []) + }, + }) + + return mutation +} From 0d607a8c9016c8c2d2da61aefde2ceaa8a3fd9e5 Mon Sep 17 00:00:00 2001 From: Joel Date: Wed, 13 Nov 2024 16:22:09 +0800 Subject: [PATCH 40/68] feat: add update workflow to update use query --- web/app/components/tools/provider/detail.tsx | 4 +++- .../tools/workflow-tool/configure-button.tsx | 4 ++++ web/service/use-plugins.ts | 3 +++ web/service/use-tools.ts | 24 +++++++------------ 4 files changed, 19 insertions(+), 16 deletions(-) diff --git a/web/app/components/tools/provider/detail.tsx b/web/app/components/tools/provider/detail.tsx index 96f36a2095..93b728e4c5 100644 --- a/web/app/components/tools/provider/detail.tsx +++ b/web/app/components/tools/provider/detail.tsx @@ -44,6 +44,7 @@ import { useProviderContext } from '@/context/provider-context' import { ConfigurationMethodEnum } from '@/app/components/header/account-setting/model-provider-page/declarations' import Loading from '@/app/components/base/loading' import { useAppContext } from '@/context/app-context' +import { useInvalidateAllWorkflowTools } from '@/service/use-tools' type Props = { collection: Collection @@ -65,7 +66,7 @@ const ProviderDetail = ({ const isBuiltIn = collection.type === CollectionType.builtIn const isModel = collection.type === CollectionType.model const { isCurrentWorkspaceManager } = useAppContext() - + const invalidateAllWorkflowTools = useInvalidateAllWorkflowTools() const [isDetailLoading, setIsDetailLoading] = useState(false) // built in provider @@ -164,6 +165,7 @@ const ProviderDetail = ({ workflow_tool_id: string }>) => { await saveWorkflowToolProvider(data) + invalidateAllWorkflowTools() onRefreshData() getWorkflowToolProvider() Toast.notify({ diff --git a/web/app/components/tools/workflow-tool/configure-button.tsx b/web/app/components/tools/workflow-tool/configure-button.tsx index 6521410dae..18d1191235 100644 --- a/web/app/components/tools/workflow-tool/configure-button.tsx +++ b/web/app/components/tools/workflow-tool/configure-button.tsx @@ -14,6 +14,7 @@ import { createWorkflowToolProvider, fetchWorkflowToolDetailByAppID, saveWorkflo import type { Emoji, WorkflowToolProviderParameter, WorkflowToolProviderRequest, WorkflowToolProviderResponse } from '@/app/components/tools/types' import type { InputVar } from '@/app/components/workflow/types' import { useAppContext } from '@/context/app-context' +import { useInvalidateAllWorkflowTools } from '@/service/use-tools' type Props = { disabled: boolean @@ -46,6 +47,7 @@ const WorkflowToolConfigureButton = ({ const [isLoading, setIsLoading] = useState(false) const [detail, setDetail] = useState() const { isCurrentWorkspaceManager } = useAppContext() + const invalidateAllWorkflowTools = useInvalidateAllWorkflowTools() const outdated = useMemo(() => { if (!detail) @@ -135,6 +137,7 @@ const WorkflowToolConfigureButton = ({ const createHandle = async (data: WorkflowToolProviderRequest & { workflow_app_id: string }) => { try { await createWorkflowToolProvider(data) + invalidateAllWorkflowTools() onRefreshData?.() getDetail(workflowAppId) Toast.notify({ @@ -156,6 +159,7 @@ const WorkflowToolConfigureButton = ({ await handlePublish() await saveWorkflowToolProvider(data) onRefreshData?.() + invalidateAllWorkflowTools() getDetail(workflowAppId) Toast.notify({ type: 'success', diff --git a/web/service/use-plugins.ts b/web/service/use-plugins.ts index 4b99caf835..c9f8058e8f 100644 --- a/web/service/use-plugins.ts +++ b/web/service/use-plugins.ts @@ -18,6 +18,7 @@ import { useQueryClient, } from '@tanstack/react-query' import { useStore as usePluginDependencyStore } from '@/app/components/workflow/plugin-dependency/store' +import { useInvalidateAllBuiltInTools } from './use-tools' const NAME_SPACE = 'plugins' @@ -31,11 +32,13 @@ export const useInstalledPluginList = () => { export const useInvalidateInstalledPluginList = () => { const queryClient = useQueryClient() + const invalidateAllBuiltInTools = useInvalidateAllBuiltInTools() return () => { queryClient.invalidateQueries( { queryKey: useInstalledPluginListKey, }) + invalidateAllBuiltInTools() } } diff --git a/web/service/use-tools.ts b/web/service/use-tools.ts index ee2af1f398..8b06d47342 100644 --- a/web/service/use-tools.ts +++ b/web/service/use-tools.ts @@ -4,6 +4,7 @@ import type { Tool, } from '@/app/components/tools/types' import type { ToolWithProvider } from '@/app/components/workflow/types' +import { useInvalid } from './use-base' import { useMutation, useQuery, @@ -21,13 +22,7 @@ export const useAllBuiltInTools = () => { } export const useInvalidateAllBuiltInTools = () => { - const queryClient = useQueryClient() - return () => { - queryClient.invalidateQueries( - { - queryKey: useAllBuiltInToolsKey, - }) - } + return useInvalid(useAllBuiltInToolsKey) } const useAllCustomToolsKey = [NAME_SPACE, 'customTools'] @@ -39,22 +34,21 @@ export const useAllCustomTools = () => { } export const useInvalidateAllCustomTools = () => { - const queryClient = useQueryClient() - return () => { - queryClient.invalidateQueries( - { - queryKey: useAllCustomToolsKey, - }) - } + return useInvalid(useAllCustomToolsKey) } +const useAllWorkflowToolsKey = [NAME_SPACE, 'workflowTools'] export const useAllWorkflowTools = () => { return useQuery({ - queryKey: [NAME_SPACE, 'workflowTools'], + queryKey: useAllWorkflowToolsKey, queryFn: () => get('/workspaces/current/tools/workflow'), }) } +export const useInvalidateAllWorkflowTools = () => { + return useInvalid(useAllWorkflowToolsKey) +} + export const useBuiltinProviderInfo = (providerName: string) => { return useQuery({ queryKey: [NAME_SPACE, 'builtin-provider-info', providerName], From 3e314843db5d0b6a13e1796a0f211a4711f56ac5 Mon Sep 17 00:00:00 2001 From: Joel Date: Wed, 13 Nov 2024 16:22:28 +0800 Subject: [PATCH 41/68] chore: add missing file --- web/service/use-base.ts | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 web/service/use-base.ts diff --git a/web/service/use-base.ts b/web/service/use-base.ts new file mode 100644 index 0000000000..5eeca22668 --- /dev/null +++ b/web/service/use-base.ts @@ -0,0 +1,13 @@ +import { + useQueryClient, +} from '@tanstack/react-query' + +export const useInvalid = (key: string[]) => { + const queryClient = useQueryClient() + return () => { + queryClient.invalidateQueries( + { + queryKey: key, + }) + } +} From aa88028564b65a4c23529096db89f5535dd276ff Mon Sep 17 00:00:00 2001 From: StyleZhang Date: Wed, 13 Nov 2024 16:28:18 +0800 Subject: [PATCH 42/68] fix: marketplace list --- .../plugins/marketplace/context.tsx | 5 ++++ .../plugins/marketplace/list/list-wrapper.tsx | 29 ++++++++++++++----- web/app/components/tools/marketplace/hooks.ts | 5 +++- 3 files changed, 30 insertions(+), 9 deletions(-) diff --git a/web/app/components/plugins/marketplace/context.tsx b/web/app/components/plugins/marketplace/context.tsx index 4c5752d45b..6dabfdf736 100644 --- a/web/app/components/plugins/marketplace/context.tsx +++ b/web/app/components/plugins/marketplace/context.tsx @@ -41,6 +41,7 @@ export type MarketplaceContextValue = { setMarketplaceCollectionsFromClient: (collections: MarketplaceCollection[]) => void marketplaceCollectionPluginsMapFromClient?: Record setMarketplaceCollectionPluginsMapFromClient: (map: Record) => void + isLoading: boolean } export const MarketplaceContext = createContext({ @@ -60,6 +61,7 @@ export const MarketplaceContext = createContext({ setMarketplaceCollectionsFromClient: () => {}, marketplaceCollectionPluginsMapFromClient: {}, setMarketplaceCollectionPluginsMapFromClient: () => {}, + isLoading: false, }) type MarketplaceContextProviderProps = { @@ -88,12 +90,14 @@ export const MarketplaceContextProvider = ({ marketplaceCollectionPluginsMap: marketplaceCollectionPluginsMapFromClient, setMarketplaceCollectionPluginsMap: setMarketplaceCollectionPluginsMapFromClient, queryMarketplaceCollectionsAndPlugins, + isLoading, } = useMarketplaceCollectionsAndPlugins() const { plugins, resetPlugins, queryPlugins, queryPluginsWithDebounced, + isLoading: isPluginsLoading, } = useMarketplacePlugins() const handleSearchPluginTextChange = useCallback((text: string) => { @@ -194,6 +198,7 @@ export const MarketplaceContextProvider = ({ setMarketplaceCollectionsFromClient, marketplaceCollectionPluginsMapFromClient, setMarketplaceCollectionPluginsMapFromClient, + isLoading: isLoading || isPluginsLoading, }} > {children} diff --git a/web/app/components/plugins/marketplace/list/list-wrapper.tsx b/web/app/components/plugins/marketplace/list/list-wrapper.tsx index 50f4c5d244..936cb7ec57 100644 --- a/web/app/components/plugins/marketplace/list/list-wrapper.tsx +++ b/web/app/components/plugins/marketplace/list/list-wrapper.tsx @@ -4,6 +4,7 @@ import type { MarketplaceCollection } from '../types' import { useMarketplaceContext } from '../context' import List from './index' import SortDropdown from '../sort-dropdown' +import Loading from '@/app/components/base/loading' type ListWrapperProps = { marketplaceCollections: MarketplaceCollection[] @@ -20,9 +21,10 @@ const ListWrapper = ({ const plugins = useMarketplaceContext(v => v.plugins) const marketplaceCollectionsFromClient = useMarketplaceContext(v => v.marketplaceCollectionsFromClient) const marketplaceCollectionPluginsMapFromClient = useMarketplaceContext(v => v.marketplaceCollectionPluginsMapFromClient) + const isLoading = useMarketplaceContext(v => v.isLoading) return ( -
+
{ plugins && (
@@ -32,13 +34,24 @@ const ListWrapper = ({
) } - + { + isLoading && ( +
+ +
+ ) + } + { + !isLoading && ( + + ) + }
) } diff --git a/web/app/components/tools/marketplace/hooks.ts b/web/app/components/tools/marketplace/hooks.ts index 5d27e10043..45cbd8a389 100644 --- a/web/app/components/tools/marketplace/hooks.ts +++ b/web/app/components/tools/marketplace/hooks.ts @@ -5,6 +5,7 @@ import { useMarketplaceCollectionsAndPlugins, useMarketplacePlugins, } from '@/app/components/plugins/marketplace/hooks' +import { PluginType } from '@/app/components/plugins/types' export const useMarketplace = (searchPluginText: string, filterPluginTags: string[]) => { const { @@ -25,18 +26,20 @@ export const useMarketplace = (searchPluginText: string, filterPluginTags: strin if (searchPluginText || filterPluginTags.length) { if (searchPluginText) { queryPluginsWithDebounced({ + category: PluginType.tool, query: searchPluginText, tags: filterPluginTags, }) return } queryPlugins({ + category: PluginType.tool, query: searchPluginText, tags: filterPluginTags, }) } else { - queryMarketplaceCollectionsAndPlugins() + queryMarketplaceCollectionsAndPlugins({ category: PluginType.tool }) resetPlugins() } }, [searchPluginText, filterPluginTags, queryPlugins, queryMarketplaceCollectionsAndPlugins, queryPluginsWithDebounced, resetPlugins]) From b10a1cd325e4f7c92e08d69251f7f89bf0849698 Mon Sep 17 00:00:00 2001 From: Yi Date: Wed, 13 Nov 2024 16:43:00 +0800 Subject: [PATCH 43/68] chore: update the theme selector setting in globals.css --- web/app/styles/globals.css | 59 ++++++++++++++++++++++---------------- 1 file changed, 35 insertions(+), 24 deletions(-) diff --git a/web/app/styles/globals.css b/web/app/styles/globals.css index f0a8e466d6..06d2596a24 100644 --- a/web/app/styles/globals.css +++ b/web/app/styles/globals.css @@ -2,8 +2,8 @@ @tailwind base; @tailwind components; -@import '../../themes/light.css'; -@import '../../themes/dark.css'; +@import "../../themes/light.css"; +@import "../../themes/dark.css"; html[data-changing-theme] * { transition: none !important; @@ -20,24 +20,30 @@ html[data-changing-theme] * { --background-start-rgb: 214, 219, 220; --background-end-rgb: 255, 255, 255; - --primary-glow: conic-gradient(from 180deg at 50% 50%, - #16abff33 0deg, - #0885ff33 55deg, - #54d6ff33 120deg, - #0071ff33 160deg, - transparent 360deg); - --secondary-glow: radial-gradient(rgba(255, 255, 255, 1), - rgba(255, 255, 255, 0)); + --primary-glow: conic-gradient( + from 180deg at 50% 50%, + #16abff33 0deg, + #0885ff33 55deg, + #54d6ff33 120deg, + #0071ff33 160deg, + transparent 360deg + ); + --secondary-glow: radial-gradient( + rgba(255, 255, 255, 1), + rgba(255, 255, 255, 0) + ); --tile-start-rgb: 239, 245, 249; --tile-end-rgb: 228, 232, 233; - --tile-border: conic-gradient(#00000080, - #00000040, - #00000030, - #00000020, - #00000010, - #00000010, - #00000080); + --tile-border: conic-gradient( + #00000080, + #00000040, + #00000030, + #00000020, + #00000010, + #00000010, + #00000080 + ); --callout-rgb: 238, 240, 241; --callout-border-rgb: 172, 175, 176; @@ -282,7 +288,7 @@ button:focus-within { line-height: 24px; } -[class*='code-'] { +[class*="code-"] { @apply font-mono; } @@ -644,7 +650,7 @@ button:focus-within { } .text-gradient { - background: linear-gradient(91.58deg, #2250F2 -29.55%, #0EBCF3 75.22%); + background: linear-gradient(91.58deg, #2250f2 -29.55%, #0ebcf3 75.22%); -webkit-background-clip: text; -webkit-text-fill-color: transparent; background-clip: text; @@ -652,7 +658,7 @@ button:focus-within { } /* overwrite paging active dark model style */ -[class*=style_paginatio] li .text-primary-600 { +[class*="style_paginatio"] li .text-primary-600 { color: rgb(28 100 242); background-color: rgb(235 245 255); } @@ -665,8 +671,13 @@ button:focus-within { bottom: 0; } -@import '../components/base/button/index.css'; -@import '../components/base/action-button/index.css'; -@import '../components/base/modal/index.css'; +[data-theme="dark"] [data-hide-on-theme="dark"], +[data-theme="light"] [data-hide-on-theme="light"] { + display: none; +} -@tailwind utilities; \ No newline at end of file +@import "../components/base/button/index.css"; +@import "../components/base/action-button/index.css"; +@import "../components/base/modal/index.css"; + +@tailwind utilities; From a1719c49b78100804766c55d6d27c9df409cfc32 Mon Sep 17 00:00:00 2001 From: twwu Date: Wed, 13 Nov 2024 16:55:43 +0800 Subject: [PATCH 44/68] feat: add internationalization support for plugin categories and update translations --- web/app/components/plugins/hooks.ts | 39 +++++++++++++++++++ .../components/plugins/plugin-item/index.tsx | 2 +- .../filter-management/category-filter.tsx | 38 ++++++------------ .../filter-management/search-box.tsx | 5 ++- .../filter-management/tag-filter.tsx | 30 ++++++-------- web/i18n/de-DE/plugin-categories.ts | 4 ++ web/i18n/en-US/plugin-categories.ts | 12 ++++++ web/i18n/en-US/plugin.ts | 1 + web/i18n/es-ES/plugin-categories.ts | 4 ++ web/i18n/fa-IR/plugin-categories.ts | 4 ++ web/i18n/fr-FR/plugin-categories.ts | 4 ++ web/i18n/hi-IN/plugin-categories.ts | 4 ++ web/i18n/i18next-config.ts | 1 + web/i18n/it-IT/plugin-categories.ts | 4 ++ web/i18n/ja-JP/plugin-categories.ts | 4 ++ web/i18n/ko-KR/plugin-categories.ts | 4 ++ web/i18n/pl-PL/plugin-categories.ts | 4 ++ web/i18n/pt-BR/plugin-categories.ts | 4 ++ web/i18n/ro-RO/plugin-categories.ts | 4 ++ web/i18n/ru-RU/plugin-categories.ts | 4 ++ web/i18n/tr-TR/plugin-categories.ts | 4 ++ web/i18n/uk-UA/plugin-categories.ts | 4 ++ web/i18n/vi-VN/plugin-categories.ts | 4 ++ web/i18n/zh-Hans/plugin-categories.ts | 12 ++++++ web/i18n/zh-Hans/plugin.ts | 1 + web/i18n/zh-Hant/plugin-categories.ts | 4 ++ 26 files changed, 159 insertions(+), 46 deletions(-) create mode 100644 web/i18n/de-DE/plugin-categories.ts create mode 100644 web/i18n/en-US/plugin-categories.ts create mode 100644 web/i18n/es-ES/plugin-categories.ts create mode 100644 web/i18n/fa-IR/plugin-categories.ts create mode 100644 web/i18n/fr-FR/plugin-categories.ts create mode 100644 web/i18n/hi-IN/plugin-categories.ts create mode 100644 web/i18n/it-IT/plugin-categories.ts create mode 100644 web/i18n/ja-JP/plugin-categories.ts create mode 100644 web/i18n/ko-KR/plugin-categories.ts create mode 100644 web/i18n/pl-PL/plugin-categories.ts create mode 100644 web/i18n/pt-BR/plugin-categories.ts create mode 100644 web/i18n/ro-RO/plugin-categories.ts create mode 100644 web/i18n/ru-RU/plugin-categories.ts create mode 100644 web/i18n/tr-TR/plugin-categories.ts create mode 100644 web/i18n/uk-UA/plugin-categories.ts create mode 100644 web/i18n/vi-VN/plugin-categories.ts create mode 100644 web/i18n/zh-Hans/plugin-categories.ts create mode 100644 web/i18n/zh-Hant/plugin-categories.ts diff --git a/web/app/components/plugins/hooks.ts b/web/app/components/plugins/hooks.ts index 484a7fbb5a..9d259c738a 100644 --- a/web/app/components/plugins/hooks.ts +++ b/web/app/components/plugins/hooks.ts @@ -87,3 +87,42 @@ export const useTags = (translateFromOut?: TFunction) => { tagsMap, } } + +type Category = { + name: string + label: string +} + +export const useCategories = (translateFromOut?: TFunction) => { + const { t: translation } = useTranslation() + const t = translateFromOut || translation + + const categories = [ + { + name: 'model', + label: t('pluginCategories.categories.model'), + }, + { + name: 'tool', + label: t('pluginCategories.categories.tool'), + }, + { + name: 'extension', + label: t('pluginCategories.categories.extension'), + }, + { + name: 'bundle', + label: t('pluginCategories.categories.bundle'), + }, + ] + + const categoriesMap = categories.reduce((acc, category) => { + acc[category.name] = category + return acc + }, {} as Record) + + return { + categories, + categoriesMap, + } +} diff --git a/web/app/components/plugins/plugin-item/index.tsx b/web/app/components/plugins/plugin-item/index.tsx index 3569ed856c..563a6bc685 100644 --- a/web/app/components/plugins/plugin-item/index.tsx +++ b/web/app/components/plugins/plugin-item/index.tsx @@ -67,7 +67,7 @@ const PluginItem: FC = ({ }} >
- + {/* Header */}
diff --git a/web/app/components/plugins/plugin-page/filter-management/category-filter.tsx b/web/app/components/plugins/plugin-page/filter-management/category-filter.tsx index 8544bef95c..fa6540c4bf 100644 --- a/web/app/components/plugins/plugin-page/filter-management/category-filter.tsx +++ b/web/app/components/plugins/plugin-page/filter-management/category-filter.tsx @@ -13,6 +13,8 @@ import { import Checkbox from '@/app/components/base/checkbox' import cn from '@/utils/classnames' import Input from '@/app/components/base/input' +import { useCategories } from '../../hooks' +import { useTranslation } from 'react-i18next' type CategoriesFilterProps = { value: string[] @@ -22,27 +24,11 @@ const CategoriesFilter = ({ value, onChange, }: CategoriesFilterProps) => { + const { t } = useTranslation() const [open, setOpen] = useState(false) const [searchText, setSearchText] = useState('') - const options = [ - { - value: 'model', - text: 'Model', - }, - { - value: 'tool', - text: 'Tool', - }, - { - value: 'extension', - text: 'Extension', - }, - { - value: 'bundle', - text: 'Bundle', - }, - ] - const filteredOptions = options.filter(option => option.text.toLowerCase().includes(searchText.toLowerCase())) + const { categories: options, categoriesMap } = useCategories() + const filteredOptions = options.filter(option => option.name.toLowerCase().includes(searchText.toLowerCase())) const handleCheck = (id: string) => { if (value.includes(id)) onChange(value.filter(tag => tag !== id)) @@ -70,10 +56,10 @@ const CategoriesFilter = ({ 'flex items-center p-1 system-sm-medium', )}> { - !selectedTagsLength && 'All Categories' + !selectedTagsLength && t('pluginCategories.allCategories') } { - !!selectedTagsLength && value.slice(0, 2).join(',') + !!selectedTagsLength && value.map(val => categoriesMap[val].label).slice(0, 2).join(',') } { selectedTagsLength > 2 && ( @@ -110,23 +96,23 @@ const CategoriesFilter = ({ showLeftIcon value={searchText} onChange={e => setSearchText(e.target.value)} - placeholder='Search categories' + placeholder={t('pluginCategories.searchCategories')} />
{ filteredOptions.map(option => (
handleCheck(option.value)} + onClick={() => handleCheck(option.name)} >
- {option.text} + {option.label}
)) diff --git a/web/app/components/plugins/plugin-page/filter-management/search-box.tsx b/web/app/components/plugins/plugin-page/filter-management/search-box.tsx index 1b67a9a112..ad3547e89b 100644 --- a/web/app/components/plugins/plugin-page/filter-management/search-box.tsx +++ b/web/app/components/plugins/plugin-page/filter-management/search-box.tsx @@ -1,6 +1,7 @@ 'use client' import Input from '@/app/components/base/input' +import { useTranslation } from 'react-i18next' type SearchBoxProps = { searchQuery: string onChange: (query: string) => void @@ -10,13 +11,15 @@ const SearchBox: React.FC = ({ searchQuery, onChange, }) => { + const { t } = useTranslation() + return ( { onChange(e.target.value) }} diff --git a/web/app/components/plugins/plugin-page/filter-management/tag-filter.tsx b/web/app/components/plugins/plugin-page/filter-management/tag-filter.tsx index d337f17495..dd1781d9f4 100644 --- a/web/app/components/plugins/plugin-page/filter-management/tag-filter.tsx +++ b/web/app/components/plugins/plugin-page/filter-management/tag-filter.tsx @@ -13,6 +13,8 @@ import { import Checkbox from '@/app/components/base/checkbox' import cn from '@/utils/classnames' import Input from '@/app/components/base/input' +import { useTags } from '../../hooks' +import { useTranslation } from 'react-i18next' type TagsFilterProps = { value: string[] @@ -22,19 +24,11 @@ const TagsFilter = ({ value, onChange, }: TagsFilterProps) => { + const { t } = useTranslation() const [open, setOpen] = useState(false) const [searchText, setSearchText] = useState('') - const options = [ - { - value: 'search', - text: 'Search', - }, - { - value: 'image', - text: 'Image', - }, - ] - const filteredOptions = options.filter(option => option.text.toLowerCase().includes(searchText.toLowerCase())) + const { tags: options, tagsMap } = useTags() + const filteredOptions = options.filter(option => option.name.toLowerCase().includes(searchText.toLowerCase())) const handleCheck = (id: string) => { if (value.includes(id)) onChange(value.filter(tag => tag !== id)) @@ -62,10 +56,10 @@ const TagsFilter = ({ 'flex items-center p-1 system-sm-medium', )}> { - !selectedTagsLength && 'All Tags' + !selectedTagsLength && t('pluginTags.allTags') } { - !!selectedTagsLength && value.slice(0, 2).join(',') + !!selectedTagsLength && value.map(val => tagsMap[val].label).slice(0, 2).join(',') } { selectedTagsLength > 2 && ( @@ -97,23 +91,23 @@ const TagsFilter = ({ showLeftIcon value={searchText} onChange={e => setSearchText(e.target.value)} - placeholder='Search tags' + placeholder={t('pluginTags.searchTags')} />
{ filteredOptions.map(option => (
handleCheck(option.value)} + onClick={() => handleCheck(option.name)} >
- {option.text} + {option.label}
)) diff --git a/web/i18n/de-DE/plugin-categories.ts b/web/i18n/de-DE/plugin-categories.ts new file mode 100644 index 0000000000..928649474b --- /dev/null +++ b/web/i18n/de-DE/plugin-categories.ts @@ -0,0 +1,4 @@ +const translation = { +} + +export default translation diff --git a/web/i18n/en-US/plugin-categories.ts b/web/i18n/en-US/plugin-categories.ts new file mode 100644 index 0000000000..6ee5b76c25 --- /dev/null +++ b/web/i18n/en-US/plugin-categories.ts @@ -0,0 +1,12 @@ +const translation = { + allCategories: 'All Categories', + searchCategories: 'Search categories', + categories: { + model: 'Model', + tool: 'Tool', + extension: 'Extension', + bundle: 'Bundle', + }, +} + +export default translation diff --git a/web/i18n/en-US/plugin.ts b/web/i18n/en-US/plugin.ts index 689510acca..3784309c09 100644 --- a/web/i18n/en-US/plugin.ts +++ b/web/i18n/en-US/plugin.ts @@ -6,6 +6,7 @@ const translation = { extensions: 'extensions', bundles: 'bundles', }, + search: 'Search', searchPlugins: 'Search plugins', from: 'From', findMoreInMarketplace: 'Find more in Marketplace', diff --git a/web/i18n/es-ES/plugin-categories.ts b/web/i18n/es-ES/plugin-categories.ts new file mode 100644 index 0000000000..928649474b --- /dev/null +++ b/web/i18n/es-ES/plugin-categories.ts @@ -0,0 +1,4 @@ +const translation = { +} + +export default translation diff --git a/web/i18n/fa-IR/plugin-categories.ts b/web/i18n/fa-IR/plugin-categories.ts new file mode 100644 index 0000000000..928649474b --- /dev/null +++ b/web/i18n/fa-IR/plugin-categories.ts @@ -0,0 +1,4 @@ +const translation = { +} + +export default translation diff --git a/web/i18n/fr-FR/plugin-categories.ts b/web/i18n/fr-FR/plugin-categories.ts new file mode 100644 index 0000000000..928649474b --- /dev/null +++ b/web/i18n/fr-FR/plugin-categories.ts @@ -0,0 +1,4 @@ +const translation = { +} + +export default translation diff --git a/web/i18n/hi-IN/plugin-categories.ts b/web/i18n/hi-IN/plugin-categories.ts new file mode 100644 index 0000000000..928649474b --- /dev/null +++ b/web/i18n/hi-IN/plugin-categories.ts @@ -0,0 +1,4 @@ +const translation = { +} + +export default translation diff --git a/web/i18n/i18next-config.ts b/web/i18n/i18next-config.ts index bbba4c7c35..9b35cd5432 100644 --- a/web/i18n/i18next-config.ts +++ b/web/i18n/i18next-config.ts @@ -30,6 +30,7 @@ const loadLangResources = (lang: string) => ({ runLog: require(`./${lang}/run-log`).default, plugin: require(`./${lang}/plugin`).default, pluginTags: require(`./${lang}/plugin-tags`).default, + pluginCategories: require(`./${lang}/plugin-categories`).default, }, }) diff --git a/web/i18n/it-IT/plugin-categories.ts b/web/i18n/it-IT/plugin-categories.ts new file mode 100644 index 0000000000..928649474b --- /dev/null +++ b/web/i18n/it-IT/plugin-categories.ts @@ -0,0 +1,4 @@ +const translation = { +} + +export default translation diff --git a/web/i18n/ja-JP/plugin-categories.ts b/web/i18n/ja-JP/plugin-categories.ts new file mode 100644 index 0000000000..928649474b --- /dev/null +++ b/web/i18n/ja-JP/plugin-categories.ts @@ -0,0 +1,4 @@ +const translation = { +} + +export default translation diff --git a/web/i18n/ko-KR/plugin-categories.ts b/web/i18n/ko-KR/plugin-categories.ts new file mode 100644 index 0000000000..928649474b --- /dev/null +++ b/web/i18n/ko-KR/plugin-categories.ts @@ -0,0 +1,4 @@ +const translation = { +} + +export default translation diff --git a/web/i18n/pl-PL/plugin-categories.ts b/web/i18n/pl-PL/plugin-categories.ts new file mode 100644 index 0000000000..928649474b --- /dev/null +++ b/web/i18n/pl-PL/plugin-categories.ts @@ -0,0 +1,4 @@ +const translation = { +} + +export default translation diff --git a/web/i18n/pt-BR/plugin-categories.ts b/web/i18n/pt-BR/plugin-categories.ts new file mode 100644 index 0000000000..928649474b --- /dev/null +++ b/web/i18n/pt-BR/plugin-categories.ts @@ -0,0 +1,4 @@ +const translation = { +} + +export default translation diff --git a/web/i18n/ro-RO/plugin-categories.ts b/web/i18n/ro-RO/plugin-categories.ts new file mode 100644 index 0000000000..928649474b --- /dev/null +++ b/web/i18n/ro-RO/plugin-categories.ts @@ -0,0 +1,4 @@ +const translation = { +} + +export default translation diff --git a/web/i18n/ru-RU/plugin-categories.ts b/web/i18n/ru-RU/plugin-categories.ts new file mode 100644 index 0000000000..928649474b --- /dev/null +++ b/web/i18n/ru-RU/plugin-categories.ts @@ -0,0 +1,4 @@ +const translation = { +} + +export default translation diff --git a/web/i18n/tr-TR/plugin-categories.ts b/web/i18n/tr-TR/plugin-categories.ts new file mode 100644 index 0000000000..928649474b --- /dev/null +++ b/web/i18n/tr-TR/plugin-categories.ts @@ -0,0 +1,4 @@ +const translation = { +} + +export default translation diff --git a/web/i18n/uk-UA/plugin-categories.ts b/web/i18n/uk-UA/plugin-categories.ts new file mode 100644 index 0000000000..928649474b --- /dev/null +++ b/web/i18n/uk-UA/plugin-categories.ts @@ -0,0 +1,4 @@ +const translation = { +} + +export default translation diff --git a/web/i18n/vi-VN/plugin-categories.ts b/web/i18n/vi-VN/plugin-categories.ts new file mode 100644 index 0000000000..928649474b --- /dev/null +++ b/web/i18n/vi-VN/plugin-categories.ts @@ -0,0 +1,4 @@ +const translation = { +} + +export default translation diff --git a/web/i18n/zh-Hans/plugin-categories.ts b/web/i18n/zh-Hans/plugin-categories.ts new file mode 100644 index 0000000000..fb08e8ad87 --- /dev/null +++ b/web/i18n/zh-Hans/plugin-categories.ts @@ -0,0 +1,12 @@ +const translation = { + allCategories: '所有类型', + searchCategories: '搜索类型', + categories: { + model: '模型', + tool: '工具', + extension: '扩展', + bundle: '捆绑包', + }, +} + +export default translation diff --git a/web/i18n/zh-Hans/plugin.ts b/web/i18n/zh-Hans/plugin.ts index 25cd0ba03f..2e835bbfab 100644 --- a/web/i18n/zh-Hans/plugin.ts +++ b/web/i18n/zh-Hans/plugin.ts @@ -6,6 +6,7 @@ const translation = { extensions: '扩展', bundles: '捆绑包', }, + search: '搜索', searchPlugins: '搜索插件', from: '来自', findMoreInMarketplace: '在 Marketplace 中查找更多', diff --git a/web/i18n/zh-Hant/plugin-categories.ts b/web/i18n/zh-Hant/plugin-categories.ts new file mode 100644 index 0000000000..928649474b --- /dev/null +++ b/web/i18n/zh-Hant/plugin-categories.ts @@ -0,0 +1,4 @@ +const translation = { +} + +export default translation From 61eb655823c71079660900b7246afc805b51460d Mon Sep 17 00:00:00 2001 From: twwu Date: Wed, 13 Nov 2024 18:30:38 +0800 Subject: [PATCH 45/68] feat: update plugin category labels and improve internationalization support --- web/app/components/plugins/card/index.tsx | 4 +++- web/app/components/plugins/hooks.ts | 8 ++++---- web/app/components/plugins/plugin-item/index.tsx | 4 +++- .../filter-management/category-filter.tsx | 4 ++-- web/i18n/de-DE/plugin-categories.ts | 4 ---- web/i18n/en-US/plugin-categories.ts | 12 ------------ web/i18n/en-US/plugin.ts | 10 ++++++---- web/i18n/es-ES/plugin-categories.ts | 4 ---- web/i18n/fa-IR/plugin-categories.ts | 4 ---- web/i18n/fr-FR/plugin-categories.ts | 4 ---- web/i18n/hi-IN/plugin-categories.ts | 4 ---- web/i18n/i18next-config.ts | 1 - web/i18n/it-IT/plugin-categories.ts | 4 ---- web/i18n/ja-JP/plugin-categories.ts | 4 ---- web/i18n/ko-KR/plugin-categories.ts | 4 ---- web/i18n/pl-PL/plugin-categories.ts | 4 ---- web/i18n/pt-BR/plugin-categories.ts | 4 ---- web/i18n/ro-RO/plugin-categories.ts | 4 ---- web/i18n/ru-RU/plugin-categories.ts | 4 ---- web/i18n/tr-TR/plugin-categories.ts | 4 ---- web/i18n/uk-UA/plugin-categories.ts | 4 ---- web/i18n/vi-VN/plugin-categories.ts | 4 ---- web/i18n/zh-Hans/plugin-categories.ts | 12 ------------ web/i18n/zh-Hans/plugin.ts | 2 ++ web/i18n/zh-Hant/plugin-categories.ts | 4 ---- 25 files changed, 20 insertions(+), 101 deletions(-) delete mode 100644 web/i18n/de-DE/plugin-categories.ts delete mode 100644 web/i18n/en-US/plugin-categories.ts delete mode 100644 web/i18n/es-ES/plugin-categories.ts delete mode 100644 web/i18n/fa-IR/plugin-categories.ts delete mode 100644 web/i18n/fr-FR/plugin-categories.ts delete mode 100644 web/i18n/hi-IN/plugin-categories.ts delete mode 100644 web/i18n/it-IT/plugin-categories.ts delete mode 100644 web/i18n/ja-JP/plugin-categories.ts delete mode 100644 web/i18n/ko-KR/plugin-categories.ts delete mode 100644 web/i18n/pl-PL/plugin-categories.ts delete mode 100644 web/i18n/pt-BR/plugin-categories.ts delete mode 100644 web/i18n/ro-RO/plugin-categories.ts delete mode 100644 web/i18n/ru-RU/plugin-categories.ts delete mode 100644 web/i18n/tr-TR/plugin-categories.ts delete mode 100644 web/i18n/uk-UA/plugin-categories.ts delete mode 100644 web/i18n/vi-VN/plugin-categories.ts delete mode 100644 web/i18n/zh-Hans/plugin-categories.ts delete mode 100644 web/i18n/zh-Hant/plugin-categories.ts diff --git a/web/app/components/plugins/card/index.tsx b/web/app/components/plugins/card/index.tsx index b262727506..1e4cc5e28b 100644 --- a/web/app/components/plugins/card/index.tsx +++ b/web/app/components/plugins/card/index.tsx @@ -11,6 +11,7 @@ import Placeholder from './base/placeholder' import cn from '@/utils/classnames' import { useGetLanguage } from '@/context/i18n' import { getLanguage } from '@/i18n/language' +import { useCategories } from '../hooks' export type Props = { className?: string @@ -41,6 +42,7 @@ const Card = ({ }: Props) => { const defaultLocale = useGetLanguage() const locale = localeFromProps ? getLanguage(localeFromProps) : defaultLocale + const { categoriesMap } = useCategories() const { type, name, org, label, brief, icon, verified } = payload @@ -59,7 +61,7 @@ const Card = ({ return (
- {!hideCornerMark && } + {!hideCornerMark && } {/* Header */}
diff --git a/web/app/components/plugins/hooks.ts b/web/app/components/plugins/hooks.ts index 9d259c738a..81488fed30 100644 --- a/web/app/components/plugins/hooks.ts +++ b/web/app/components/plugins/hooks.ts @@ -100,19 +100,19 @@ export const useCategories = (translateFromOut?: TFunction) => { const categories = [ { name: 'model', - label: t('pluginCategories.categories.model'), + label: t('plugin.category.models'), }, { name: 'tool', - label: t('pluginCategories.categories.tool'), + label: t('plugin.category.tools'), }, { name: 'extension', - label: t('pluginCategories.categories.extension'), + label: t('plugin.category.extensions'), }, { name: 'bundle', - label: t('pluginCategories.categories.bundle'), + label: t('plugin.category.bundles'), }, ] diff --git a/web/app/components/plugins/plugin-item/index.tsx b/web/app/components/plugins/plugin-item/index.tsx index 563a6bc685..aaa64b87a5 100644 --- a/web/app/components/plugins/plugin-item/index.tsx +++ b/web/app/components/plugins/plugin-item/index.tsx @@ -22,6 +22,7 @@ import cn from '@/utils/classnames' import { API_PREFIX, MARKETPLACE_URL_PREFIX } from '@/config' import { useLanguage } from '../../header/account-setting/model-provider-page/hooks' import { useInvalidateInstalledPluginList } from '@/service/use-plugins' +import { useCategories } from '../hooks' type Props = { className?: string @@ -34,6 +35,7 @@ const PluginItem: FC = ({ }) => { const locale = useLanguage() const { t } = useTranslation() + const { categoriesMap } = useCategories() const currentPluginDetail = usePluginPageContext(v => v.currentPluginDetail) const setCurrentPluginDetail = usePluginPageContext(v => v.setCurrentPluginDetail) const invalidateInstalledPluginList = useInvalidateInstalledPluginList() @@ -67,7 +69,7 @@ const PluginItem: FC = ({ }} >
- + {/* Header */}
diff --git a/web/app/components/plugins/plugin-page/filter-management/category-filter.tsx b/web/app/components/plugins/plugin-page/filter-management/category-filter.tsx index fa6540c4bf..7c3417eec3 100644 --- a/web/app/components/plugins/plugin-page/filter-management/category-filter.tsx +++ b/web/app/components/plugins/plugin-page/filter-management/category-filter.tsx @@ -56,7 +56,7 @@ const CategoriesFilter = ({ 'flex items-center p-1 system-sm-medium', )}> { - !selectedTagsLength && t('pluginCategories.allCategories') + !selectedTagsLength && t('plugin.allCategories') } { !!selectedTagsLength && value.map(val => categoriesMap[val].label).slice(0, 2).join(',') @@ -96,7 +96,7 @@ const CategoriesFilter = ({ showLeftIcon value={searchText} onChange={e => setSearchText(e.target.value)} - placeholder={t('pluginCategories.searchCategories')} + placeholder={t('plugin.searchCategories')} />
diff --git a/web/i18n/de-DE/plugin-categories.ts b/web/i18n/de-DE/plugin-categories.ts deleted file mode 100644 index 928649474b..0000000000 --- a/web/i18n/de-DE/plugin-categories.ts +++ /dev/null @@ -1,4 +0,0 @@ -const translation = { -} - -export default translation diff --git a/web/i18n/en-US/plugin-categories.ts b/web/i18n/en-US/plugin-categories.ts deleted file mode 100644 index 6ee5b76c25..0000000000 --- a/web/i18n/en-US/plugin-categories.ts +++ /dev/null @@ -1,12 +0,0 @@ -const translation = { - allCategories: 'All Categories', - searchCategories: 'Search categories', - categories: { - model: 'Model', - tool: 'Tool', - extension: 'Extension', - bundle: 'Bundle', - }, -} - -export default translation diff --git a/web/i18n/en-US/plugin.ts b/web/i18n/en-US/plugin.ts index 3784309c09..91f17e07f3 100644 --- a/web/i18n/en-US/plugin.ts +++ b/web/i18n/en-US/plugin.ts @@ -1,12 +1,14 @@ const translation = { category: { all: 'All', - models: 'models', - tools: 'tools', - extensions: 'extensions', - bundles: 'bundles', + models: 'Models', + tools: 'Tools', + extensions: 'Extensions', + bundles: 'Bundles', }, search: 'Search', + allCategories: 'All Categories', + searchCategories: 'Search Categories', searchPlugins: 'Search plugins', from: 'From', findMoreInMarketplace: 'Find more in Marketplace', diff --git a/web/i18n/es-ES/plugin-categories.ts b/web/i18n/es-ES/plugin-categories.ts deleted file mode 100644 index 928649474b..0000000000 --- a/web/i18n/es-ES/plugin-categories.ts +++ /dev/null @@ -1,4 +0,0 @@ -const translation = { -} - -export default translation diff --git a/web/i18n/fa-IR/plugin-categories.ts b/web/i18n/fa-IR/plugin-categories.ts deleted file mode 100644 index 928649474b..0000000000 --- a/web/i18n/fa-IR/plugin-categories.ts +++ /dev/null @@ -1,4 +0,0 @@ -const translation = { -} - -export default translation diff --git a/web/i18n/fr-FR/plugin-categories.ts b/web/i18n/fr-FR/plugin-categories.ts deleted file mode 100644 index 928649474b..0000000000 --- a/web/i18n/fr-FR/plugin-categories.ts +++ /dev/null @@ -1,4 +0,0 @@ -const translation = { -} - -export default translation diff --git a/web/i18n/hi-IN/plugin-categories.ts b/web/i18n/hi-IN/plugin-categories.ts deleted file mode 100644 index 928649474b..0000000000 --- a/web/i18n/hi-IN/plugin-categories.ts +++ /dev/null @@ -1,4 +0,0 @@ -const translation = { -} - -export default translation diff --git a/web/i18n/i18next-config.ts b/web/i18n/i18next-config.ts index 9b35cd5432..bbba4c7c35 100644 --- a/web/i18n/i18next-config.ts +++ b/web/i18n/i18next-config.ts @@ -30,7 +30,6 @@ const loadLangResources = (lang: string) => ({ runLog: require(`./${lang}/run-log`).default, plugin: require(`./${lang}/plugin`).default, pluginTags: require(`./${lang}/plugin-tags`).default, - pluginCategories: require(`./${lang}/plugin-categories`).default, }, }) diff --git a/web/i18n/it-IT/plugin-categories.ts b/web/i18n/it-IT/plugin-categories.ts deleted file mode 100644 index 928649474b..0000000000 --- a/web/i18n/it-IT/plugin-categories.ts +++ /dev/null @@ -1,4 +0,0 @@ -const translation = { -} - -export default translation diff --git a/web/i18n/ja-JP/plugin-categories.ts b/web/i18n/ja-JP/plugin-categories.ts deleted file mode 100644 index 928649474b..0000000000 --- a/web/i18n/ja-JP/plugin-categories.ts +++ /dev/null @@ -1,4 +0,0 @@ -const translation = { -} - -export default translation diff --git a/web/i18n/ko-KR/plugin-categories.ts b/web/i18n/ko-KR/plugin-categories.ts deleted file mode 100644 index 928649474b..0000000000 --- a/web/i18n/ko-KR/plugin-categories.ts +++ /dev/null @@ -1,4 +0,0 @@ -const translation = { -} - -export default translation diff --git a/web/i18n/pl-PL/plugin-categories.ts b/web/i18n/pl-PL/plugin-categories.ts deleted file mode 100644 index 928649474b..0000000000 --- a/web/i18n/pl-PL/plugin-categories.ts +++ /dev/null @@ -1,4 +0,0 @@ -const translation = { -} - -export default translation diff --git a/web/i18n/pt-BR/plugin-categories.ts b/web/i18n/pt-BR/plugin-categories.ts deleted file mode 100644 index 928649474b..0000000000 --- a/web/i18n/pt-BR/plugin-categories.ts +++ /dev/null @@ -1,4 +0,0 @@ -const translation = { -} - -export default translation diff --git a/web/i18n/ro-RO/plugin-categories.ts b/web/i18n/ro-RO/plugin-categories.ts deleted file mode 100644 index 928649474b..0000000000 --- a/web/i18n/ro-RO/plugin-categories.ts +++ /dev/null @@ -1,4 +0,0 @@ -const translation = { -} - -export default translation diff --git a/web/i18n/ru-RU/plugin-categories.ts b/web/i18n/ru-RU/plugin-categories.ts deleted file mode 100644 index 928649474b..0000000000 --- a/web/i18n/ru-RU/plugin-categories.ts +++ /dev/null @@ -1,4 +0,0 @@ -const translation = { -} - -export default translation diff --git a/web/i18n/tr-TR/plugin-categories.ts b/web/i18n/tr-TR/plugin-categories.ts deleted file mode 100644 index 928649474b..0000000000 --- a/web/i18n/tr-TR/plugin-categories.ts +++ /dev/null @@ -1,4 +0,0 @@ -const translation = { -} - -export default translation diff --git a/web/i18n/uk-UA/plugin-categories.ts b/web/i18n/uk-UA/plugin-categories.ts deleted file mode 100644 index 928649474b..0000000000 --- a/web/i18n/uk-UA/plugin-categories.ts +++ /dev/null @@ -1,4 +0,0 @@ -const translation = { -} - -export default translation diff --git a/web/i18n/vi-VN/plugin-categories.ts b/web/i18n/vi-VN/plugin-categories.ts deleted file mode 100644 index 928649474b..0000000000 --- a/web/i18n/vi-VN/plugin-categories.ts +++ /dev/null @@ -1,4 +0,0 @@ -const translation = { -} - -export default translation diff --git a/web/i18n/zh-Hans/plugin-categories.ts b/web/i18n/zh-Hans/plugin-categories.ts deleted file mode 100644 index fb08e8ad87..0000000000 --- a/web/i18n/zh-Hans/plugin-categories.ts +++ /dev/null @@ -1,12 +0,0 @@ -const translation = { - allCategories: '所有类型', - searchCategories: '搜索类型', - categories: { - model: '模型', - tool: '工具', - extension: '扩展', - bundle: '捆绑包', - }, -} - -export default translation diff --git a/web/i18n/zh-Hans/plugin.ts b/web/i18n/zh-Hans/plugin.ts index 2e835bbfab..30de7acced 100644 --- a/web/i18n/zh-Hans/plugin.ts +++ b/web/i18n/zh-Hans/plugin.ts @@ -7,6 +7,8 @@ const translation = { bundles: '捆绑包', }, search: '搜索', + allCategories: '所有类别', + searchCategories: '搜索类别', searchPlugins: '搜索插件', from: '来自', findMoreInMarketplace: '在 Marketplace 中查找更多', diff --git a/web/i18n/zh-Hant/plugin-categories.ts b/web/i18n/zh-Hant/plugin-categories.ts deleted file mode 100644 index 928649474b..0000000000 --- a/web/i18n/zh-Hant/plugin-categories.ts +++ /dev/null @@ -1,4 +0,0 @@ -const translation = { -} - -export default translation From fa6858090bf704a023edf5be3a11f7971f5fece0 Mon Sep 17 00:00:00 2001 From: twwu Date: Wed, 13 Nov 2024 18:34:04 +0800 Subject: [PATCH 46/68] refactor: remove version prop from plugin item components and update version comparison logic --- web/app/components/plugins/plugin-item/action.tsx | 4 +--- web/app/components/plugins/plugin-item/index.tsx | 2 -- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/web/app/components/plugins/plugin-item/action.tsx b/web/app/components/plugins/plugin-item/action.tsx index 80c5c5e78a..52c8c10309 100644 --- a/web/app/components/plugins/plugin-item/action.tsx +++ b/web/app/components/plugins/plugin-item/action.tsx @@ -23,7 +23,6 @@ type Props = { installationId: string pluginUniqueIdentifier: string pluginName: string - version: string usedInApps: number isShowFetchNewVersion: boolean isShowInfo: boolean @@ -36,7 +35,6 @@ const Action: FC = ({ installationId, pluginUniqueIdentifier, pluginName, - version, isShowFetchNewVersion, isShowInfo, isShowDelete, @@ -63,7 +61,7 @@ const Action: FC = ({ return const versions = fetchedReleases.map(release => release.tag_name) const latestVersion = getLatestVersion(versions) - if (compareVersion(latestVersion, version) === 1) { + if (compareVersion(latestVersion, meta!.version) === 1) { setShowUpdatePluginModal({ onSaveCallback: () => { invalidateInstalledPluginList() diff --git a/web/app/components/plugins/plugin-item/index.tsx b/web/app/components/plugins/plugin-item/index.tsx index aaa64b87a5..4ac2c80d7d 100644 --- a/web/app/components/plugins/plugin-item/index.tsx +++ b/web/app/components/plugins/plugin-item/index.tsx @@ -48,7 +48,6 @@ const PluginItem: FC = ({ endpoints_active, meta, plugin_id, - version, } = plugin const { category, author, name, label, description, icon, verified } = plugin.declaration @@ -93,7 +92,6 @@ const PluginItem: FC = ({ installationId={installation_id} author={author} pluginName={name} - version={version} usedInApps={5} isShowFetchNewVersion={source === PluginSource.github} isShowInfo={source === PluginSource.github} From 93e3077f77bd7060b3b4748d2935b71f00e8be85 Mon Sep 17 00:00:00 2001 From: Yi Date: Wed, 13 Nov 2024 18:40:11 +0800 Subject: [PATCH 47/68] chore: update the esc button and the upgrade button --- .../components/base/premium-badge/index.tsx | 2 +- .../components/billing/upgrade-btn/index.tsx | 32 ++++----- .../header/account-setting/index.tsx | 69 +++++++++++-------- .../header/account-setting/menu-dialog.tsx | 14 ---- web/app/components/header/index.tsx | 6 +- 5 files changed, 60 insertions(+), 63 deletions(-) diff --git a/web/app/components/base/premium-badge/index.tsx b/web/app/components/base/premium-badge/index.tsx index 1af527cd16..ce260fcf80 100644 --- a/web/app/components/base/premium-badge/index.tsx +++ b/web/app/components/base/premium-badge/index.tsx @@ -53,7 +53,7 @@ const PremiumBadge: React.FC = ({
v const UpgradeBtn: FC = ({ className, isPlain = false, - isFull = false, isShort = false, - size = 'md', onClick: _onClick, loc, }) => { @@ -63,22 +60,19 @@ const UpgradeBtn: FC = ({ return return ( -
- -
{t(`billing.upgradeBtn.${isShort ? 'encourageShort' : 'encourage'}`)}
- -
+ +
+ + {t(`billing.upgradeBtn.${isShort ? 'encourageShort' : 'encourage'}`)} + +
+ ) } export default React.memo(UpgradeBtn) diff --git a/web/app/components/header/account-setting/index.tsx b/web/app/components/header/account-setting/index.tsx index 9df7065733..b8d265c263 100644 --- a/web/app/components/header/account-setting/index.tsx +++ b/web/app/components/header/account-setting/index.tsx @@ -4,6 +4,7 @@ import { useEffect, useRef, useState } from 'react' import { RiBrain2Fill, RiBrain2Line, + RiCloseLine, RiColorFilterFill, RiColorFilterLine, RiDatabase2Fill, @@ -16,6 +17,7 @@ import { RiPuzzle2Line, RiTranslate2, } from '@remixicon/react' +import Button from '../../base/button' import MembersPage from './members-page' import LanguagePage from './language-page' import ApiBasedExtensionPage from './api-based-extension-page' @@ -178,34 +180,47 @@ export default function AccountSetting({ }
-
-
-
{activeItem?.name}
- { - activeItem?.description && ( -
{activeItem?.description}
- ) - } - {activeItem?.key === 'provider' && ( -
- setSearchValue(e.target.value)} - value={searchValue} - /> -
- )} +
+
+ +
ESC
-
- {activeMenu === 'provider' && } - {activeMenu === 'members' && } - {activeMenu === 'billing' && } - {activeMenu === 'data-source' && } - {activeMenu === 'api-based-extension' && } - {activeMenu === 'custom' && } - {activeMenu === 'language' && } +
+
+
{activeItem?.name}
+ { + activeItem?.description && ( +
{activeItem?.description}
+ ) + } + {activeItem?.key === 'provider' && ( +
+ setSearchValue(e.target.value)} + value={searchValue} + /> +
+ )} +
+
+ {activeMenu === 'provider' && } + {activeMenu === 'members' && } + {activeMenu === 'billing' && } + {activeMenu === 'data-source' && } + {activeMenu === 'api-based-extension' && } + {activeMenu === 'custom' && } + {activeMenu === 'language' && } +
diff --git a/web/app/components/header/account-setting/menu-dialog.tsx b/web/app/components/header/account-setting/menu-dialog.tsx index 19639488da..3db8475c51 100644 --- a/web/app/components/header/account-setting/menu-dialog.tsx +++ b/web/app/components/header/account-setting/menu-dialog.tsx @@ -1,8 +1,6 @@ import { Fragment, useCallback, useEffect } from 'react' import type { ReactNode } from 'react' -import { RiCloseLine } from '@remixicon/react' import { Dialog, Transition } from '@headlessui/react' -import Button from '@/app/components/base/button' import cn from '@/utils/classnames' type DialogProps = { @@ -47,18 +45,6 @@ const MenuDialog = ({ leaveTo="opacity-0 scale-95" > -
-
- -
ESC
-
{children} diff --git a/web/app/components/header/index.tsx b/web/app/components/header/index.tsx index c6befcc0d9..425834d7b9 100644 --- a/web/app/components/header/index.tsx +++ b/web/app/components/header/index.tsx @@ -21,6 +21,7 @@ import WorkplaceSelector from '@/app/components/header/account-dropdown/workplac import useBreakpoints, { MediaType } from '@/hooks/use-breakpoints' import { useProviderContext } from '@/context/provider-context' import { useModalContext } from '@/context/modal-context' +import { useTranslation } from 'react-i18next' const navClassName = ` flex items-center relative mr-0 sm:mr-3 px-3 h-8 rounded-xl @@ -30,6 +31,7 @@ const navClassName = ` const Header = () => { const { isCurrentWorkspaceEditor, isCurrentWorkspaceDatasetOperator } = useAppContext() + const { t } = useTranslation() const selectedSegment = useSelectedLayoutSegment() const media = useBreakpoints() @@ -74,7 +76,7 @@ const Header = () => {
- Upgrade + {t('billing.upgradeBtn.encourage')}
@@ -96,7 +98,7 @@ const Header = () => {
- Upgrade + {t('billing.upgradeBtn.encourage')}
From 2fbc0c2261e1d8062916e41d46921964a7078bfb Mon Sep 17 00:00:00 2001 From: twwu Date: Wed, 13 Nov 2024 18:40:23 +0800 Subject: [PATCH 48/68] revert: revert category label handling in plugin card component --- web/app/components/plugins/card/index.tsx | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/web/app/components/plugins/card/index.tsx b/web/app/components/plugins/card/index.tsx index 1e4cc5e28b..b262727506 100644 --- a/web/app/components/plugins/card/index.tsx +++ b/web/app/components/plugins/card/index.tsx @@ -11,7 +11,6 @@ import Placeholder from './base/placeholder' import cn from '@/utils/classnames' import { useGetLanguage } from '@/context/i18n' import { getLanguage } from '@/i18n/language' -import { useCategories } from '../hooks' export type Props = { className?: string @@ -42,7 +41,6 @@ const Card = ({ }: Props) => { const defaultLocale = useGetLanguage() const locale = localeFromProps ? getLanguage(localeFromProps) : defaultLocale - const { categoriesMap } = useCategories() const { type, name, org, label, brief, icon, verified } = payload @@ -61,7 +59,7 @@ const Card = ({ return (
- {!hideCornerMark && } + {!hideCornerMark && } {/* Header */}
From 926f85ce4fb342750ceed6c80e6943a05d44eff7 Mon Sep 17 00:00:00 2001 From: JzoNg Date: Wed, 13 Nov 2024 16:43:43 +0800 Subject: [PATCH 49/68] tool selector trigger --- .../model-provider-page/model-modal/Form.tsx | 2 +- .../model-provider-page/model-modal/Input.tsx | 4 +- .../plugin-detail-panel/endpoint-modal.tsx | 9 +- .../components/tools/tool-selector/index.tsx | 111 ++++++++++++++++++ .../tools/tool-selector/tool-trigger.tsx | 45 +++++++ .../workflow/block-selector/tool-picker.tsx | 1 - .../block-selector/tool/action-item.tsx | 3 +- 7 files changed, 168 insertions(+), 7 deletions(-) create mode 100644 web/app/components/tools/tool-selector/index.tsx create mode 100644 web/app/components/tools/tool-selector/tool-trigger.tsx diff --git a/web/app/components/header/account-setting/model-provider-page/model-modal/Form.tsx b/web/app/components/header/account-setting/model-provider-page/model-modal/Form.tsx index 90d0688db0..b1788b89bc 100644 --- a/web/app/components/header/account-setting/model-provider-page/model-modal/Form.tsx +++ b/web/app/components/header/account-setting/model-provider-page/model-modal/Form.tsx @@ -73,7 +73,7 @@ const Form: FC = ({ const newValue = { ...value[key], provider: model.provider, - name: model.modelId, + model: model.modelId, mode: model.mode, } onChange({ ...value, [key]: newValue }) diff --git a/web/app/components/header/account-setting/model-provider-page/model-modal/Input.tsx b/web/app/components/header/account-setting/model-provider-page/model-modal/Input.tsx index ee9d75becc..041b44a507 100644 --- a/web/app/components/header/account-setting/model-provider-page/model-modal/Input.tsx +++ b/web/app/components/header/account-setting/model-provider-page/model-modal/Input.tsx @@ -41,9 +41,9 @@ const Input: FC = ({ = ({ onSaved(tempCredential) } + const [mockTool, setTool] = useState() + return ( = ({ isEditMode={true} showOnVariableMap={{}} validating={false} - inputClassName='!bg-gray-50' + inputClassName='bg-components-input-bg-normal hover:bg-state-base-hover-alt' fieldMoreInfo={item => item.url ? ( = ({ ) : null} /> +
diff --git a/web/app/components/tools/tool-selector/index.tsx b/web/app/components/tools/tool-selector/index.tsx new file mode 100644 index 0000000000..af78695740 --- /dev/null +++ b/web/app/components/tools/tool-selector/index.tsx @@ -0,0 +1,111 @@ +'use client' +import type { FC } from 'react' +import React, { useMemo, useState } from 'react' +import { useTranslation } from 'react-i18next' +import { + PortalToFollowElem, + PortalToFollowElemContent, + PortalToFollowElemTrigger, +} from '@/app/components/base/portal-to-follow-elem' +import ToolTrigger from '@/app/components/tools/tool-selector/tool-trigger' +import ToolPicker from '@/app/components/workflow/block-selector/tool-picker' + +import { useAllBuiltInTools, useAllCustomTools, useAllWorkflowTools } from '@/service/use-tools' +// import AddToolModal from '@/app/components/tools/add-tool-modal' +import type { ToolDefaultValue } from '@/app/components/workflow/block-selector/types' +import type { + OffsetOptions, + Placement, +} from '@floating-ui/react' + +type Props = { + value?: { + provider: string + tool_name: string + } + disabled: boolean + placement?: Placement + offset?: OffsetOptions + onSelect: (tool: { + provider: string + tool_name: string + }) => void + supportAddCustomTool?: boolean +} +const ToolSelector: FC = ({ + value, + disabled, + placement = 'bottom', + offset = 0, + onSelect, +}) => { + const { t } = useTranslation() + const [isShow, onShowChange] = useState(false) + const handleTriggerClick = () => { + if (disabled) return + onShowChange(true) + } + const { data: buildInTools } = useAllBuiltInTools() + const { data: customTools } = useAllCustomTools() + const { data: workflowTools } = useAllWorkflowTools() + const currentProvider = useMemo(() => { + const mergedTools = [...(buildInTools || []), ...(customTools || []), ...(workflowTools || [])] + return mergedTools.find((toolWithProvider) => { + return toolWithProvider.id === value?.provider && toolWithProvider.tools.some(tool => tool.name === value?.tool_name) + }) + }, [value, buildInTools, customTools, workflowTools]) + const [isShowChooseTool, setIsShowChooseTool] = useState(false) + const [isShowSettingAuth, setShowSettingAuth] = useState(false) + + const handleToolAuthSetting = (value: any) => { + // const newModelConfig = produce(modelConfig, (draft) => { + // const tool = (draft.agentConfig.tools).find((item: any) => item.provider_id === value?.collection?.id && item.tool_name === value?.tool_name) + // if (tool) + // (tool as AgentTool).notAuthor = false + // }) + // setModelConfig(newModelConfig) + } + + const handleSelectTool = (tool: ToolDefaultValue) => { + const toolValue = { + provider: tool.provider_id, + tool_name: tool.tool_name, + } + onSelect(toolValue) + } + + return ( + <> + + + + + +
+
+
Tool
+ } + isShow={isShowChooseTool} + onShowChange={setIsShowChooseTool} + disabled={false} + supportAddCustomTool + onSelect={handleSelectTool} + /> +
+
+
+
+ + ) +} +export default React.memo(ToolSelector) diff --git a/web/app/components/tools/tool-selector/tool-trigger.tsx b/web/app/components/tools/tool-selector/tool-trigger.tsx new file mode 100644 index 0000000000..79efa4a06a --- /dev/null +++ b/web/app/components/tools/tool-selector/tool-trigger.tsx @@ -0,0 +1,45 @@ +'use client' +import React from 'react' +import { + RiArrowDownSLine, +} from '@remixicon/react' +import BlockIcon from '@/app/components/workflow/block-icon' +import { BlockEnum } from '@/app/components/workflow/types' +import type { ToolWithProvider } from '@/app/components/workflow/types' +import cn from '@/utils/classnames' + +type Props = { + open: boolean + provider?: ToolWithProvider + value?: { + provider: string + tool_name: string + } +} + +const ToolTrigger = ({ + open, + provider, + value, +}: Props) => { + return ( +
+ {value && provider && ( + + )} + {value && ( +
{value.tool_name}
+ )} + {!value && ( +
Select a tool ...
+ )} + +
+ ) +} + +export default ToolTrigger diff --git a/web/app/components/workflow/block-selector/tool-picker.tsx b/web/app/components/workflow/block-selector/tool-picker.tsx index 44f7c73e80..1990c6daca 100644 --- a/web/app/components/workflow/block-selector/tool-picker.tsx +++ b/web/app/components/workflow/block-selector/tool-picker.tsx @@ -106,7 +106,6 @@ const ToolPicker: FC = ({ - { }
void + onSelect: (type: BlockEnum, tool?: ToolDefaultValue & { is_team_authorization: boolean }) => void } const ToolItem: FC = ({ @@ -57,6 +57,7 @@ const ToolItem: FC = ({ tool_name: payload.name, tool_label: payload.label[language], title: payload.label[language], + is_team_authorization: provider.is_team_authorization, params, }) }} From 194a99220be256e69a18672e9212946bec2c5d0e Mon Sep 17 00:00:00 2001 From: JzoNg Date: Wed, 13 Nov 2024 23:28:55 +0800 Subject: [PATCH 50/68] authorization of tool selector --- .../config/agent/agent-tools/index.tsx | 2 +- .../model-provider-page/model-modal/Form.tsx | 10 +-- .../plugin-detail-panel/endpoint-modal.tsx | 5 +- .../components/tools/tool-selector/index.tsx | 85 +++++++++++++++---- .../tools/tool-selector/tool-trigger.tsx | 24 ++++-- .../workflow/block-selector/tool-picker.tsx | 2 +- .../block-selector/tool/action-item.tsx | 2 +- .../workflow/block-selector/types.ts | 1 + web/i18n/en-US/tools.ts | 5 ++ web/i18n/zh-Hans/tools.ts | 4 + 10 files changed, 107 insertions(+), 33 deletions(-) diff --git a/web/app/components/app/configuration/config/agent/agent-tools/index.tsx b/web/app/components/app/configuration/config/agent/agent-tools/index.tsx index d83fcb3637..35cee8eefc 100644 --- a/web/app/components/app/configuration/config/agent/agent-tools/index.tsx +++ b/web/app/components/app/configuration/config/agent/agent-tools/index.tsx @@ -92,7 +92,7 @@ const AgentTools: FC = () => { tool_name: tool.tool_name, tool_label: tool.tool_label, tool_parameters: tool.params, - notAuthor: !(tool as ToolDefaultValue & { is_team_authorization: boolean }).is_team_authorization, + notAuthor: !tool.is_team_authorization, enabled: true, }) }) diff --git a/web/app/components/header/account-setting/model-provider-page/model-modal/Form.tsx b/web/app/components/header/account-setting/model-provider-page/model-modal/Form.tsx index b1788b89bc..e6ce15d696 100644 --- a/web/app/components/header/account-setting/model-provider-page/model-modal/Form.tsx +++ b/web/app/components/header/account-setting/model-provider-page/model-modal/Form.tsx @@ -114,7 +114,7 @@ const Form: FC = ({ const disabled = readonly || (isEditMode && (variable === '__model_type' || variable === '__model_name')) return (
-
+
{label[language] || label.en_US} { required && ( @@ -155,7 +155,7 @@ const Form: FC = ({ return (
-
+
{label[language] || label.en_US} { required && ( @@ -211,7 +211,7 @@ const Form: FC = ({ return (
-
+
{label[language] || label.en_US} { @@ -254,7 +254,7 @@ const Form: FC = ({ return (
-
+
{label[language] || label.en_US} { @@ -287,7 +287,7 @@ const Form: FC = ({ return (
-
+
{label[language] || label.en_US} { required && ( diff --git a/web/app/components/plugins/plugin-detail-panel/endpoint-modal.tsx b/web/app/components/plugins/plugin-detail-panel/endpoint-modal.tsx index 63b580429f..342b66e948 100644 --- a/web/app/components/plugins/plugin-detail-panel/endpoint-modal.tsx +++ b/web/app/components/plugins/plugin-detail-panel/endpoint-modal.tsx @@ -40,7 +40,10 @@ const EndpointModal: FC = ({ onSaved(tempCredential) } - const [mockTool, setTool] = useState() + const [mockTool, setTool] = useState({ + provider: 'langgenius/google/google', + tool_name: 'google_search', + }) return ( = ({ value, disabled, placement = 'bottom', - offset = 0, + offset = 4, onSelect, }) => { const { t } = useTranslation() @@ -45,6 +50,7 @@ const ToolSelector: FC = ({ if (disabled) return onShowChange(true) } + const { data: buildInTools } = useAllBuiltInTools() const { data: customTools } = useAllCustomTools() const { data: workflowTools } = useAllWorkflowTools() @@ -55,24 +61,29 @@ const ToolSelector: FC = ({ }) }, [value, buildInTools, customTools, workflowTools]) const [isShowChooseTool, setIsShowChooseTool] = useState(false) - const [isShowSettingAuth, setShowSettingAuth] = useState(false) - - const handleToolAuthSetting = (value: any) => { - // const newModelConfig = produce(modelConfig, (draft) => { - // const tool = (draft.agentConfig.tools).find((item: any) => item.provider_id === value?.collection?.id && item.tool_name === value?.tool_name) - // if (tool) - // (tool as AgentTool).notAuthor = false - // }) - // setModelConfig(newModelConfig) - } - const handleSelectTool = (tool: ToolDefaultValue) => { const toolValue = { provider: tool.provider_id, tool_name: tool.tool_name, } onSelect(toolValue) + setIsShowChooseTool(false) + if (tool.provider_type === CollectionType.builtIn && tool.is_team_authorization) + onShowChange(false) } + const { isCurrentWorkspaceManager } = useAppContext() + const [authLoading, setAuthLoading] = useState(false) + + // const [isShowSettingAuth, setShowSettingAuth] = useState(false) + + // const handleToolAuthSetting = (value: any) => { + // const newModelConfig = produce(modelConfig, (draft) => { + // const tool = (draft.agentConfig.tools).find((item: any) => item.provider_id === value?.collection?.id && item.tool_name === value?.tool_name) + // if (tool) + // (tool as AgentTool).notAuthor = false + // }) + // setModelConfig(newModelConfig) + // } return ( <> @@ -86,15 +97,26 @@ const ToolSelector: FC = ({ className='w-full' onClick={handleTriggerClick} > - +
-
Tool
+
{t('tools.toolSelector.label')}
} + offset={offset} + trigger={ + + } isShow={isShowChooseTool} onShowChange={setIsShowChooseTool} disabled={false} @@ -102,6 +124,37 @@ const ToolSelector: FC = ({ onSelect={handleSelectTool} />
+ {/* authorization panel */} + {authLoading && ( +
+ )} + {!authLoading && currentProvider && currentProvider.type === CollectionType.builtIn && currentProvider.is_team_authorization && currentProvider.allow_delete && ( +
+
{t('tools.toolSelector.auth')}
+ {isCurrentWorkspaceManager && ( + + )} +
+ )} + {!authLoading && currentProvider && currentProvider.type === CollectionType.builtIn && !currentProvider.is_team_authorization && currentProvider.allow_delete && ( +
+ +
+ )}
diff --git a/web/app/components/tools/tool-selector/tool-trigger.tsx b/web/app/components/tools/tool-selector/tool-trigger.tsx index 79efa4a06a..e481448bcd 100644 --- a/web/app/components/tools/tool-selector/tool-trigger.tsx +++ b/web/app/components/tools/tool-selector/tool-trigger.tsx @@ -1,5 +1,6 @@ 'use client' import React from 'react' +import { useTranslation } from 'react-i18next' import { RiArrowDownSLine, } from '@remixicon/react' @@ -22,20 +23,27 @@ const ToolTrigger = ({ provider, value, }: Props) => { + const { t } = useTranslation() return ( -
+
{value && provider && ( - +
+ +
)} {value && ( -
{value.tool_name}
+
{value.tool_name}
)} {!value && ( -
Select a tool ...
+
{t('tools.toolSelector.placeholder')}
)}
diff --git a/web/app/components/workflow/block-selector/tool-picker.tsx b/web/app/components/workflow/block-selector/tool-picker.tsx index 1990c6daca..60de09d3e6 100644 --- a/web/app/components/workflow/block-selector/tool-picker.tsx +++ b/web/app/components/workflow/block-selector/tool-picker.tsx @@ -106,7 +106,7 @@ const ToolPicker: FC = ({ -
+
void + onSelect: (type: BlockEnum, tool?: ToolDefaultValue) => void } const ToolItem: FC = ({ diff --git a/web/app/components/workflow/block-selector/types.ts b/web/app/components/workflow/block-selector/types.ts index 9bdbf5cb3c..ffe6cc627c 100644 --- a/web/app/components/workflow/block-selector/types.ts +++ b/web/app/components/workflow/block-selector/types.ts @@ -25,5 +25,6 @@ export type ToolDefaultValue = { tool_name: string tool_label: string title: string + is_team_authorization: boolean params: Record } diff --git a/web/i18n/en-US/tools.ts b/web/i18n/en-US/tools.ts index 9c2d22b711..37250473d6 100644 --- a/web/i18n/en-US/tools.ts +++ b/web/i18n/en-US/tools.ts @@ -149,6 +149,11 @@ const translation = { openInStudio: 'Open in Studio', toolNameUsageTip: 'Tool call name for agent reasoning and prompting', copyToolName: 'Copy Name', + toolSelector: { + label: 'TOOL', + placeholder: 'Select a tool...', + auth: 'AUTHORIZATION', + }, } export default translation diff --git a/web/i18n/zh-Hans/tools.ts b/web/i18n/zh-Hans/tools.ts index fa1e8344a7..f3ec76aa97 100644 --- a/web/i18n/zh-Hans/tools.ts +++ b/web/i18n/zh-Hans/tools.ts @@ -149,6 +149,10 @@ const translation = { openInStudio: '在工作室中打开', toolNameUsageTip: '工具调用名称,用于 Agent 推理和提示词', copyToolName: '复制名称', + toolSelector: { + label: '工具', + placeholder: '选择一个工具...', + }, } export default translation From ff1d42bd66ffba553be466d95668a87d4f00b7a6 Mon Sep 17 00:00:00 2001 From: JzoNg Date: Thu, 14 Nov 2024 00:01:47 +0800 Subject: [PATCH 51/68] add tool selector in endpoint modal --- .../model-provider-page/model-modal/Form.tsx | 28 +++++- .../plugin-detail-panel/endpoint-modal.tsx | 10 +- .../components/tools/tool-selector/index.tsx | 54 +++++++---- .../tool-selector/tool-credentials-form.tsx | 95 +++++++++++++++++++ 4 files changed, 158 insertions(+), 29 deletions(-) create mode 100644 web/app/components/tools/tool-selector/tool-credentials-form.tsx diff --git a/web/app/components/header/account-setting/model-provider-page/model-modal/Form.tsx b/web/app/components/header/account-setting/model-provider-page/model-modal/Form.tsx index e6ce15d696..cef2146daa 100644 --- a/web/app/components/header/account-setting/model-provider-page/model-modal/Form.tsx +++ b/web/app/components/header/account-setting/model-provider-page/model-modal/Form.tsx @@ -18,6 +18,7 @@ import { SimpleSelect } from '@/app/components/base/select' import Tooltip from '@/app/components/base/tooltip' import Radio from '@/app/components/base/radio' import ModelParameterModal from '@/app/components/header/account-setting/model-provider-page/model-parameter-modal' +import ToolSelector from '@/app/components/tools/tool-selector' type FormProps = { className?: string @@ -317,7 +318,32 @@ const Form: FC = ({ } if (formSchema.type === FormTypeEnum.toolSelector) { - // TODO + const { + variable, + label, + required, + } = formSchema as (CredentialFormSchemaTextInput | CredentialFormSchemaSecretInput) + + return ( +
+
+ {label[language] || label.en_US} + { + required && ( + * + ) + } + {tooltipContent} +
+ handleFormChange(variable, item as any)} + /> + {fieldMoreInfo?.(formSchema)} + {validating && changeKey === variable && } +
+ ) } if (formSchema.type === FormTypeEnum.appSelector) { diff --git a/web/app/components/plugins/plugin-detail-panel/endpoint-modal.tsx b/web/app/components/plugins/plugin-detail-panel/endpoint-modal.tsx index 342b66e948..ca4813d3c6 100644 --- a/web/app/components/plugins/plugin-detail-panel/endpoint-modal.tsx +++ b/web/app/components/plugins/plugin-detail-panel/endpoint-modal.tsx @@ -1,6 +1,6 @@ 'use client' import type { FC } from 'react' -import React, { useState } from 'react' +import React from 'react' import { useTranslation } from 'react-i18next' import { RiArrowRightUpLine, RiCloseLine } from '@remixicon/react' import ActionButton from '@/app/components/base/action-button' @@ -11,8 +11,6 @@ import Toast from '@/app/components/base/toast' import { useLanguage } from '@/app/components/header/account-setting/model-provider-page/hooks' import cn from '@/utils/classnames' -import ToolSelector from '@/app/components/tools/tool-selector' - type Props = { formSchemas: any defaultValues?: any @@ -40,11 +38,6 @@ const EndpointModal: FC = ({ onSaved(tempCredential) } - const [mockTool, setTool] = useState({ - provider: 'langgenius/google/google', - tool_name: 'google_search', - }) - return ( = ({ ) : null} /> -
diff --git a/web/app/components/tools/tool-selector/index.tsx b/web/app/components/tools/tool-selector/index.tsx index 2689abbbc6..75b02698de 100644 --- a/web/app/components/tools/tool-selector/index.tsx +++ b/web/app/components/tools/tool-selector/index.tsx @@ -9,12 +9,18 @@ import { } from '@/app/components/base/portal-to-follow-elem' import ToolTrigger from '@/app/components/tools/tool-selector/tool-trigger' import ToolPicker from '@/app/components/workflow/block-selector/tool-picker' -import Loading from '@/app/components/base/loading' import Button from '@/app/components/base/button' import Indicator from '@/app/components/header/indicator' +import ToolCredentialForm from '@/app/components/tools/tool-selector/tool-credentials-form' +import Toast from '@/app/components/base/toast' import { useAppContext } from '@/context/app-context' -import { useAllBuiltInTools, useAllCustomTools, useAllWorkflowTools } from '@/service/use-tools' +import { + useAllBuiltInTools, + useAllCustomTools, + useAllWorkflowTools, + useUpdateProviderCredentials, +} from '@/service/use-tools' import { CollectionType } from '@/app/components/tools/types' import type { ToolDefaultValue } from '@/app/components/workflow/block-selector/types' import type { @@ -28,7 +34,7 @@ type Props = { provider: string tool_name: string } - disabled: boolean + disabled?: boolean placement?: Placement offset?: OffsetOptions onSelect: (tool: { @@ -72,18 +78,19 @@ const ToolSelector: FC = ({ onShowChange(false) } const { isCurrentWorkspaceManager } = useAppContext() - const [authLoading, setAuthLoading] = useState(false) + const [isShowSettingAuth, setShowSettingAuth] = useState(false) + const handleCredentialSettingUpdate = () => { + Toast.notify({ + type: 'success', + message: t('common.api.actionSuccess'), + }) + setShowSettingAuth(false) + onShowChange(false) + } - // const [isShowSettingAuth, setShowSettingAuth] = useState(false) - - // const handleToolAuthSetting = (value: any) => { - // const newModelConfig = produce(modelConfig, (draft) => { - // const tool = (draft.agentConfig.tools).find((item: any) => item.provider_id === value?.collection?.id && item.tool_name === value?.tool_name) - // if (tool) - // (tool as AgentTool).notAuthor = false - // }) - // setModelConfig(newModelConfig) - // } + const { mutate: updatePermission } = useUpdateProviderCredentials({ + onSuccess: handleCredentialSettingUpdate, + }) return ( <> @@ -125,10 +132,19 @@ const ToolSelector: FC = ({ />
{/* authorization panel */} - {authLoading && ( -
+ {isShowSettingAuth && currentProvider && ( +
+ setShowSettingAuth(false)} + onSaved={async value => updatePermission({ + providerName: currentProvider.name, + credentials: value, + })} + /> +
)} - {!authLoading && currentProvider && currentProvider.type === CollectionType.builtIn && currentProvider.is_team_authorization && currentProvider.allow_delete && ( + {!isShowSettingAuth && currentProvider && currentProvider.type === CollectionType.builtIn && currentProvider.is_team_authorization && currentProvider.allow_delete && (
{t('tools.toolSelector.auth')}
{isCurrentWorkspaceManager && ( @@ -143,12 +159,12 @@ const ToolSelector: FC = ({ )}
)} - {!authLoading && currentProvider && currentProvider.type === CollectionType.builtIn && !currentProvider.is_team_authorization && currentProvider.allow_delete && ( + {!isShowSettingAuth && currentProvider && currentProvider.type === CollectionType.builtIn && !currentProvider.is_team_authorization && currentProvider.allow_delete && (
+ +
+
+ + ) + } + +
+ ) +} +export default React.memo(ToolCredentialForm) From 300cd675c6cdb695ff1e2d75c724eeb56f00cc9f Mon Sep 17 00:00:00 2001 From: JzoNg Date: Thu, 14 Nov 2024 00:04:06 +0800 Subject: [PATCH 52/68] update tool list after tool selector --- web/app/components/tools/tool-selector/index.tsx | 3 +++ 1 file changed, 3 insertions(+) diff --git a/web/app/components/tools/tool-selector/index.tsx b/web/app/components/tools/tool-selector/index.tsx index 75b02698de..0b13ab9bc2 100644 --- a/web/app/components/tools/tool-selector/index.tsx +++ b/web/app/components/tools/tool-selector/index.tsx @@ -19,6 +19,7 @@ import { useAllBuiltInTools, useAllCustomTools, useAllWorkflowTools, + useInvalidateAllBuiltInTools, useUpdateProviderCredentials, } from '@/service/use-tools' import { CollectionType } from '@/app/components/tools/types' @@ -60,6 +61,7 @@ const ToolSelector: FC = ({ const { data: buildInTools } = useAllBuiltInTools() const { data: customTools } = useAllCustomTools() const { data: workflowTools } = useAllWorkflowTools() + const invalidateAllBuiltinTools = useInvalidateAllBuiltInTools() const currentProvider = useMemo(() => { const mergedTools = [...(buildInTools || []), ...(customTools || []), ...(workflowTools || [])] return mergedTools.find((toolWithProvider) => { @@ -80,6 +82,7 @@ const ToolSelector: FC = ({ const { isCurrentWorkspaceManager } = useAppContext() const [isShowSettingAuth, setShowSettingAuth] = useState(false) const handleCredentialSettingUpdate = () => { + invalidateAllBuiltinTools() Toast.notify({ type: 'success', message: t('common.api.actionSuccess'), From 1aed0fe5d6657b06b037b28f38eeccdccac39b58 Mon Sep 17 00:00:00 2001 From: AkaraChen Date: Thu, 14 Nov 2024 11:04:41 +0800 Subject: [PATCH 53/68] chore: use mitt hook --- web/hooks/use-mitt.ts | 74 +++++++++++++++++++++++++++++++++++++++++++ web/package.json | 1 + web/pnpm-lock.yaml | 8 +++++ 3 files changed, 83 insertions(+) create mode 100644 web/hooks/use-mitt.ts diff --git a/web/hooks/use-mitt.ts b/web/hooks/use-mitt.ts new file mode 100644 index 0000000000..b9094bc262 --- /dev/null +++ b/web/hooks/use-mitt.ts @@ -0,0 +1,74 @@ +import type { Emitter, EventType, Handler, WildcardHandler } from 'mitt' +import create from 'mitt' +import { useEffect, useRef } from 'react' + +const merge = >( + ...args: Array +): T => { + return Object.assign({}, ...args) +} + +export type _Events = Record + +export type UseSubcribeOption = { + /** + * Whether the subscription is enabled. + * @default true + */ + enabled: boolean; +} + +export type ExtendedOn = { + ( + type: Key, + handler: Handler, + options?: UseSubcribeOption, + ): void; + ( + type: '*', + handler: WildcardHandler, + option?: UseSubcribeOption, + ): void; +} + +export type UseMittReturn = { + useSubcribe: ExtendedOn; + emit: Emitter['emit']; +} + +const defaultSubcribeOption: UseSubcribeOption = { + enabled: true, +} + +function useMitt( + mitt?: Emitter, +): UseMittReturn { + const emitterRef = useRef>() + if (!emitterRef.current) + emitterRef.current = mitt ?? create() + + if (mitt && emitterRef.current !== mitt) { + emitterRef.current.off('*') + emitterRef.current = mitt + } + const emitter = emitterRef.current + const useSubcribe: ExtendedOn = ( + type: string, + handler: any, + option?: UseSubcribeOption, + ) => { + const { enabled } = merge(defaultSubcribeOption, option) + useEffect(() => { + if (enabled) { + emitter.on(type, handler) + return () => emitter.off(type, handler) + } + }) + } + return { + emit: emitter.emit, + useSubcribe, + } +} + +export { useMitt } diff --git a/web/package.json b/web/package.json index 7cbe778790..22a704bdcb 100644 --- a/web/package.json +++ b/web/package.json @@ -70,6 +70,7 @@ "lodash-es": "^4.17.21", "mermaid": "10.9.3", "mime": "^4.0.4", + "mitt": "^3.0.1", "negotiator": "^0.6.3", "next": "^14.2.10", "pinyin-pro": "^3.25.0", diff --git a/web/pnpm-lock.yaml b/web/pnpm-lock.yaml index 5765f2589c..9426a81c49 100644 --- a/web/pnpm-lock.yaml +++ b/web/pnpm-lock.yaml @@ -151,6 +151,9 @@ importers: mime: specifier: ^4.0.4 version: 4.0.4 + mitt: + specifier: ^3.0.1 + version: 3.0.1 negotiator: specifier: ^0.6.3 version: 0.6.4 @@ -6129,6 +6132,9 @@ packages: resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==} engines: {node: '>=16 || 14 >=14.17'} + mitt@3.0.1: + resolution: {integrity: sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==} + mkdirp@0.5.6: resolution: {integrity: sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==} hasBin: true @@ -15636,6 +15642,8 @@ snapshots: minipass@7.1.2: {} + mitt@3.0.1: {} + mkdirp@0.5.6: dependencies: minimist: 1.2.8 From 028fc00be6e402143a4a867f7058ed1ba59392de Mon Sep 17 00:00:00 2001 From: Yi Date: Thu, 14 Nov 2024 11:19:39 +0800 Subject: [PATCH 54/68] chore: update i18n & setting window --- web/app/components/header/account-setting/menu-dialog.tsx | 1 + web/app/components/plugins/plugin-page/context.tsx | 2 +- web/i18n/en-US/common.ts | 1 + web/i18n/zh-Hans/common.ts | 1 + 4 files changed, 4 insertions(+), 1 deletion(-) diff --git a/web/app/components/header/account-setting/menu-dialog.tsx b/web/app/components/header/account-setting/menu-dialog.tsx index 3db8475c51..4df8ab8ab1 100644 --- a/web/app/components/header/account-setting/menu-dialog.tsx +++ b/web/app/components/header/account-setting/menu-dialog.tsx @@ -45,6 +45,7 @@ const MenuDialog = ({ leaveTo="opacity-0 scale-95" > +
{children} diff --git a/web/app/components/plugins/plugin-page/context.tsx b/web/app/components/plugins/plugin-page/context.tsx index 6554ce344a..e9e66849e9 100644 --- a/web/app/components/plugins/plugin-page/context.tsx +++ b/web/app/components/plugins/plugin-page/context.tsx @@ -68,7 +68,7 @@ export const PluginPageContextProvider = ({ { value: 'plugins', text: t('common.menus.plugins') }, ...( enable_marketplace - ? [{ value: 'discover', text: 'Explore Marketplace' }] + ? [{ value: 'discover', text: t('common.menus.exploreMarketplace') }] : [] ), ] diff --git a/web/i18n/en-US/common.ts b/web/i18n/en-US/common.ts index 4b364fcfe8..b9d4f80265 100644 --- a/web/i18n/en-US/common.ts +++ b/web/i18n/en-US/common.ts @@ -126,6 +126,7 @@ const translation = { explore: 'Explore', apps: 'Studio', plugins: 'Plugins', + exploreMarketplace: 'Explore Marketplace', pluginsTips: 'Integrate third-party plugins or create ChatGPT-compatible AI-Plugins.', datasets: 'Knowledge', datasetsTips: 'COMING SOON: Import your own text data or write data in real-time via Webhook for LLM context enhancement.', diff --git a/web/i18n/zh-Hans/common.ts b/web/i18n/zh-Hans/common.ts index ed3ccc840c..170713b95c 100644 --- a/web/i18n/zh-Hans/common.ts +++ b/web/i18n/zh-Hans/common.ts @@ -126,6 +126,7 @@ const translation = { explore: '探索', apps: '工作室', plugins: '插件', + exploreMarketplace: '探索市场', pluginsTips: '集成第三方插件或创建与 ChatGPT 兼容的 AI 插件。', datasets: '知识库', datasetsTips: '即将到来: 上传自己的长文本数据,或通过 Webhook 集成自己的数据源', From 253abaf1a346a3a3dab51833d1aeea611e913974 Mon Sep 17 00:00:00 2001 From: StyleZhang Date: Thu, 14 Nov 2024 14:26:02 +0800 Subject: [PATCH 55/68] fix: marketplace empty page --- .../plugins/marketplace/description/index.tsx | 16 +++--- .../plugins/marketplace/empty/index.tsx | 20 +++++--- .../plugins/marketplace/list/list-wrapper.tsx | 4 +- .../marketplace/sort-dropdown/index.tsx | 49 ++++++++++--------- .../components/tools/marketplace/index.tsx | 2 +- web/i18n/en-US/plugin.ts | 9 ++++ web/i18n/zh-Hans/plugin.ts | 9 ++++ web/tailwind-common-config.ts | 1 + web/themes/dark.css | 1 + web/themes/light.css | 1 + 10 files changed, 71 insertions(+), 41 deletions(-) diff --git a/web/app/components/plugins/marketplace/description/index.tsx b/web/app/components/plugins/marketplace/description/index.tsx index 9e3f9774b5..d1be3c9806 100644 --- a/web/app/components/plugins/marketplace/description/index.tsx +++ b/web/app/components/plugins/marketplace/description/index.tsx @@ -19,20 +19,20 @@ const Description = async ({

{t('marketplace.discover')} - - {t('category.models')} + + {t('category.models')} , - - {t('category.tools')} + + {t('category.tools')} , - - {t('category.extensions')} + + {t('category.extensions')} {t('marketplace.and')} - - {t('category.bundles')} + + {t('category.bundles')} {t('marketplace.inDifyMarketplace')}

diff --git a/web/app/components/plugins/marketplace/empty/index.tsx b/web/app/components/plugins/marketplace/empty/index.tsx index cc3957d3ff..25f8efc504 100644 --- a/web/app/components/plugins/marketplace/empty/index.tsx +++ b/web/app/components/plugins/marketplace/empty/index.tsx @@ -1,25 +1,31 @@ +'use client' +import { useTranslation } from 'react-i18next' import { Group } from '@/app/components/base/icons/src/vender/other' import Line from './line' +import cn from '@/utils/classnames' const Empty = () => { + const { t } = useTranslation() + return (
{ Array.from({ length: 16 }).map((_, index) => (
11 && 'mb-0', + )} >
)) }
@@ -30,7 +36,7 @@ const Empty = () => {
- No plugin found + {t('plugin.marketplace.noPluginFound')}
diff --git a/web/app/components/plugins/marketplace/list/list-wrapper.tsx b/web/app/components/plugins/marketplace/list/list-wrapper.tsx index 936cb7ec57..cf31bf9dee 100644 --- a/web/app/components/plugins/marketplace/list/list-wrapper.tsx +++ b/web/app/components/plugins/marketplace/list/list-wrapper.tsx @@ -1,4 +1,5 @@ 'use client' +import { useTranslation } from 'react-i18next' import type { Plugin } from '../../types' import type { MarketplaceCollection } from '../types' import { useMarketplaceContext } from '../context' @@ -18,6 +19,7 @@ const ListWrapper = ({ showInstallButton, locale, }: ListWrapperProps) => { + const { t } = useTranslation() const plugins = useMarketplaceContext(v => v.plugins) const marketplaceCollectionsFromClient = useMarketplaceContext(v => v.marketplaceCollectionsFromClient) const marketplaceCollectionPluginsMapFromClient = useMarketplaceContext(v => v.marketplaceCollectionPluginsMapFromClient) @@ -28,7 +30,7 @@ const ListWrapper = ({ { plugins && (
-
{plugins.length} results
+
{t('plugin.marketplace.pluginsResult', { num: plugins.length })}
diff --git a/web/app/components/plugins/marketplace/sort-dropdown/index.tsx b/web/app/components/plugins/marketplace/sort-dropdown/index.tsx index ed1d788b29..df520f26c1 100644 --- a/web/app/components/plugins/marketplace/sort-dropdown/index.tsx +++ b/web/app/components/plugins/marketplace/sort-dropdown/index.tsx @@ -4,6 +4,7 @@ import { RiArrowDownSLine, RiCheckLine, } from '@remixicon/react' +import { useTranslation } from 'react-i18next' import { useMarketplaceContext } from '../context' import { PortalToFollowElem, @@ -11,30 +12,30 @@ import { PortalToFollowElemTrigger, } from '@/app/components/base/portal-to-follow-elem' -const options = [ - { - value: 'install_count', - order: 'DESC', - text: 'Most Popular', - }, - { - value: 'version_updated_at', - order: 'DESC', - text: 'Recently Updated', - }, - { - value: 'created_at', - order: 'DESC', - text: 'Newly Released', - }, - { - value: 'created_at', - order: 'ASC', - text: 'First Released', - }, -] - const SortDropdown = () => { + const { t } = useTranslation() + const options = [ + { + value: 'install_count', + order: 'DESC', + text: t('plugin.marketplace.sortOption.mostPopular'), + }, + { + value: 'version_updated_at', + order: 'DESC', + text: t('plugin.marketplace.sortOption.recentlyUpdated'), + }, + { + value: 'created_at', + order: 'DESC', + text: t('plugin.marketplace.sortOption.newlyReleased'), + }, + { + value: 'created_at', + order: 'ASC', + text: t('plugin.marketplace.sortOption.firstReleased'), + }, + ] const sort = useMarketplaceContext(v => v.sort) const handleSortChange = useMarketplaceContext(v => v.handleSortChange) const [open, setOpen] = useState(false) @@ -53,7 +54,7 @@ const SortDropdown = () => { setOpen(v => !v)}>
- Sort by + {t('plugin.marketplace.sortBy')} {selectedOption.text} diff --git a/web/app/components/tools/marketplace/index.tsx b/web/app/components/tools/marketplace/index.tsx index c50b898362..e7c1aaec9e 100644 --- a/web/app/components/tools/marketplace/index.tsx +++ b/web/app/components/tools/marketplace/index.tsx @@ -25,7 +25,7 @@ const Marketplace = ({ } = useMarketplace(searchPluginText, filterPluginTags) return ( -
+
onMarketplaceScroll()} diff --git a/web/i18n/en-US/plugin.ts b/web/i18n/en-US/plugin.ts index 91f17e07f3..402d1a21b1 100644 --- a/web/i18n/en-US/plugin.ts +++ b/web/i18n/en-US/plugin.ts @@ -128,6 +128,15 @@ const translation = { and: 'and', inDifyMarketplace: 'in Dify Marketplace', moreFrom: 'More from Marketplace', + noPluginFound: 'No plugin found', + pluginsResult: '{{num}} results', + sortBy: 'Sort by', + sortOption: { + mostPopular: 'Most Popular', + recentlyUpdated: 'Recently Updated', + newlyReleased: 'Newly Released', + firstReleased: 'First Released', + }, }, task: { installing: 'Installing {{installingLength}}/{{totalLength}} plugins...', diff --git a/web/i18n/zh-Hans/plugin.ts b/web/i18n/zh-Hans/plugin.ts index 30de7acced..a78fdb31f7 100644 --- a/web/i18n/zh-Hans/plugin.ts +++ b/web/i18n/zh-Hans/plugin.ts @@ -128,6 +128,15 @@ const translation = { and: '和', inDifyMarketplace: '在 Dify 市场中', moreFrom: '更多来自市场', + noPluginFound: '未找到插件', + pluginsResult: '{{num}} 个插件结果', + sortBy: '排序方式', + sortOption: { + mostPopular: '最受欢迎', + recentlyUpdated: '最近更新', + newlyReleased: '最新发布', + firstReleased: '首次发布', + }, }, task: { installing: '{{installingLength}}/{{totalLength}} 插件安装中...', diff --git a/web/tailwind-common-config.ts b/web/tailwind-common-config.ts index c1ec16a6a1..41f36bc17a 100644 --- a/web/tailwind-common-config.ts +++ b/web/tailwind-common-config.ts @@ -88,6 +88,7 @@ const config = { 'chat-bubble-bg': 'var(--color-chat-bubble-bg)', 'workflow-process-bg': 'var(--color-workflow-process-bg)', 'marketplace-divider-bg': 'var(--color-marketplace-divider-bg)', + 'marketplace-plugin-empty': 'var(--color-marketplace-plugin-empty)', }, animation: { 'spin-slow': 'spin 2s linear infinite', diff --git a/web/themes/dark.css b/web/themes/dark.css index 08994039eb..a4ef4e001b 100644 --- a/web/themes/dark.css +++ b/web/themes/dark.css @@ -695,4 +695,5 @@ html[data-theme="dark"] { --color-third-party-model-bg-default: #0B0B0E; --color-workflow-process-bg: linear-gradient(90deg, rgba(24, 24, 27, 0.25) 0%, rgba(24, 24, 27, 0.04) 100%); --color-marketplace-divider-bg: linear-gradient(90deg, rgba(200, 206, 218, 0.14) 0%, rgba(0, 0, 0, 0) 100%); + --color-marketplace-plugin-empty: linear-gradient(180deg, rgba(0, 0, 0, 0.00) 0%, #222225 100%); } \ No newline at end of file diff --git a/web/themes/light.css b/web/themes/light.css index ed563ad594..4f380e50e4 100644 --- a/web/themes/light.css +++ b/web/themes/light.css @@ -695,4 +695,5 @@ html[data-theme="light"] { --color-third-party-model-bg-default: #F9FAFB; --color-workflow-process-bg: linear-gradient(90deg, rgba(200, 206, 218, 0.20) 0%, rgba(200, 206, 218, 0.04) 100%); --color-marketplace-divider-bg: linear-gradient(90deg, rgba(16, 24, 40, 0.08) 0%, rgba(255, 255, 255, 0) 100%); + --color-marketplace-plugin-empty: linear-gradient(180deg, rgba(255, 255, 255, 0.00) 0%, #FCFCFD 100%); } \ No newline at end of file From a0a62db6ad3298bb705064bd46e658886b4aad43 Mon Sep 17 00:00:00 2001 From: twwu Date: Thu, 14 Nov 2024 14:36:30 +0800 Subject: [PATCH 56/68] refactor: Split linear-gradient and color --- web/app/styles/globals.css | 40 +++++++++++++++++--------------------- web/themes/dark.css | 5 ----- web/themes/light.css | 5 ----- web/themes/other-dark.css | 7 +++++++ web/themes/other-light.css | 7 +++++++ 5 files changed, 32 insertions(+), 32 deletions(-) create mode 100644 web/themes/other-dark.css create mode 100644 web/themes/other-light.css diff --git a/web/app/styles/globals.css b/web/app/styles/globals.css index 06d2596a24..8b74c07afd 100644 --- a/web/app/styles/globals.css +++ b/web/app/styles/globals.css @@ -4,6 +4,8 @@ @import "../../themes/light.css"; @import "../../themes/dark.css"; +@import "../../themes/other-light.css"; +@import "../../themes/other-dark.css"; html[data-changing-theme] * { transition: none !important; @@ -20,30 +22,24 @@ html[data-changing-theme] * { --background-start-rgb: 214, 219, 220; --background-end-rgb: 255, 255, 255; - --primary-glow: conic-gradient( - from 180deg at 50% 50%, - #16abff33 0deg, - #0885ff33 55deg, - #54d6ff33 120deg, - #0071ff33 160deg, - transparent 360deg - ); - --secondary-glow: radial-gradient( - rgba(255, 255, 255, 1), - rgba(255, 255, 255, 0) - ); + --primary-glow: conic-gradient(from 180deg at 50% 50%, + #16abff33 0deg, + #0885ff33 55deg, + #54d6ff33 120deg, + #0071ff33 160deg, + transparent 360deg); + --secondary-glow: radial-gradient(rgba(255, 255, 255, 1), + rgba(255, 255, 255, 0)); --tile-start-rgb: 239, 245, 249; --tile-end-rgb: 228, 232, 233; - --tile-border: conic-gradient( - #00000080, - #00000040, - #00000030, - #00000020, - #00000010, - #00000010, - #00000080 - ); + --tile-border: conic-gradient(#00000080, + #00000040, + #00000030, + #00000020, + #00000010, + #00000010, + #00000080); --callout-rgb: 238, 240, 241; --callout-border-rgb: 172, 175, 176; @@ -680,4 +676,4 @@ button:focus-within { @import "../components/base/action-button/index.css"; @import "../components/base/modal/index.css"; -@tailwind utilities; +@tailwind utilities; \ No newline at end of file diff --git a/web/themes/dark.css b/web/themes/dark.css index a4ef4e001b..9ef62c53cb 100644 --- a/web/themes/dark.css +++ b/web/themes/dark.css @@ -685,15 +685,10 @@ html[data-theme="dark"] { --color-third-party-LangChain: #FFFFFF; --color-third-party-Langfuse: #FFFFFF; - --color-chatbot-bg: linear-gradient(180deg, rgba(34, 34, 37, 0.90) 0%, rgba(29, 29, 32, 0.90) 90.48%); - --color-chat-bubble-bg: linear-gradient(180deg, rgba(200, 206, 218, 0.08) 0%, rgba(200, 206, 218, 0.02) 100%); --color-third-party-Github: #FFFFFF; --color-third-party-Github-tertiary: #C8CEDA99; --color-third-party-Github-secondary: #D9D9DE; --color-third-party-model-bg-openai: #121212; --color-third-party-model-bg-anthropic: #1D1917; --color-third-party-model-bg-default: #0B0B0E; - --color-workflow-process-bg: linear-gradient(90deg, rgba(24, 24, 27, 0.25) 0%, rgba(24, 24, 27, 0.04) 100%); - --color-marketplace-divider-bg: linear-gradient(90deg, rgba(200, 206, 218, 0.14) 0%, rgba(0, 0, 0, 0) 100%); - --color-marketplace-plugin-empty: linear-gradient(180deg, rgba(0, 0, 0, 0.00) 0%, #222225 100%); } \ No newline at end of file diff --git a/web/themes/light.css b/web/themes/light.css index 4f380e50e4..73d73ced37 100644 --- a/web/themes/light.css +++ b/web/themes/light.css @@ -685,15 +685,10 @@ html[data-theme="light"] { --color-third-party-LangChain: #1C3C3C; --color-third-party-Langfuse: #000000; - --color-chatbot-bg: linear-gradient(180deg, rgba(249, 250, 251, 0.90) 0%, rgba(242, 244, 247, 0.90) 90.48%); - --color-chat-bubble-bg: linear-gradient(180deg, #FFF 0%, rgba(255, 255, 255, 0.60) 100%); --color-third-party-Github: #1B1F24; --color-third-party-Github-tertiary: #1B1F24; --color-third-party-Github-secondary: #1B1F24; --color-third-party-model-bg-openai: #E3E5E8; --color-third-party-model-bg-anthropic: #EEEDE7; --color-third-party-model-bg-default: #F9FAFB; - --color-workflow-process-bg: linear-gradient(90deg, rgba(200, 206, 218, 0.20) 0%, rgba(200, 206, 218, 0.04) 100%); - --color-marketplace-divider-bg: linear-gradient(90deg, rgba(16, 24, 40, 0.08) 0%, rgba(255, 255, 255, 0) 100%); - --color-marketplace-plugin-empty: linear-gradient(180deg, rgba(255, 255, 255, 0.00) 0%, #FCFCFD 100%); } \ No newline at end of file diff --git a/web/themes/other-dark.css b/web/themes/other-dark.css new file mode 100644 index 0000000000..4e48cdbb16 --- /dev/null +++ b/web/themes/other-dark.css @@ -0,0 +1,7 @@ +html[data-theme="dark"] { + --color-chatbot-bg: linear-gradient(180deg, rgba(34, 34, 37, 0.90) 0%, rgba(29, 29, 32, 0.90) 90.48%); + --color-chat-bubble-bg: linear-gradient(180deg, rgba(200, 206, 218, 0.08) 0%, rgba(200, 206, 218, 0.02) 100%); + --color-workflow-process-bg: linear-gradient(90deg, rgba(24, 24, 27, 0.25) 0%, rgba(24, 24, 27, 0.04) 100%); + --color-marketplace-divider-bg: linear-gradient(90deg, rgba(200, 206, 218, 0.14) 0%, rgba(0, 0, 0, 0) 100%); + --color-marketplace-plugin-empty: linear-gradient(180deg, rgba(0, 0, 0, 0.00) 0%, #222225 100%); +} \ No newline at end of file diff --git a/web/themes/other-light.css b/web/themes/other-light.css new file mode 100644 index 0000000000..e99ba4dd0a --- /dev/null +++ b/web/themes/other-light.css @@ -0,0 +1,7 @@ +html[data-theme="light"] { + --color-chatbot-bg: linear-gradient(180deg, rgba(249, 250, 251, 0.90) 0%, rgba(242, 244, 247, 0.90) 90.48%); + --color-chat-bubble-bg: linear-gradient(180deg, #FFF 0%, rgba(255, 255, 255, 0.60) 100%); + --color-workflow-process-bg: linear-gradient(90deg, rgba(200, 206, 218, 0.20) 0%, rgba(200, 206, 218, 0.04) 100%); + --color-marketplace-divider-bg: linear-gradient(90deg, rgba(16, 24, 40, 0.08) 0%, rgba(255, 255, 255, 0) 100%); + --color-marketplace-plugin-empty: linear-gradient(180deg, rgba(255, 255, 255, 0.00) 0%, #FCFCFD 100%); +} \ No newline at end of file From 6a63a03cb2ce1bdac725a0b2112a92e1c6e0be0b Mon Sep 17 00:00:00 2001 From: StyleZhang Date: Thu, 14 Nov 2024 14:47:53 +0800 Subject: [PATCH 57/68] feat: tool list use query --- web/app/components/tools/marketplace/index.tsx | 16 ++++++++++++++-- web/app/components/tools/provider-list.tsx | 16 ++++------------ web/i18n/en-US/common.ts | 1 + web/i18n/en-US/plugin.ts | 2 +- web/i18n/zh-Hans/common.ts | 1 + web/i18n/zh-Hans/plugin.ts | 2 +- web/service/use-tools.ts | 9 +++++++++ 7 files changed, 31 insertions(+), 16 deletions(-) diff --git a/web/app/components/tools/marketplace/index.tsx b/web/app/components/tools/marketplace/index.tsx index e7c1aaec9e..2c56cdd322 100644 --- a/web/app/components/tools/marketplace/index.tsx +++ b/web/app/components/tools/marketplace/index.tsx @@ -1,9 +1,13 @@ -import { RiArrowUpDoubleLine } from '@remixicon/react' +import { + RiArrowRightUpLine, + RiArrowUpDoubleLine, +} from '@remixicon/react' import { useTranslation } from 'react-i18next' import { useMarketplace } from './hooks' import List from '@/app/components/plugins/marketplace/list' import Loading from '@/app/components/base/loading' import { getLocaleOnClient } from '@/i18n' +import { MARKETPLACE_URL_PREFIX } from '@/config' type MarketplaceProps = { searchPluginText: string @@ -51,7 +55,15 @@ const Marketplace = ({ {t('plugin.category.bundles')} - {t('plugin.marketplace.inDifyMarketplace')} + {t('common.operation.in')} + + {t('plugin.marketplace.difyMarketplace')} + +
{ diff --git a/web/app/components/tools/provider-list.tsx b/web/app/components/tools/provider-list.tsx index acec3dad7e..364c5e00b9 100644 --- a/web/app/components/tools/provider-list.tsx +++ b/web/app/components/tools/provider-list.tsx @@ -10,10 +10,10 @@ import LabelFilter from '@/app/components/tools/labels/filter' import Input from '@/app/components/base/input' import ProviderDetail from '@/app/components/tools/provider/detail' import Empty from '@/app/components/tools/add-tool-modal/empty' -import { fetchCollectionList } from '@/service/tools' import Card from '@/app/components/plugins/card' import CardMoreInfo from '@/app/components/plugins/card/card-more-info' import { useSelector as useAppContextSelector } from '@/context/app-context' +import { useAllToolProviders } from '@/service/use-tools' const ProviderList = () => { const { t } = useTranslation() @@ -36,8 +36,7 @@ const ProviderList = () => { const handleKeywordsChange = (value: string) => { setKeywords(value) } - - const [collectionList, setCollectionList] = useState([]) + const { data: collectionList, refetch } = useAllToolProviders() const filteredCollectionList = useMemo(() => { return collectionList.filter((collection) => { if (collection.type !== activeTab) @@ -49,13 +48,6 @@ const ProviderList = () => { return true }) }, [activeTab, tagFilterValue, keywords, collectionList]) - const getProviderList = async () => { - const list = await fetchCollectionList() - setCollectionList([...list]) - } - useEffect(() => { - getProviderList() - }, []) const [currentProvider, setCurrentProvider] = useState() useEffect(() => { @@ -106,7 +98,7 @@ const ProviderList = () => { > { setCurrentProvider(undefined)} - onRefreshData={getProviderList} + onRefreshData={refetch} /> )}
diff --git a/web/i18n/en-US/common.ts b/web/i18n/en-US/common.ts index b9d4f80265..97b158904b 100644 --- a/web/i18n/en-US/common.ts +++ b/web/i18n/en-US/common.ts @@ -44,6 +44,7 @@ const translation = { zoomOut: 'Zoom Out', zoomIn: 'Zoom In', openInNewTab: 'Open in new tab', + in: 'in', }, errorMsg: { fieldRequired: '{{field}} is required', diff --git a/web/i18n/en-US/plugin.ts b/web/i18n/en-US/plugin.ts index 402d1a21b1..0fc944f3e8 100644 --- a/web/i18n/en-US/plugin.ts +++ b/web/i18n/en-US/plugin.ts @@ -126,7 +126,7 @@ const translation = { empower: 'Empower your AI development', discover: 'Discover', and: 'and', - inDifyMarketplace: 'in Dify Marketplace', + difyMarketplace: 'Dify Marketplace', moreFrom: 'More from Marketplace', noPluginFound: 'No plugin found', pluginsResult: '{{num}} results', diff --git a/web/i18n/zh-Hans/common.ts b/web/i18n/zh-Hans/common.ts index 170713b95c..28be0bf3e9 100644 --- a/web/i18n/zh-Hans/common.ts +++ b/web/i18n/zh-Hans/common.ts @@ -44,6 +44,7 @@ const translation = { zoomOut: '缩小', zoomIn: '放大', openInNewTab: '在新标签页打开', + in: '在', }, errorMsg: { fieldRequired: '{{field}} 为必填项', diff --git a/web/i18n/zh-Hans/plugin.ts b/web/i18n/zh-Hans/plugin.ts index a78fdb31f7..8769762be7 100644 --- a/web/i18n/zh-Hans/plugin.ts +++ b/web/i18n/zh-Hans/plugin.ts @@ -126,7 +126,7 @@ const translation = { empower: '助力您的 AI 开发', discover: '探索', and: '和', - inDifyMarketplace: '在 Dify 市场中', + difyMarketplace: 'Dify 市场', moreFrom: '更多来自市场', noPluginFound: '未找到插件', pluginsResult: '{{num}} 个插件结果', diff --git a/web/service/use-tools.ts b/web/service/use-tools.ts index 8b06d47342..36b8c3d120 100644 --- a/web/service/use-tools.ts +++ b/web/service/use-tools.ts @@ -13,6 +13,15 @@ import { const NAME_SPACE = 'tools' +const useAllToolProvidersKey = [NAME_SPACE, 'allToolProviders'] +export const useAllToolProviders = () => { + return useQuery({ + queryKey: useAllToolProvidersKey, + queryFn: () => get('/workspaces/current/tool-providers'), + initialData: [], + }) +} + const useAllBuiltInToolsKey = [NAME_SPACE, 'builtIn'] export const useAllBuiltInTools = () => { return useQuery({ From ceb18d160f65ccfbde54e916659072976efe27a2 Mon Sep 17 00:00:00 2001 From: StyleZhang Date: Thu, 14 Nov 2024 14:56:15 +0800 Subject: [PATCH 58/68] fix: marketplace i18n --- web/app/components/plugins/marketplace/description/index.tsx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/web/app/components/plugins/marketplace/description/index.tsx b/web/app/components/plugins/marketplace/description/index.tsx index d1be3c9806..8cab8373f3 100644 --- a/web/app/components/plugins/marketplace/description/index.tsx +++ b/web/app/components/plugins/marketplace/description/index.tsx @@ -11,6 +11,7 @@ const Description = async ({ }: DescriptionProps) => { const localeDefault = getLocaleOnServer() const { t } = await translate(localeFromProps || localeDefault, 'plugin') + const { t: tCommon } = await translate(localeFromProps || localeDefault, 'common') return ( <> @@ -34,7 +35,8 @@ const Description = async ({ {t('category.bundles')} - {t('marketplace.inDifyMarketplace')} + {tCommon('operation.in')} + {t('marketplace.difyMarketplace')} ) From 070968a0481f40cc09435b5894c9c9c7ae236de3 Mon Sep 17 00:00:00 2001 From: AkaraChen Date: Thu, 14 Nov 2024 15:39:21 +0800 Subject: [PATCH 59/68] style: add lint rule for tailwind --- web/eslint.config.mjs | 20 ++++++++++++++++++++ web/package.json | 1 + web/pnpm-lock.yaml | 15 +++++++++++++++ 3 files changed, 36 insertions(+) diff --git a/web/eslint.config.mjs b/web/eslint.config.mjs index 2f51cfaca3..58dec4999e 100644 --- a/web/eslint.config.mjs +++ b/web/eslint.config.mjs @@ -9,6 +9,7 @@ import { FlatCompat } from '@eslint/eslintrc' import globals from 'globals' import storybook from 'eslint-plugin-storybook' import { fixupConfigRules } from '@eslint/compat' +import tailwind from 'eslint-plugin-tailwindcss' const __filename = fileURLToPath(import.meta.url) const __dirname = path.dirname(__filename) @@ -76,6 +77,12 @@ export default combine( ? [] // TODO: remove this when upgrade to nextjs 15 : fixupConfigRules(compat.extends('next')), + { + rules: { + // performance issue, and not used. + '@next/next/no-html-link-for-pages': 'off', + }, + }, { ignores: [ '**/node_modules/*', @@ -160,4 +167,17 @@ export default combine( }, }, }, + tailwind.configs['flat/recommended'], + { + rules: { + // due to 1k lines of tailwind config, these rule have performance issue + 'tailwindcss/no-contradicting-classname': 'off', + 'tailwindcss/no-unnecessary-arbitrary-value': 'off', + 'tailwindcss/enforces-shorthand': 'off', + 'tailwindcss/no-custom-classname': 'off', + + // in the future + 'tailwindcss/classnames-order': 'off', + }, + }, ) diff --git a/web/package.json b/web/package.json index 22a704bdcb..ba619d45f7 100644 --- a/web/package.json +++ b/web/package.json @@ -162,6 +162,7 @@ "eslint-plugin-react-hooks": "^5.0.0", "eslint-plugin-react-refresh": "^0.4.13", "eslint-plugin-storybook": "^0.10.1", + "eslint-plugin-tailwindcss": "^3.17.5", "husky": "^9.1.6", "jest": "^29.7.0", "jest-environment-jsdom": "^29.7.0", diff --git a/web/pnpm-lock.yaml b/web/pnpm-lock.yaml index 9426a81c49..2c43d1fe44 100644 --- a/web/pnpm-lock.yaml +++ b/web/pnpm-lock.yaml @@ -422,6 +422,9 @@ importers: eslint-plugin-storybook: specifier: ^0.10.1 version: 0.10.1(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) + eslint-plugin-tailwindcss: + specifier: ^3.17.5 + version: 3.17.5(tailwindcss@3.4.14(ts-node@10.9.2(@types/node@18.15.0)(typescript@4.9.5))) husky: specifier: ^9.1.6 version: 9.1.6 @@ -4444,6 +4447,12 @@ packages: peerDependencies: eslint: '>=6' + eslint-plugin-tailwindcss@3.17.5: + resolution: {integrity: sha512-8Mi7p7dm+mO1dHgRHHFdPu4RDTBk69Cn4P0B40vRQR+MrguUpwmKwhZy1kqYe3Km8/4nb+cyrCF+5SodOEmaow==} + engines: {node: '>=18.12.0'} + peerDependencies: + tailwindcss: ^3.4.0 + eslint-plugin-toml@0.11.1: resolution: {integrity: sha512-Y1WuMSzfZpeMIrmlP1nUh3kT8p96mThIq4NnHrYUhg10IKQgGfBZjAWnrg9fBqguiX4iFps/x/3Hb5TxBisfdw==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -13174,6 +13183,12 @@ snapshots: - supports-color - typescript + eslint-plugin-tailwindcss@3.17.5(tailwindcss@3.4.14(ts-node@10.9.2(@types/node@18.15.0)(typescript@4.9.5))): + dependencies: + fast-glob: 3.3.2 + postcss: 8.4.47 + tailwindcss: 3.4.14(ts-node@10.9.2(@types/node@18.15.0)(typescript@4.9.5)) + eslint-plugin-toml@0.11.1(eslint@9.13.0(jiti@1.21.6)): dependencies: debug: 4.3.7 From cd2860deb4048db0224a4d912d642a3a6462911d Mon Sep 17 00:00:00 2001 From: twwu Date: Thu, 14 Nov 2024 15:47:22 +0800 Subject: [PATCH 60/68] feat: add i18n support for plugin installation and empty states --- .../plugins/plugin-page/empty/index.tsx | 14 ++++++++------ .../plugin-page/install-plugin-dropdown.tsx | 12 +++++++----- web/i18n/en-US/plugin.ts | 16 ++++++++++++++++ web/i18n/zh-Hans/plugin.ts | 16 ++++++++++++++++ 4 files changed, 47 insertions(+), 11 deletions(-) diff --git a/web/app/components/plugins/plugin-page/empty/index.tsx b/web/app/components/plugins/plugin-page/empty/index.tsx index 3092e0f444..06dc41492f 100644 --- a/web/app/components/plugins/plugin-page/empty/index.tsx +++ b/web/app/components/plugins/plugin-page/empty/index.tsx @@ -9,8 +9,10 @@ import { Group } from '@/app/components/base/icons/src/vender/other' import { useSelector as useAppContextSelector } from '@/context/app-context' import Line from '../../marketplace/empty/line' import { useInstalledPluginList, useInvalidateInstalledPluginList } from '@/service/use-plugins' +import { useTranslation } from 'react-i18next' const Empty = () => { + const { t } = useTranslation() const fileInputRef = useRef(null) const [selectedAction, setSelectedAction] = useState(null) const [selectedFile, setSelectedFile] = useState(null) @@ -30,9 +32,9 @@ const Empty = () => { const text = useMemo(() => { if (pluginList?.plugins.length === 0) - return 'No plugins installed' + return t('plugin.list.noInstalled') if (filters.categories.length > 0 || filters.tags.length > 0 || filters.searchQuery) - return 'No plugins found' + return t('plugin.list.notFound') }, [pluginList, filters]) return ( @@ -70,11 +72,11 @@ const Empty = () => { {[ ...( (enable_marketplace || true) - ? [{ icon: MagicBox, text: 'Marketplace', action: 'marketplace' }] + ? [{ icon: MagicBox, text: t('plugin.list.source.marketplace'), action: 'marketplace' }] : [] ), - { icon: Github, text: 'GitHub', action: 'github' }, - { icon: FileZip, text: 'Local Package File', action: 'local' }, + { icon: Github, text: t('plugin.list.source.github'), action: 'github' }, + { icon: FileZip, text: t('plugin.list.source.local'), action: 'local' }, ].map(({ icon: Icon, text, action }) => (
{ }} > - {`Install from ${text}`} + {text}
))}
diff --git a/web/app/components/plugins/plugin-page/install-plugin-dropdown.tsx b/web/app/components/plugins/plugin-page/install-plugin-dropdown.tsx index 3d1351b67c..826aba334b 100644 --- a/web/app/components/plugins/plugin-page/install-plugin-dropdown.tsx +++ b/web/app/components/plugins/plugin-page/install-plugin-dropdown.tsx @@ -16,6 +16,7 @@ import { } from '@/app/components/base/portal-to-follow-elem' import { useSelector as useAppContextSelector } from '@/context/app-context' import { useInvalidateInstalledPluginList } from '@/service/use-plugins' +import { useTranslation } from 'react-i18next' type Props = { onSwitchToMarketplaceTab: () => void @@ -23,6 +24,7 @@ type Props = { const InstallPluginDropdown = ({ onSwitchToMarketplaceTab, }: Props) => { + const { t } = useTranslation() const fileInputRef = useRef(null) const [isMenuOpen, setIsMenuOpen] = useState(false) const [selectedAction, setSelectedAction] = useState(null) @@ -65,14 +67,14 @@ const InstallPluginDropdown = ({ className={cn('w-full h-full p-2 text-components-button-secondary-text', isMenuOpen && 'bg-state-base-hover')} > - Install plugin + {t('plugin.installPlugin')}
- Install From + {t('plugin.installFrom')} (
Date: Thu, 14 Nov 2024 16:21:28 +0800 Subject: [PATCH 61/68] chore: update the plan tags --- .../header/account-dropdown/workplace-selector/index.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/web/app/components/header/account-dropdown/workplace-selector/index.tsx b/web/app/components/header/account-dropdown/workplace-selector/index.tsx index f7ecb67c5c..fc6a42338a 100644 --- a/web/app/components/header/account-dropdown/workplace-selector/index.tsx +++ b/web/app/components/header/account-dropdown/workplace-selector/index.tsx @@ -69,12 +69,12 @@ const WorkplaceSelector = () => { workspaces.map(workspace => (
handleSwitchWorkspace(workspace.id)}>
{workspace.name[0].toLocaleUpperCase()}
-
{workspace.name}
+
{workspace.name}
{
- {plan.type.toUpperCase()} + {plan.type === 'professional' ? 'PRO' : plan.type.toUpperCase()}
From 1877433f20fc9a5f9c319e4ab00ccdd459f22990 Mon Sep 17 00:00:00 2001 From: StyleZhang Date: Thu, 14 Nov 2024 16:37:33 +0800 Subject: [PATCH 62/68] fix: marketplace --- .../plugins/marketplace/description/index.tsx | 8 +-- .../plugins/marketplace/list/card-wrapper.tsx | 72 ++++++++++++++----- 2 files changed, 59 insertions(+), 21 deletions(-) diff --git a/web/app/components/plugins/marketplace/description/index.tsx b/web/app/components/plugins/marketplace/description/index.tsx index 8cab8373f3..30ddc73595 100644 --- a/web/app/components/plugins/marketplace/description/index.tsx +++ b/web/app/components/plugins/marketplace/description/index.tsx @@ -21,19 +21,19 @@ const Description = async ({

{t('marketplace.discover')} - {t('category.models')} + {t('category.models')} , - {t('category.tools')} + {t('category.tools')} , - {t('category.extensions')} + {t('category.extensions')} {t('marketplace.and')} - {t('category.bundles')} + {t('category.bundles')} {tCommon('operation.in')} {t('marketplace.difyMarketplace')} diff --git a/web/app/components/plugins/marketplace/list/card-wrapper.tsx b/web/app/components/plugins/marketplace/list/card-wrapper.tsx index 3465e095c4..d8e9bcb61c 100644 --- a/web/app/components/plugins/marketplace/list/card-wrapper.tsx +++ b/web/app/components/plugins/marketplace/list/card-wrapper.tsx @@ -25,13 +25,61 @@ const CardWrapper = ({ setFalse: hideInstallFromMarketplace, }] = useBoolean(false) + if (showInstallButton) { + return ( +
+ tag.name)} + /> + } + /> + { + showInstallButton && ( +
+ + +
+ ) + } + { + isShowInstallFromMarketplace && ( + + ) + } +
+ ) + } + return ( -
{ - if (!showInstallButton) - window.open(`${MARKETPLACE_URL_PREFIX}/plugin/${plugin.org}/${plugin.name}`) - }} + ) } - { - isShowInstallFromMarketplace && ( - - ) - } -
+ ) } From 76104d811c2347278db52a440c3625319b07ec62 Mon Sep 17 00:00:00 2001 From: Joel Date: Thu, 14 Nov 2024 16:54:23 +0800 Subject: [PATCH 63/68] feat: can show install plugins --- .../(commonLayout)/plugins/test/card/page.tsx | 20 ++++- .../install-plugin/install-bundle/index.tsx | 9 +- .../install-bundle/item/github-item.tsx | 47 +++++++++++ .../install-bundle/item/loaded-item.tsx | 36 ++++++++ .../install-bundle/item/loading.tsx | 12 +++ .../install-bundle/item/marketplace-item.tsx | 29 +++++++ .../steps/install-by-dsl-list.tsx | 83 +++++++++++++++++++ .../install-bundle/steps/install.tsx | 55 ++++++------ web/service/use-plugins.ts | 25 ++++++ 9 files changed, 279 insertions(+), 37 deletions(-) create mode 100644 web/app/components/plugins/install-plugin/install-bundle/item/github-item.tsx create mode 100644 web/app/components/plugins/install-plugin/install-bundle/item/loaded-item.tsx create mode 100644 web/app/components/plugins/install-plugin/install-bundle/item/loading.tsx create mode 100644 web/app/components/plugins/install-plugin/install-bundle/item/marketplace-item.tsx create mode 100644 web/app/components/plugins/install-plugin/install-bundle/steps/install-by-dsl-list.tsx diff --git a/web/app/(commonLayout)/plugins/test/card/page.tsx b/web/app/(commonLayout)/plugins/test/card/page.tsx index efc569a733..85a00d5af0 100644 --- a/web/app/(commonLayout)/plugins/test/card/page.tsx +++ b/web/app/(commonLayout)/plugins/test/card/page.tsx @@ -1,6 +1,6 @@ 'use client' import Card from '@/app/components/plugins/card' -import { customTool, extensionDallE, modelGPT4, toolNeko, toolNotion } from '@/app/components/plugins/card/card-mock' +import { customTool, extensionDallE, modelGPT4, toolNotion } from '@/app/components/plugins/card/card-mock' // import PluginItem from '@/app/components/plugins/plugin-item' import CardMoreInfo from '@/app/components/plugins/card/card-more-info' // import ProviderCard from '@/app/components/plugins/provider-card' @@ -12,7 +12,23 @@ const PluginList = () => { return (
- { }} plugins={[toolNeko, { ...toolNeko, plugin_unique_identifier: `${toolNeko.plugin_unique_identifier}xxx` }]} /> + { }} fromDSLPayload={[ + { + type: 'marketplace', + value: { + plugin_unique_identifier: 'langgenius/google:0.0.2@dcb354c9d0fee60e6e9c9eb996e1e485bbef343ba8cd545c0cfb3ec80970f6f1', + }, + }, + { + type: 'github', + value: { + repo: 'YIXIAO0/test', + version: '1.11.5', + package: 'test.difypkg', + github_plugin_unique_identifier: 'yixiao0/test:0.0.1@3592166c87afcf944b4f13f27467a5c8f9e00bd349cb42033a072734a37431b4', + }, + }, + ]} />
{/*

Dify Plugin list

*/} {/*
diff --git a/web/app/components/plugins/install-plugin/install-bundle/index.tsx b/web/app/components/plugins/install-plugin/install-bundle/index.tsx index 6f20db7725..54f00d68a4 100644 --- a/web/app/components/plugins/install-plugin/install-bundle/index.tsx +++ b/web/app/components/plugins/install-plugin/install-bundle/index.tsx @@ -3,7 +3,7 @@ import type { FC } from 'react' import Modal from '@/app/components/base/modal' import React, { useCallback, useState } from 'react' import { InstallStep } from '../../types' -import type { PluginDeclaration } from '../../types' +import type { Dependency } from '../../types' import Install from './steps/install' import { useTranslation } from 'react-i18next' @@ -17,13 +17,14 @@ export enum InstallType { type Props = { installType?: InstallType - plugins?: PluginDeclaration[] + fromDSLPayload: Dependency[] + // plugins?: PluginDeclaration[] onClose: () => void } const InstallBundle: FC = ({ installType = InstallType.fromMarketplace, - plugins = [], + fromDSLPayload, onClose, }) => { const { t } = useTranslation() @@ -54,7 +55,7 @@ const InstallBundle: FC = ({
{step === InstallStep.readyToInstall && ( )} diff --git a/web/app/components/plugins/install-plugin/install-bundle/item/github-item.tsx b/web/app/components/plugins/install-plugin/install-bundle/item/github-item.tsx new file mode 100644 index 0000000000..1a773ca6a8 --- /dev/null +++ b/web/app/components/plugins/install-plugin/install-bundle/item/github-item.tsx @@ -0,0 +1,47 @@ +'use client' +import type { FC } from 'react' +import React, { useEffect } from 'react' +import type { Dependency, Plugin } from '../../../types' +import { pluginManifestToCardPluginProps } from '../../utils' +import { useUploadGitHub } from '@/service/use-plugins' +import Loading from './loading' +import LoadedItem from './loaded-item' + +type Props = { + checked: boolean + onCheckedChange: (plugin: Plugin) => void + dependency: Dependency + onFetchedPayload: (payload: Plugin) => void +} + +const Item: FC = ({ + checked, + onCheckedChange, + dependency, + onFetchedPayload, +}) => { + const info = dependency.value + const { data } = useUploadGitHub({ + repo: info.repo!, + version: info.version!, + package: info.package!, + }) + const [payload, setPayload] = React.useState(null) + useEffect(() => { + if (data) { + const payload = pluginManifestToCardPluginProps(data.manifest) + onFetchedPayload(payload) + setPayload(payload) + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [data]) + if (!payload) return + return ( + + ) +} +export default React.memo(Item) diff --git a/web/app/components/plugins/install-plugin/install-bundle/item/loaded-item.tsx b/web/app/components/plugins/install-plugin/install-bundle/item/loaded-item.tsx new file mode 100644 index 0000000000..94a9071dae --- /dev/null +++ b/web/app/components/plugins/install-plugin/install-bundle/item/loaded-item.tsx @@ -0,0 +1,36 @@ +'use client' +import type { FC } from 'react' +import React from 'react' +import type { Plugin } from '../../../types' +import Card from '../../../card' +import Checkbox from '@/app/components/base/checkbox' +import Badge, { BadgeState } from '@/app/components/base/badge/index' + +type Props = { + checked: boolean + onCheckedChange: (plugin: Plugin) => void + payload: Plugin +} + +const LoadedItem: FC = ({ + checked, + onCheckedChange, + payload, +}) => { + return ( +
+ onCheckedChange(payload)} + /> + {payload.version}} + /> +
+ ) +} + +export default React.memo(LoadedItem) diff --git a/web/app/components/plugins/install-plugin/install-bundle/item/loading.tsx b/web/app/components/plugins/install-plugin/install-bundle/item/loading.tsx new file mode 100644 index 0000000000..e89022aad6 --- /dev/null +++ b/web/app/components/plugins/install-plugin/install-bundle/item/loading.tsx @@ -0,0 +1,12 @@ +'use client' +import React from 'react' + +const Loading = () => { + return ( +
+ Loading... +
+ ) +} + +export default React.memo(Loading) diff --git a/web/app/components/plugins/install-plugin/install-bundle/item/marketplace-item.tsx b/web/app/components/plugins/install-plugin/install-bundle/item/marketplace-item.tsx new file mode 100644 index 0000000000..5f2e9433a1 --- /dev/null +++ b/web/app/components/plugins/install-plugin/install-bundle/item/marketplace-item.tsx @@ -0,0 +1,29 @@ +'use client' +import type { FC } from 'react' +import React from 'react' +import type { Plugin } from '../../../types' +import Loading from './loading' +import LoadedItem from './loaded-item' + +type Props = { + checked: boolean + onCheckedChange: (plugin: Plugin) => void + payload?: Plugin +} + +const MarketPlaceItem: FC = ({ + checked, + onCheckedChange, + payload, +}) => { + if (!payload) return + return ( + + ) +} + +export default React.memo(MarketPlaceItem) diff --git a/web/app/components/plugins/install-plugin/install-bundle/steps/install-by-dsl-list.tsx b/web/app/components/plugins/install-plugin/install-bundle/steps/install-by-dsl-list.tsx new file mode 100644 index 0000000000..eae9394dc1 --- /dev/null +++ b/web/app/components/plugins/install-plugin/install-bundle/steps/install-by-dsl-list.tsx @@ -0,0 +1,83 @@ +'use client' +import type { FC } from 'react' +import React, { useCallback, useEffect, useMemo } from 'react' +import type { Dependency, Plugin } from '../../../types' +import MarketplaceItem from '../item/marketplace-item' +import GithubItem from '../item/github-item' +import { useFetchPluginsInMarketPlaceByIds } from '@/service/use-plugins' +import produce from 'immer' +import { useGetState } from 'ahooks' + +type Props = { + fromDSLPayload: Dependency[] + selectedPlugins: Plugin[] + handleSelect: (plugin: Plugin) => void + onLoadedAllPlugin: () => void +} + +const InstallByDSLList: FC = ({ + fromDSLPayload, + selectedPlugins, + handleSelect, + onLoadedAllPlugin, +}) => { + const { isLoading: isFetchingMarketplaceData, data: marketplaceRes } = useFetchPluginsInMarketPlaceByIds(fromDSLPayload.filter(d => d.type === 'marketplace').map(d => d.value.plugin_unique_identifier!)) + const [plugins, setPlugins, getPlugins] = useGetState([]) + const handlePlugInFetched = useCallback((index: number) => { + return (p: Plugin) => { + setPlugins(plugins.map((item, i) => i === index ? p : item)) + } + }, [plugins]) + + const marketPlaceInDSLIndex = useMemo(() => { + const res: number[] = [] + fromDSLPayload.forEach((d, index) => { + if (d.type === 'marketplace') + res.push(index) + }) + return res + }, [fromDSLPayload]) + + useEffect(() => { + if (!isFetchingMarketplaceData && marketplaceRes?.data.plugins && marketplaceRes?.data.plugins.length > 0) { + const payloads = marketplaceRes?.data.plugins + + const nextPlugins = produce(getPlugins(), (draft) => { + marketPlaceInDSLIndex.forEach((index, i) => { + draft[index] = payloads[i] + }) + }) + setPlugins(nextPlugins) + // marketplaceRes?.data.plugins + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [isFetchingMarketplaceData]) + + const isLoadedAllData = fromDSLPayload.length === plugins.length && plugins.every(p => !!p) + useEffect(() => { + if (isLoadedAllData) + onLoadedAllPlugin() + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [isLoadedAllData]) + return ( + <> + {fromDSLPayload.map((d, index) => ( + d.type === 'github' + ? p.plugin_id === d.value.plugin_unique_identifier)} + onCheckedChange={handleSelect} + dependency={d} + onFetchedPayload={handlePlugInFetched(index)} + /> + : p.plugin_id === d.value.plugin_unique_identifier)} + onCheckedChange={handleSelect} + payload={plugins[index] as Plugin} + /> + ))} + + ) +} +export default React.memo(InstallByDSLList) diff --git a/web/app/components/plugins/install-plugin/install-bundle/steps/install.tsx b/web/app/components/plugins/install-plugin/install-bundle/steps/install.tsx index 9b0e996f82..1423e399b8 100644 --- a/web/app/components/plugins/install-plugin/install-bundle/steps/install.tsx +++ b/web/app/components/plugins/install-plugin/install-bundle/steps/install.tsx @@ -1,41 +1,42 @@ 'use client' import type { FC } from 'react' -import React from 'react' -import type { PluginDeclaration } from '../../../types' -import Card from '../../../card' +import React, { useCallback } from 'react' +import type { Dependency, Plugin } from '../../../types' import Button from '@/app/components/base/button' import { RiLoader2Line } from '@remixicon/react' -import Badge, { BadgeState } from '@/app/components/base/badge/index' -import { pluginManifestToCardPluginProps } from '../../utils' import { useTranslation } from 'react-i18next' -import Checkbox from '@/app/components/base/checkbox' +import InstallByDSLList from './install-by-dsl-list' const i18nPrefix = 'plugin.installModal' type Props = { - plugins: PluginDeclaration[], + fromDSLPayload: Dependency[] onCancel: () => void } const Install: FC = ({ - plugins, + fromDSLPayload, onCancel, }) => { const { t } = useTranslation() - const [selectedPlugins, setSelectedPlugins] = React.useState([]) + const [selectedPlugins, setSelectedPlugins] = React.useState([]) const selectedPluginsNum = selectedPlugins.length - const handleSelect = (plugin: PluginDeclaration) => { + + const handleSelect = (plugin: Plugin) => { return () => { - const isSelected = !!selectedPlugins.find(p => p.plugin_unique_identifier === plugin.plugin_unique_identifier) + const isSelected = !!selectedPlugins.find(p => p.plugin_id === plugin.plugin_id) let nextSelectedPlugins if (isSelected) - nextSelectedPlugins = selectedPlugins.filter(p => p.plugin_unique_identifier !== plugin.plugin_unique_identifier) + nextSelectedPlugins = selectedPlugins.filter(p => p.plugin_id !== plugin.plugin_id) else nextSelectedPlugins = [...selectedPlugins, plugin] setSelectedPlugins(nextSelectedPlugins) } } - const [isInstalling, setIsInstalling] = React.useState(false) + const [canInstall, setCanInstall] = React.useState(false) + const handleLoadedAllPlugin = useCallback(() => { + setCanInstall(true) + }, []) const handleInstall = () => { } @@ -46,25 +47,17 @@ const Install: FC = ({

{t(`${i18nPrefix}.${selectedPluginsNum > 1 ? 'readyToInstallPackages' : 'readyToInstallPackage'}`, { num: selectedPluginsNum })}

- {plugins.map(plugin => ( -
- p.plugin_unique_identifier === plugin.plugin_unique_identifier)} - onCheck={handleSelect(plugin)} - /> - {plugin.version}} - /> -
- ))} +
{/* Action Buttons */}
- {!isInstalling && ( + {!canInstall && ( @@ -72,11 +65,11 @@ const Install: FC = ({
diff --git a/web/service/use-plugins.ts b/web/service/use-plugins.ts index c9f8058e8f..196f9bd5ff 100644 --- a/web/service/use-plugins.ts +++ b/web/service/use-plugins.ts @@ -7,6 +7,7 @@ import type { Permissions, PluginTask, PluginsFromMarketplaceResponse, + uploadGitHubResponse, } from '@/app/components/plugins/types' import type { PluginsSearchParams, @@ -60,6 +61,19 @@ export const useInstallPackageFromLocal = () => { }) } +export const useUploadGitHub = (payload: { + repo: string + version: string + package: string +}) => { + return useQuery({ + queryKey: [NAME_SPACE, 'uploadGitHub', payload], + queryFn: () => post('/workspaces/current/plugin/upload/github', { + body: payload, + }), + }) +} + export const useDebugKey = () => { return useQuery({ queryKey: [NAME_SPACE, 'debugKey'], @@ -123,6 +137,17 @@ export const useMutationPluginsFromMarketplace = () => { }) } +export const useFetchPluginsInMarketPlaceByIds = (unique_identifiers: string[]) => { + return useQuery({ + queryKey: [NAME_SPACE, 'fetchPluginsInMarketPlaceByIds', unique_identifiers], + queryFn: () => postMarketplace<{ data: PluginsFromMarketplaceResponse }>('/plugins/identifier/batch', { + body: { + unique_identifiers, + }, + }), + }) +} + const usePluginTaskListKey = [NAME_SPACE, 'pluginTaskList'] export const usePluginTaskList = () => { const [enabled, setEnabled] = useState(true) From 6af51701de86b80fe0ee00c9e49a7315733450c9 Mon Sep 17 00:00:00 2001 From: StyleZhang Date: Thu, 14 Nov 2024 18:18:10 +0800 Subject: [PATCH 64/68] fix: card link --- web/app/components/plugins/marketplace/list/card-wrapper.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/app/components/plugins/marketplace/list/card-wrapper.tsx b/web/app/components/plugins/marketplace/list/card-wrapper.tsx index d8e9bcb61c..b58afa051f 100644 --- a/web/app/components/plugins/marketplace/list/card-wrapper.tsx +++ b/web/app/components/plugins/marketplace/list/card-wrapper.tsx @@ -79,7 +79,7 @@ const CardWrapper = ({ return ( Date: Thu, 14 Nov 2024 18:26:16 +0800 Subject: [PATCH 65/68] chore: update the plugins tab button --- .../components/header/plugins-nav/index.tsx | 9 ++++++++- .../install-from-github/steps/loaded.tsx | 10 ++++++---- .../components/plugins/plugin-page/index.tsx | 4 ++-- web/i18n/en-US/plugin.ts | 1 + web/i18n/zh-Hans/plugin.ts | 1 + web/service/plugins.ts | 11 ---------- web/service/use-plugins.ts | 20 +++++++++++++++++++ 7 files changed, 38 insertions(+), 18 deletions(-) diff --git a/web/app/components/header/plugins-nav/index.tsx b/web/app/components/header/plugins-nav/index.tsx index 7cef0ce6fb..8bc654d860 100644 --- a/web/app/components/header/plugins-nav/index.tsx +++ b/web/app/components/header/plugins-nav/index.tsx @@ -4,6 +4,8 @@ import { useTranslation } from 'react-i18next' import Link from 'next/link' import classNames from '@/utils/classnames' import { Group } from '@/app/components/base/icons/src/vender/other' +import { useSelectedLayoutSegment } from 'next/navigation' + type PluginsNavProps = { className?: string } @@ -12,12 +14,17 @@ const PluginsNav = ({ className, }: PluginsNavProps) => { const { t } = useTranslation() + const selectedSegment = useSelectedLayoutSegment() + const activated = selectedSegment === 'plugins' return ( -
+
diff --git a/web/app/components/plugins/install-plugin/install-from-github/steps/loaded.tsx b/web/app/components/plugins/install-plugin/install-from-github/steps/loaded.tsx index 6338e387f7..6b63c24aea 100644 --- a/web/app/components/plugins/install-plugin/install-from-github/steps/loaded.tsx +++ b/web/app/components/plugins/install-plugin/install-from-github/steps/loaded.tsx @@ -7,7 +7,8 @@ import Card from '../../../card' import Badge, { BadgeState } from '@/app/components/base/badge/index' import { pluginManifestToCardPluginProps } from '../../utils' import { useTranslation } from 'react-i18next' -import { installPackageFromGitHub, updateFromGitHub } from '@/service/plugins' +import { updateFromGitHub } from '@/service/plugins' +import { useInstallPackageFromGitHub } from '@/service/use-plugins' import { RiLoader2Line } from '@remixicon/react' import { usePluginTaskList } from '@/service/use-plugins' import checkTaskStatus from '../../base/check-task-status' @@ -40,6 +41,7 @@ const Loaded: React.FC = ({ }) => { const { t } = useTranslation() const [isInstalling, setIsInstalling] = React.useState(false) + const { mutateAsync: installPackageFromGitHub } = useInstallPackageFromGitHub() const { handleRefetch } = usePluginTaskList() const { check } = checkTaskStatus() @@ -72,12 +74,12 @@ const Loaded: React.FC = ({ onInstalled() } else { - const { all_installed: isInstalled, task_id: taskId } = await installPackageFromGitHub( - `${owner}/${repo}`, + const { all_installed: isInstalled, task_id: taskId } = await installPackageFromGitHub({ + repoUrl: `${owner}/${repo}`, selectedVersion, selectedPackage, uniqueIdentifier, - ) + }) if (isInstalled) { onInstalled() diff --git a/web/app/components/plugins/plugin-page/index.tsx b/web/app/components/plugins/plugin-page/index.tsx index 2cba8cf939..d089d37543 100644 --- a/web/app/components/plugins/plugin-page/index.tsx +++ b/web/app/components/plugins/plugin-page/index.tsx @@ -132,7 +132,7 @@ const PluginPage = ({ options={options} />
-
+
{canManagement && ( - Drop plugin package here to install + {t('plugin.installModal.dropPluginToInstall')}
{currentFile && ( trusted source.', + dropPluginToInstall: 'Drop plugin package here to install', labels: { repository: 'Repository', version: 'Version', diff --git a/web/i18n/zh-Hans/plugin.ts b/web/i18n/zh-Hans/plugin.ts index f3c34a8219..2e9f234af6 100644 --- a/web/i18n/zh-Hans/plugin.ts +++ b/web/i18n/zh-Hans/plugin.ts @@ -103,6 +103,7 @@ const translation = { readyToInstallPackage: '即将安装以下插件', readyToInstallPackages: '即将安装以下 {{num}} 个插件', fromTrustSource: '请保证仅从可信源安装插件。', + dropPluginToInstall: '拖放插件包到此处安装', labels: { repository: '仓库', version: '版本', diff --git a/web/service/plugins.ts b/web/service/plugins.ts index 4782738be5..46a90b885c 100644 --- a/web/service/plugins.ts +++ b/web/service/plugins.ts @@ -54,17 +54,6 @@ export const uploadGitHub = async (repoUrl: string, selectedVersion: string, sel }) } -export const installPackageFromGitHub = async (repoUrl: string, selectedVersion: string, selectedPackage: string, uniqueIdentifier: string) => { - return post('/workspaces/current/plugin/install/github', { - body: { - repo: repoUrl, - version: selectedVersion, - package: selectedPackage, - plugin_unique_identifier: uniqueIdentifier, - }, - }) -} - export const fetchIcon = (tenantId: string, fileName: string) => { return get(`workspaces/current/plugin/icon?tenant_id=${tenantId}&filename=${fileName}`) } diff --git a/web/service/use-plugins.ts b/web/service/use-plugins.ts index c9f8058e8f..5de2b5f7fd 100644 --- a/web/service/use-plugins.ts +++ b/web/service/use-plugins.ts @@ -60,6 +60,26 @@ export const useInstallPackageFromLocal = () => { }) } +export const useInstallPackageFromGitHub = () => { + return useMutation({ + mutationFn: ({ repoUrl, selectedVersion, selectedPackage, uniqueIdentifier }: { + repoUrl: string + selectedVersion: string + selectedPackage: string + uniqueIdentifier: string + }) => { + return post('/workspaces/current/plugin/install/github', { + body: { + repo: repoUrl, + version: selectedVersion, + package: selectedPackage, + plugin_unique_identifier: uniqueIdentifier, + }, + }) + }, + }) +} + export const useDebugKey = () => { return useQuery({ queryKey: [NAME_SPACE, 'debugKey'], From 6f5e010db54a6c8e388031b4d140835a4b110aba Mon Sep 17 00:00:00 2001 From: Joel Date: Thu, 14 Nov 2024 18:31:10 +0800 Subject: [PATCH 66/68] chore: handle uploaded selected --- .../install-bundle/item/loaded-item.tsx | 2 +- .../install-bundle/steps/install-by-dsl-list.tsx | 4 ++-- .../install-bundle/steps/install.tsx | 16 +++++++--------- 3 files changed, 10 insertions(+), 12 deletions(-) diff --git a/web/app/components/plugins/install-plugin/install-bundle/item/loaded-item.tsx b/web/app/components/plugins/install-plugin/install-bundle/item/loaded-item.tsx index 94a9071dae..ef083b6924 100644 --- a/web/app/components/plugins/install-plugin/install-bundle/item/loaded-item.tsx +++ b/web/app/components/plugins/install-plugin/install-bundle/item/loaded-item.tsx @@ -27,7 +27,7 @@ const LoadedItem: FC = ({ {payload.version}} + titleLeft={payload.version ? {payload.version} : null} />
) diff --git a/web/app/components/plugins/install-plugin/install-bundle/steps/install-by-dsl-list.tsx b/web/app/components/plugins/install-plugin/install-bundle/steps/install-by-dsl-list.tsx index eae9394dc1..a7ab97ab6a 100644 --- a/web/app/components/plugins/install-plugin/install-bundle/steps/install-by-dsl-list.tsx +++ b/web/app/components/plugins/install-plugin/install-bundle/steps/install-by-dsl-list.tsx @@ -65,14 +65,14 @@ const InstallByDSLList: FC = ({ d.type === 'github' ? p.plugin_id === d.value.plugin_unique_identifier)} + checked={!!selectedPlugins.find(p => p.plugin_id === plugins[index]?.plugin_id)} onCheckedChange={handleSelect} dependency={d} onFetchedPayload={handlePlugInFetched(index)} /> : p.plugin_id === d.value.plugin_unique_identifier)} + checked={!!selectedPlugins.find(p => p.plugin_id === plugins[index]?.plugin_id)} onCheckedChange={handleSelect} payload={plugins[index] as Plugin} /> diff --git a/web/app/components/plugins/install-plugin/install-bundle/steps/install.tsx b/web/app/components/plugins/install-plugin/install-bundle/steps/install.tsx index 1423e399b8..e3610f6d98 100644 --- a/web/app/components/plugins/install-plugin/install-bundle/steps/install.tsx +++ b/web/app/components/plugins/install-plugin/install-bundle/steps/install.tsx @@ -23,15 +23,13 @@ const Install: FC = ({ const selectedPluginsNum = selectedPlugins.length const handleSelect = (plugin: Plugin) => { - return () => { - const isSelected = !!selectedPlugins.find(p => p.plugin_id === plugin.plugin_id) - let nextSelectedPlugins - if (isSelected) - nextSelectedPlugins = selectedPlugins.filter(p => p.plugin_id !== plugin.plugin_id) - else - nextSelectedPlugins = [...selectedPlugins, plugin] - setSelectedPlugins(nextSelectedPlugins) - } + const isSelected = !!selectedPlugins.find(p => p.plugin_id === plugin.plugin_id) + let nextSelectedPlugins + if (isSelected) + nextSelectedPlugins = selectedPlugins.filter(p => p.plugin_id !== plugin.plugin_id) + else + nextSelectedPlugins = [...selectedPlugins, plugin] + setSelectedPlugins(nextSelectedPlugins) } const [canInstall, setCanInstall] = React.useState(false) const handleLoadedAllPlugin = useCallback(() => { From 73ce8a17a5657ae4c5afb6130690757807cf4a7d Mon Sep 17 00:00:00 2001 From: Joel Date: Fri, 15 Nov 2024 10:39:57 +0800 Subject: [PATCH 67/68] feat: add loading --- .../components/plugins/card/base/placeholder.tsx | 8 ++++++-- .../install-bundle/item/loading.tsx | 15 +++++++++++++-- 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/web/app/components/plugins/card/base/placeholder.tsx b/web/app/components/plugins/card/base/placeholder.tsx index a8b106a40b..96b83f152e 100644 --- a/web/app/components/plugins/card/base/placeholder.tsx +++ b/web/app/components/plugins/card/base/placeholder.tsx @@ -4,7 +4,7 @@ import cn from '@/utils/classnames' type Props = { wrapClassName: string - loadingFileName: string + loadingFileName?: string } export const LoadingPlaceholder = ({ className }: { className?: string }) => ( @@ -27,7 +27,11 @@ const Placeholder = ({
- + {loadingFileName ? ( + <Title title={loadingFileName} /> + ) : ( + <LoadingPlaceholder className="w-[260px]" /> + )} </div> <div className={cn('flex items-center h-4 space-x-0.5')}> <LoadingPlaceholder className="w-[41px]" /> diff --git a/web/app/components/plugins/install-plugin/install-bundle/item/loading.tsx b/web/app/components/plugins/install-plugin/install-bundle/item/loading.tsx index e89022aad6..5e33363ecf 100644 --- a/web/app/components/plugins/install-plugin/install-bundle/item/loading.tsx +++ b/web/app/components/plugins/install-plugin/install-bundle/item/loading.tsx @@ -1,10 +1,21 @@ 'use client' import React from 'react' +import Placeholder from '../../../card/base/placeholder' +import Checkbox from '@/app/components/base/checkbox' const Loading = () => { return ( - <div> - Loading... + <div className='flex items-center space-x-2'> + <Checkbox + className='shrink-0' + checked={false} + disabled + /> + <div className='grow relative p-4 pb-3 border-[0.5px] border-components-panel-border bg-components-panel-on-panel-item-bg hover-bg-components-panel-on-panel-item-bg rounded-xl shadow-xs'> + <Placeholder + wrapClassName='w-full' + /> + </div> </div> ) } From 6699441e539b0bf67d6c27aab847b2751727d8d0 Mon Sep 17 00:00:00 2001 From: Joel <iamjoel007@gmail.com> Date: Fri, 15 Nov 2024 12:07:20 +0800 Subject: [PATCH 68/68] just add --- .../(commonLayout)/plugins/test/card/page.tsx | 6 ++++ .../steps/install-by-dsl-list.tsx | 15 +++++--- .../install-bundle/steps/install.tsx | 26 ++++++++++---- web/service/use-plugins.ts | 36 +++++++++++++++++++ 4 files changed, 72 insertions(+), 11 deletions(-) diff --git a/web/app/(commonLayout)/plugins/test/card/page.tsx b/web/app/(commonLayout)/plugins/test/card/page.tsx index 85a00d5af0..1d7817a982 100644 --- a/web/app/(commonLayout)/plugins/test/card/page.tsx +++ b/web/app/(commonLayout)/plugins/test/card/page.tsx @@ -28,6 +28,12 @@ const PluginList = () => { github_plugin_unique_identifier: 'yixiao0/test:0.0.1@3592166c87afcf944b4f13f27467a5c8f9e00bd349cb42033a072734a37431b4', }, }, + { + type: 'marketplace', + value: { + plugin_unique_identifier: 'langgenius/openai:0.0.1@f88fdb98d104466db16a425bfe3af8c1bcad45047a40fb802d98a989ac57a5a3', + }, + }, ]} /> <div className='mx-3 '> {/* <h2 className='my-3'>Dify Plugin list</h2> */} diff --git a/web/app/components/plugins/install-plugin/install-bundle/steps/install-by-dsl-list.tsx b/web/app/components/plugins/install-plugin/install-bundle/steps/install-by-dsl-list.tsx index a7ab97ab6a..8442c0a13d 100644 --- a/web/app/components/plugins/install-plugin/install-bundle/steps/install-by-dsl-list.tsx +++ b/web/app/components/plugins/install-plugin/install-bundle/steps/install-by-dsl-list.tsx @@ -11,17 +11,18 @@ import { useGetState } from 'ahooks' type Props = { fromDSLPayload: Dependency[] selectedPlugins: Plugin[] - handleSelect: (plugin: Plugin) => void + onSelect: (plugin: Plugin, selectedIndex: number) => void onLoadedAllPlugin: () => void } const InstallByDSLList: FC<Props> = ({ fromDSLPayload, selectedPlugins, - handleSelect, + onSelect, onLoadedAllPlugin, }) => { const { isLoading: isFetchingMarketplaceData, data: marketplaceRes } = useFetchPluginsInMarketPlaceByIds(fromDSLPayload.filter(d => d.type === 'marketplace').map(d => d.value.plugin_unique_identifier!)) + const [plugins, setPlugins, getPlugins] = useGetState<Plugin[]>([]) const handlePlugInFetched = useCallback((index: number) => { return (p: Plugin) => { @@ -59,6 +60,12 @@ const InstallByDSLList: FC<Props> = ({ onLoadedAllPlugin() // eslint-disable-next-line react-hooks/exhaustive-deps }, [isLoadedAllData]) + + const handleSelect = useCallback((index: number) => { + return () => { + onSelect(plugins[index], index) + } + }, [onSelect, plugins]) return ( <> {fromDSLPayload.map((d, index) => ( @@ -66,14 +73,14 @@ const InstallByDSLList: FC<Props> = ({ ? <GithubItem key={index} checked={!!selectedPlugins.find(p => p.plugin_id === plugins[index]?.plugin_id)} - onCheckedChange={handleSelect} + onCheckedChange={handleSelect(index)} dependency={d} onFetchedPayload={handlePlugInFetched(index)} /> : <MarketplaceItem key={index} checked={!!selectedPlugins.find(p => p.plugin_id === plugins[index]?.plugin_id)} - onCheckedChange={handleSelect} + onCheckedChange={handleSelect(index)} payload={plugins[index] as Plugin} /> ))} diff --git a/web/app/components/plugins/install-plugin/install-bundle/steps/install.tsx b/web/app/components/plugins/install-plugin/install-bundle/steps/install.tsx index e3610f6d98..1ac7f95746 100644 --- a/web/app/components/plugins/install-plugin/install-bundle/steps/install.tsx +++ b/web/app/components/plugins/install-plugin/install-bundle/steps/install.tsx @@ -6,6 +6,7 @@ import Button from '@/app/components/base/button' import { RiLoader2Line } from '@remixicon/react' import { useTranslation } from 'react-i18next' import InstallByDSLList from './install-by-dsl-list' +import { useInstallFromMarketplaceAndGitHub } from '@/service/use-plugins' const i18nPrefix = 'plugin.installModal' @@ -20,9 +21,10 @@ const Install: FC<Props> = ({ }) => { const { t } = useTranslation() const [selectedPlugins, setSelectedPlugins] = React.useState<Plugin[]>([]) + const [selectedIndexes, setSelectedIndexes] = React.useState<number[]>([]) const selectedPluginsNum = selectedPlugins.length - const handleSelect = (plugin: Plugin) => { + const handleSelect = (plugin: Plugin, selectedIndex: number) => { const isSelected = !!selectedPlugins.find(p => p.plugin_id === plugin.plugin_id) let nextSelectedPlugins if (isSelected) @@ -30,13 +32,23 @@ const Install: FC<Props> = ({ else nextSelectedPlugins = [...selectedPlugins, plugin] setSelectedPlugins(nextSelectedPlugins) + const nextSelectedIndexes = isSelected ? selectedIndexes.filter(i => i !== selectedIndex) : [...selectedIndexes, selectedIndex] + setSelectedIndexes(nextSelectedIndexes) } const [canInstall, setCanInstall] = React.useState(false) const handleLoadedAllPlugin = useCallback(() => { setCanInstall(true) - }, []) - const handleInstall = () => { + }, [selectedPlugins, selectedIndexes]) + // Install from marketplace and github + const { mutate: installFromMarketplaceAndGitHub, isPending: isInstalling } = useInstallFromMarketplaceAndGitHub({ + onSuccess: () => { + console.log('success!') + }, + }) + console.log(canInstall, !isInstalling, selectedPlugins.length === 0) + const handleInstall = () => { + installFromMarketplaceAndGitHub(fromDSLPayload.filter((_d, index) => selectedIndexes.includes(index))) } return ( <> @@ -48,7 +60,7 @@ const Install: FC<Props> = ({ <InstallByDSLList fromDSLPayload={fromDSLPayload} selectedPlugins={selectedPlugins} - handleSelect={handleSelect} + onSelect={handleSelect} onLoadedAllPlugin={handleLoadedAllPlugin} /> </div> @@ -63,11 +75,11 @@ const Install: FC<Props> = ({ <Button variant='primary' className='min-w-[72px] flex space-x-0.5' - disabled={canInstall || selectedPlugins.length === 0} + disabled={!canInstall || isInstalling || selectedPlugins.length === 0} onClick={handleInstall} > - {canInstall && <RiLoader2Line className='w-4 h-4 animate-spin-slow' />} - <span>{t(`${i18nPrefix}.${canInstall ? 'installing' : 'install'}`)}</span> + {isInstalling && <RiLoader2Line className='w-4 h-4 animate-spin-slow' />} + <span>{t(`${i18nPrefix}.${isInstalling ? 'installing' : 'install'}`)}</span> </Button> </div> </> diff --git a/web/service/use-plugins.ts b/web/service/use-plugins.ts index c071d4a993..6697948877 100644 --- a/web/service/use-plugins.ts +++ b/web/service/use-plugins.ts @@ -94,6 +94,42 @@ export const useUploadGitHub = (payload: { }) } +export const useInstallFromMarketplaceAndGitHub = ({ + onSuccess, +}: { + onSuccess?: () => void +}) => { + return useMutation({ + mutationFn: (payload: Dependency[]) => { + return Promise.all(payload.map(async (item) => { + try { + if (item.type === 'github') { + await post<InstallPackageResponse>('/workspaces/current/plugin/install/github', { + body: { + repo: item.value.repo!, + version: item.value.version!, + package: item.value.package!, + plugin_unique_identifier: item.value.github_plugin_unique_identifier!, + }, + }) + return ({ success: true }) + } + await post<InstallPackageResponse>('/workspaces/current/plugin/install/marketplace', { + body: { + plugin_unique_identifiers: [item.value.plugin_unique_identifier!], + }, + }) + return ({ success: true }) + } + catch (e) { + return Promise.resolve({ success: false }) + } + })) + }, + onSuccess, + }) +} + export const useDebugKey = () => { return useQuery({ queryKey: [NAME_SPACE, 'debugKey'],