diff --git a/web/app/components/app/configuration/config/agent/agent-tools/setting-built-in-tool.tsx b/web/app/components/app/configuration/config/agent/agent-tools/setting-built-in-tool.tsx index 75183ab5a7..952ad66fc4 100644 --- a/web/app/components/app/configuration/config/agent/agent-tools/setting-built-in-tool.tsx +++ b/web/app/components/app/configuration/config/agent/agent-tools/setting-built-in-tool.tsx @@ -163,7 +163,7 @@ const SettingBuiltInTool: FC = ({ footer={null} mask={false} positionCenter={false} - panelClassname={cn('mb-2 mr-2 mt-[64px] !w-[420px] !max-w-[420px] justify-start rounded-2xl border-[0.5px] border-components-panel-border !bg-components-panel-bg !p-0 shadow-xl')} + panelClassName={cn('mb-2 mr-2 mt-[64px] !w-[420px] !max-w-[420px] justify-start rounded-2xl border-[0.5px] border-components-panel-border !bg-components-panel-bg !p-0 shadow-xl')} > <> {isLoading && } diff --git a/web/app/components/app/configuration/dataset-config/card-item/item.tsx b/web/app/components/app/configuration/dataset-config/card-item/item.tsx index d44fb145bb..65ad2ca941 100644 --- a/web/app/components/app/configuration/dataset-config/card-item/item.tsx +++ b/web/app/components/app/configuration/dataset-config/card-item/item.tsx @@ -97,7 +97,7 @@ const Item: FC = ({ - setShowSettingsModal(false)} footer={null} mask={isMobile} panelClassname='mt-16 mx-2 sm:mr-2 mb-3 !p-0 !max-w-[640px] rounded-xl'> + setShowSettingsModal(false)} footer={null} mask={isMobile} panelClassName='mt-16 mx-2 sm:mr-2 mb-3 !p-0 !max-w-[640px] rounded-xl'> setShowSettingsModal(false)} diff --git a/web/app/components/app/configuration/dataset-config/settings-modal/index.tsx b/web/app/components/app/configuration/dataset-config/settings-modal/index.tsx index 90885dacc8..645f6045f0 100644 --- a/web/app/components/app/configuration/dataset-config/settings-modal/index.tsx +++ b/web/app/components/app/configuration/dataset-config/settings-modal/index.tsx @@ -62,13 +62,13 @@ const SettingsModal: FC = ({ const { notify } = useToastContext() const ref = useRef(null) const isExternal = currentDataset.provider === 'external' - const [topK, setTopK] = useState(currentDataset?.external_retrieval_model.top_k ?? 2) - const [scoreThreshold, setScoreThreshold] = useState(currentDataset?.external_retrieval_model.score_threshold ?? 0.5) - const [scoreThresholdEnabled, setScoreThresholdEnabled] = useState(currentDataset?.external_retrieval_model.score_threshold_enabled ?? false) const { setShowAccountSettingModal } = useModalContext() const [loading, setLoading] = useState(false) const { isCurrentWorkspaceDatasetOperator } = useAppContext() const [localeCurrentDataset, setLocaleCurrentDataset] = useState({ ...currentDataset }) + const [topK, setTopK] = useState(localeCurrentDataset?.external_retrieval_model.top_k ?? 2) + const [scoreThreshold, setScoreThreshold] = useState(localeCurrentDataset?.external_retrieval_model.score_threshold ?? 0.5) + const [scoreThresholdEnabled, setScoreThresholdEnabled] = useState(localeCurrentDataset?.external_retrieval_model.score_threshold_enabled ?? false) const [selectedMemberIDs, setSelectedMemberIDs] = useState(currentDataset.partial_member_list || []) const [memberList, setMemberList] = useState([]) @@ -88,6 +88,14 @@ const SettingsModal: FC = ({ setScoreThreshold(data.score_threshold) if (data.score_threshold_enabled !== undefined) setScoreThresholdEnabled(data.score_threshold_enabled) + + setLocaleCurrentDataset({ + ...localeCurrentDataset, + external_retrieval_model: { + ...localeCurrentDataset?.external_retrieval_model, + ...data, + }, + }) } const handleSave = async () => { diff --git a/web/app/components/app/log/list.tsx b/web/app/components/app/log/list.tsx index b78af5cdba..056ce84f1e 100644 --- a/web/app/components/app/log/list.tsx +++ b/web/app/components/app/log/list.tsx @@ -743,7 +743,7 @@ const ConversationList: FC = ({ logs, appDetail, onRefresh }) onClose={onCloseDrawer} mask={isMobile} footer={null} - panelClassname='mt-16 mx-2 sm:mr-2 mb-4 !p-0 !max-w-[640px] rounded-xl bg-components-panel-bg' + panelClassName='mt-16 mx-2 sm:mr-2 mb-4 !p-0 !max-w-[640px] rounded-xl bg-components-panel-bg' > = ({ logs, appDetail, onRefresh }) => { onClose={onCloseDrawer} mask={isMobile} footer={null} - panelClassname='mt-16 mx-2 sm:mr-2 mb-3 !p-0 !max-w-[600px] rounded-xl border border-components-panel-border' + panelClassName='mt-16 mx-2 sm:mr-2 mb-3 !p-0 !max-w-[600px] rounded-xl border border-components-panel-border' > diff --git a/web/app/components/base/chat/embedded-chatbot/hooks.tsx b/web/app/components/base/chat/embedded-chatbot/hooks.tsx index d6a7b230e4..0f2529152c 100644 --- a/web/app/components/base/chat/embedded-chatbot/hooks.tsx +++ b/web/app/components/base/chat/embedded-chatbot/hooks.tsx @@ -80,8 +80,30 @@ export const useEmbeddedChatbot = () => { }, []) useEffect(() => { - if (appInfo?.site.default_language) - changeLanguage(appInfo.site.default_language) + const setLanguageFromParams = async () => { + // Check URL parameters for language override + const urlParams = new URLSearchParams(window.location.search) + const localeParam = urlParams.get('locale') + + // Check for encoded system variables + const systemVariables = await getProcessedSystemVariablesFromUrlParams() + const localeFromSysVar = systemVariables.locale + + if (localeParam) { + // If locale parameter exists in URL, use it instead of default + changeLanguage(localeParam) + } + else if (localeFromSysVar) { + // If locale is set as a system variable, use that + changeLanguage(localeFromSysVar) + } + else if (appInfo?.site.default_language) { + // Otherwise use the default from app config + changeLanguage(appInfo.site.default_language) + } + } + + setLanguageFromParams() }, [appInfo]) const [conversationIdInfo, setConversationIdInfo] = useLocalStorageState>>(CONVERSATION_ID_INFO, { diff --git a/web/app/components/base/drawer-plus/index.tsx b/web/app/components/base/drawer-plus/index.tsx index bb022acdcb..33a1948181 100644 --- a/web/app/components/base/drawer-plus/index.tsx +++ b/web/app/components/base/drawer-plus/index.tsx @@ -9,6 +9,8 @@ import useBreakpoints, { MediaType } from '@/hooks/use-breakpoints' type Props = { isShow: boolean onHide: () => void + dialogClassName?: string + dialogBackdropClassName?: string panelClassName?: string maxWidthClassName?: string contentClassName?: string @@ -26,6 +28,8 @@ type Props = { const DrawerPlus: FC = ({ isShow, onHide, + dialogClassName = '', + dialogBackdropClassName = '', panelClassName = '', maxWidthClassName = '!max-w-[640px]', height = 'calc(100vh - 72px)', @@ -55,7 +59,9 @@ const DrawerPlus: FC = ({ footer={null} mask={isMobile || isShowMask} positionCenter={positionCenter} - panelClassname={cn('mx-2 mb-3 mt-16 rounded-xl !p-0 sm:mr-2', panelClassName, maxWidthClassName)} + dialogClassName={dialogClassName} + dialogBackdropClassName={dialogBackdropClassName} + panelClassName={cn('mx-2 mb-3 mt-16 rounded-xl !p-0 sm:mr-2', panelClassName, maxWidthClassName)} >
!clickOutsideNotOpen && onClose()} - className="fixed inset-0 z-[80] overflow-y-auto" + className={cn('fixed inset-0 z-[30] overflow-y-auto', dialogClassName)} >
{/* mask */} { !clickOutsideNotOpen && onClose() }} /> -
+
<>
{title && { return
} -const Link = ({ node, ...props }: any) => { +const Link = ({ node, children, ...props }: any) => { if (node.properties?.href && node.properties.href?.toString().startsWith('abbr')) { // eslint-disable-next-line react-hooks/rules-of-hooks const { onSend } = useChatContext() @@ -261,7 +261,7 @@ const Link = ({ node, ...props }: any) => { return onSend?.(hidden_text)} title={node.children[0]?.value}>{node.children[0]?.value} } else { - return {node.children[0] ? node.children[0]?.value : 'Download'} + return {children || 'Download'} } } diff --git a/web/app/components/base/prompt-editor/plugins/component-picker-block/index.tsx b/web/app/components/base/prompt-editor/plugins/component-picker-block/index.tsx index d7a3a81417..562bb8c0d9 100644 --- a/web/app/components/base/prompt-editor/plugins/component-picker-block/index.tsx +++ b/web/app/components/base/prompt-editor/plugins/component-picker-block/index.tsx @@ -31,6 +31,7 @@ import { useOptions } from './hooks' import type { PickerBlockMenuOption } from './menu' import VarReferenceVars from '@/app/components/workflow/nodes/_base/components/variable/var-reference-vars' import { useEventEmitterContextContext } from '@/context/event-emitter' +import { KEY_ESCAPE_COMMAND } from 'lexical' type ComponentPickerProps = { triggerString: string @@ -118,6 +119,13 @@ const ComponentPicker = ({ editor.dispatchCommand(INSERT_WORKFLOW_VARIABLE_BLOCK_COMMAND, variables) }, [editor, checkForTriggerMatch, triggerString]) + const handleClose = useCallback(() => { + ReactDOM.flushSync(() => { + const escapeEvent = new KeyboardEvent('keydown', { key: 'Escape' }) + editor.dispatchCommand(KEY_ESCAPE_COMMAND, escapeEvent) + }) + }, [editor]) + const renderMenu = useCallback>(( anchorElementRef, { options, selectedIndex, selectOptionAndCleanUp, setHighlightedIndex }, @@ -141,51 +149,54 @@ const ComponentPicker = ({ visibility: isPositioned ? 'visible' : 'hidden', }} ref={refs.setFloating} + data-testid="component-picker-container" > { - options.map((option, index) => ( - - { - // Divider - index !== 0 && options.at(index - 1)?.group !== option.group && ( -
- ) - } - {option.renderMenuOption({ - queryString, - isSelected: selectedIndex === index, - onSelect: () => { - selectOptionAndCleanUp(option) - }, - onSetHighlight: () => { - setHighlightedIndex(index) - }, - })} -
- )) + workflowVariableBlock?.show && ( +
+ { + handleSelectWorkflowVariable(variables) + }} + maxHeightClass='max-h-[34vh]' + isSupportFileVar={isSupportFileVar} + onClose={handleClose} + onBlur={handleClose} + /> +
+ ) } { - workflowVariableBlock?.show && ( - <> - { - (!!options.length) && ( -
- ) - } -
- { - handleSelectWorkflowVariable(variables) - }} - maxHeightClass='max-h-[34vh]' - isSupportFileVar={isSupportFileVar} - /> -
- + workflowVariableBlock?.show && !!options.length && ( +
) } +
+ { + options.map((option, index) => ( + + { + // Divider + index !== 0 && options.at(index - 1)?.group !== option.group && ( +
+ ) + } + {option.renderMenuOption({ + queryString, + isSelected: selectedIndex === index, + onSelect: () => { + selectOptionAndCleanUp(option) + }, + onSetHighlight: () => { + setHighlightedIndex(index) + }, + })} +
+ )) + } +
, anchorElementRef.current, @@ -193,7 +204,7 @@ const ComponentPicker = ({ } ) - }, [allFlattenOptions.length, workflowVariableBlock?.show, refs, isPositioned, floatingStyles, queryString, workflowVariableOptions, handleSelectWorkflowVariable]) + }, [allFlattenOptions.length, workflowVariableBlock?.show, refs, isPositioned, floatingStyles, queryString, workflowVariableOptions, handleSelectWorkflowVariable, handleClose, isSupportFileVar]) return ( = ({ ), editor.registerCommand( BLUR_COMMAND, - () => { - ref.current = setTimeout(() => { - editor.dispatchCommand(KEY_ESCAPE_COMMAND, new KeyboardEvent('keydown', { key: 'Escape' })) - }, 200) - - if (onBlur) - onBlur() - + (event) => { + // Check if the clicked target element is var-search-input + const target = event?.relatedTarget as HTMLElement + if (!target?.classList?.contains('var-search-input')) { + ref.current = setTimeout(() => { + editor.dispatchCommand(KEY_ESCAPE_COMMAND, new KeyboardEvent('keydown', { key: 'Escape' })) + }, 200) + if (onBlur) + onBlur() + } return true }, COMMAND_PRIORITY_EDITOR, diff --git a/web/app/components/datasets/documents/detail/completed/common/full-screen-drawer.tsx b/web/app/components/datasets/documents/detail/completed/common/full-screen-drawer.tsx index 64f5bd7033..277c42928c 100644 --- a/web/app/components/datasets/documents/detail/completed/common/full-screen-drawer.tsx +++ b/web/app/components/datasets/documents/detail/completed/common/full-screen-drawer.tsx @@ -20,7 +20,7 @@ const FullScreenDrawer: FC = ({ = ({ datasetId, documentId }) => { }
} - setShowMetadata(false)} isMobile={isMobile} panelClassname='!justify-start' footer={null}> + setShowMetadata(false)} isMobile={isMobile} panelClassName='!justify-start' footer={null}> = ({ datasetId }: Props) => { )}
- +
{/* {renderHitResults(generalResultData)} */} {submitLoading @@ -197,7 +197,7 @@ const HitTestingPage: FC = ({ datasetId }: Props) => { }
- setIsShowModifyRetrievalModal(false)} footer={null} mask={isMobile} panelClassname='mt-16 mx-2 sm:mr-2 mb-3 !p-0 !max-w-[640px] rounded-xl'> + setIsShowModifyRetrievalModal(false)} footer={null} mask={isMobile} panelClassName='mt-16 mx-2 sm:mr-2 mb-3 !p-0 !max-w-[640px] rounded-xl'> = ({ showClose title={t('dataset.metadata.metadata')} footer={null} - panelClassname='px-4 block !max-w-[420px] my-2 rounded-l-2xl' + panelClassName='px-4 block !max-w-[420px] my-2 rounded-l-2xl' >
{t(`${i18nPrefix}.description`)}
diff --git a/web/app/components/datasets/settings/permission-selector/index.tsx b/web/app/components/datasets/settings/permission-selector/index.tsx index 71a46087af..9bb6f812d4 100644 --- a/web/app/components/datasets/settings/permission-selector/index.tsx +++ b/web/app/components/datasets/settings/permission-selector/index.tsx @@ -150,8 +150,8 @@ const PermissionSelector = ({ disabled, permission, value, memberList, onChange,
{isPartialMembers && ( -
-
+
+
= ({ /> setSearchText(e.target.value)} /> diff --git a/web/app/components/plugins/marketplace/list/list-with-collection.tsx b/web/app/components/plugins/marketplace/list/list-with-collection.tsx index e18356cd85..4c396c565f 100644 --- a/web/app/components/plugins/marketplace/list/list-with-collection.tsx +++ b/web/app/components/plugins/marketplace/list/list-with-collection.tsx @@ -32,7 +32,9 @@ const ListWithCollection = ({ return ( <> { - marketplaceCollections.map(collection => ( + marketplaceCollections.filter((collection) => { + return marketplaceCollectionPluginsMap[collection.name]?.length + }).map(collection => (
= ({ footer={null} mask positionCenter={false} - panelClassname={cn('mb-2 mr-2 mt-[64px] !w-[420px] !max-w-[420px] justify-start rounded-2xl border-[0.5px] border-components-panel-border !bg-components-panel-bg !p-0 shadow-xl')} + panelClassName={cn('mb-2 mr-2 mt-[64px] !w-[420px] !max-w-[420px] justify-start rounded-2xl border-[0.5px] border-components-panel-border !bg-components-panel-bg !p-0 shadow-xl')} > <>
diff --git a/web/app/components/plugins/plugin-detail-panel/index.tsx b/web/app/components/plugins/plugin-detail-panel/index.tsx index 70bd9edabc..3ec867faae 100644 --- a/web/app/components/plugins/plugin-detail-panel/index.tsx +++ b/web/app/components/plugins/plugin-detail-panel/index.tsx @@ -38,7 +38,7 @@ const PluginDetailPanel: FC = ({ footer={null} mask={false} positionCenter={false} - panelClassname={cn('mb-2 mr-2 mt-[64px] !w-[420px] !max-w-[420px] justify-start rounded-2xl border-[0.5px] border-components-panel-border !bg-components-panel-bg !p-0 shadow-xl')} + panelClassName={cn('mb-2 mr-2 mt-[64px] !w-[420px] !max-w-[420px] justify-start rounded-2xl border-[0.5px] border-components-panel-border !bg-components-panel-bg !p-0 shadow-xl')} > {detail && ( <> diff --git a/web/app/components/plugins/plugin-detail-panel/strategy-detail.tsx b/web/app/components/plugins/plugin-detail-panel/strategy-detail.tsx index 89ee850e03..00794d83ed 100644 --- a/web/app/components/plugins/plugin-detail-panel/strategy-detail.tsx +++ b/web/app/components/plugins/plugin-detail-panel/strategy-detail.tsx @@ -78,7 +78,7 @@ const StrategyDetail: FC = ({ footer={null} mask={false} positionCenter={false} - panelClassname={cn('mb-2 mr-2 mt-[64px] !w-[420px] !max-w-[420px] justify-start rounded-2xl border-[0.5px] border-components-panel-border !bg-components-panel-bg !p-0 shadow-xl')} + panelClassName={cn('mb-2 mr-2 mt-[64px] !w-[420px] !max-w-[420px] justify-start rounded-2xl border-[0.5px] border-components-panel-border !bg-components-panel-bg !p-0 shadow-xl')} > <> {/* header */} diff --git a/web/app/components/tools/add-tool-modal/index.tsx b/web/app/components/tools/add-tool-modal/index.tsx index 1129fe55ce..c45313fc09 100644 --- a/web/app/components/tools/add-tool-modal/index.tsx +++ b/web/app/components/tools/add-tool-modal/index.tsx @@ -178,7 +178,7 @@ const AddToolModal: FC = ({ clickOutsideNotOpen onClose={onHide} footer={null} - panelClassname={cn('mx-2 mb-3 mt-16 rounded-xl !p-0 sm:mr-2', 'mt-2 !w-[640px]', '!max-w-[640px]')} + panelClassName={cn('mx-2 mb-3 mt-16 rounded-xl !p-0 sm:mr-2', 'mt-2 !w-[640px]', '!max-w-[640px]')} >
= ({ positionCenter={positionCenter} onHide={onHide} title={t('tools.createTool.authMethod.title')!} - panelClassName='mt-2 !w-[520px] h-fit' + dialogClassName='z-[60]' + dialogBackdropClassName='z-[70]' + panelClassName='mt-2 !w-[520px] h-fit z-[80]' maxWidthClassName='!max-w-[520px]' height={'fit-content'} headerClassName='!border-b-divider-regular' diff --git a/web/app/components/tools/provider/detail.tsx b/web/app/components/tools/provider/detail.tsx index 5d3a1794d8..21ea8bc464 100644 --- a/web/app/components/tools/provider/detail.tsx +++ b/web/app/components/tools/provider/detail.tsx @@ -234,7 +234,7 @@ const ProviderDetail = ({ footer={null} mask={false} positionCenter={false} - panelClassname={cn('mb-2 mr-2 mt-[64px] !w-[420px] !max-w-[420px] justify-start rounded-2xl border-[0.5px] border-components-panel-border !bg-components-panel-bg !p-0 shadow-xl')} + panelClassName={cn('mb-2 mr-2 mt-[64px] !w-[420px] !max-w-[420px] justify-start rounded-2xl border-[0.5px] border-components-panel-border !bg-components-panel-bg !p-0 shadow-xl')} >
diff --git a/web/app/components/workflow/nodes/_base/components/variable/var-reference-vars.tsx b/web/app/components/workflow/nodes/_base/components/variable/var-reference-vars.tsx index 751e1990cf..023916ec5b 100644 --- a/web/app/components/workflow/nodes/_base/components/variable/var-reference-vars.tsx +++ b/web/app/components/workflow/nodes/_base/components/variable/var-reference-vars.tsx @@ -258,6 +258,8 @@ type Props = { onChange: (value: ValueSelector, item: Var) => void itemWidth?: number maxHeightClass?: string + onClose?: () => void + onBlur?: () => void } const VarReferenceVars: FC = ({ hideSearch, @@ -267,10 +269,19 @@ const VarReferenceVars: FC = ({ onChange, itemWidth, maxHeightClass, + onClose, + onBlur, }) => { const { t } = useTranslation() const [searchText, setSearchText] = useState('') + const handleKeyDown = (e: React.KeyboardEvent) => { + if (e.key === 'Escape') { + e.preventDefault() + onClose?.() + } + } + const filteredVars = vars.filter((v) => { const children = v.vars.filter(v => checkKeys([v.variable], false).isValid || v.variable.startsWith('sys.') || v.variable.startsWith('env.') || v.variable.startsWith('conversation.')) return children.length > 0 @@ -301,14 +312,17 @@ const VarReferenceVars: FC = ({ { !hideSearch && ( <> -
e.stopPropagation()}> +
e.stopPropagation()}> setSearchText(e.target.value)} + onKeyDown={handleKeyDown} onClear={() => setSearchText('')} + onBlur={onBlur} autoFocus />
diff --git a/web/app/components/workflow/nodes/knowledge-retrieval/components/dataset-item.tsx b/web/app/components/workflow/nodes/knowledge-retrieval/components/dataset-item.tsx index e424ea8e1f..f8d2dcfc75 100644 --- a/web/app/components/workflow/nodes/knowledge-retrieval/components/dataset-item.tsx +++ b/web/app/components/workflow/nodes/knowledge-retrieval/components/dataset-item.tsx @@ -111,7 +111,7 @@ const DatasetItem: FC = ({ } {isShowSettingsModal && ( - +