From cd5f089f2f16b690b9c37fe6fbe93afe57f2fcb6 Mon Sep 17 00:00:00 2001 From: 1AhmedYasser <26207361+1AhmedYasser@users.noreply.github.com> Date: Fri, 22 May 2026 11:12:02 +0300 Subject: [PATCH 1/2] fix(961): Fixed name normalization --- .../POST/services/check-import-names.yml | 36 +++++++++++++++++++ .../Flow/Controls/ImportExportControls.tsx | 25 ++++++++++--- GUI/src/resources/api-constants.ts | 1 + 3 files changed, 58 insertions(+), 4 deletions(-) create mode 100644 DSL/Ruuter/services/POST/services/check-import-names.yml diff --git a/DSL/Ruuter/services/POST/services/check-import-names.yml b/DSL/Ruuter/services/POST/services/check-import-names.yml new file mode 100644 index 00000000..2d0632bd --- /dev/null +++ b/DSL/Ruuter/services/POST/services/check-import-names.yml @@ -0,0 +1,36 @@ +declaration: + call: declare + version: 0.1 + description: "Check which service names already exist and return them with timestamps appended where needed" + method: post + accepts: json + returns: json + namespace: service + allowlist: + body: + - field: names + type: string + description: "Comma-separated service names to check" + - field: timezone + type: string + description: "Timezone for timestamp generation" + +extract_request_data: + assign: + names: ${incoming.body.names} + timezone: ${incoming.body.timezone} + +check_names: + call: http.post + args: + url: "[#SERVICE_RESQL]/get-import-names" + body: + names: ${names} + timezone: ${timezone} + result: check_names_res + +return_result: + status: 200 + wrapper: false + return: ${check_names_res.response.body[0]} + next: end diff --git a/GUI/src/components/Flow/Controls/ImportExportControls.tsx b/GUI/src/components/Flow/Controls/ImportExportControls.tsx index fe64d248..74749f9b 100644 --- a/GUI/src/components/Flow/Controls/ImportExportControls.tsx +++ b/GUI/src/components/Flow/Controls/ImportExportControls.tsx @@ -4,6 +4,7 @@ import { format } from 'date-fns'; import { ChangeEvent, FC, useCallback, useRef, useState } from 'react'; import { useTranslation } from 'react-i18next'; import { AiOutlineExport, AiOutlineImport } from 'react-icons/ai'; +import api from 'services/api'; import { updateFlowInputRules } from 'services/flow-builder'; import useServiceStore from 'store/new-services.store'; import useToastStore from 'store/toasts.store'; @@ -17,6 +18,7 @@ import { serializeFlowArtifact, } from 'utils/service-flow-artifact'; import { removeTrailingUnderscores } from 'utils/string-util'; +import { checkImportNames } from 'resources/api-constants'; const ImportExportControls: FC = () => { const { getNodes, getEdges, setNodes, setEdges } = useReactFlow(); @@ -90,23 +92,38 @@ const ImportExportControls: FC = () => { [setStoreNodes, setStoreEdges, setHasUnsavedChanges, saveToHistory, t], ); + const resolveImportedName = useCallback(async (title: string): Promise => { + try { + const timezone = Intl.DateTimeFormat().resolvedOptions().timeZone; + const res = await api.post(checkImportNames(), { names: title, timezone }); + return (res.data as { names?: string })?.names ?? title; + } catch { + return title; + } + }, []); + const handleImport = useCallback( (event: ChangeEvent) => { const file = event.target.files?.[0]; if (!file) return; const reader = new FileReader(); - reader.onload = (e) => { + reader.onload = async (e) => { try { const content = e.target?.result as string; const { nodes, edges, settings } = parseFlowArtifact(content); const flowData = { nodes, edges } as FlowData; + + const resolvedSettings = settings?.title + ? { ...settings, title: await resolveImportedName(settings.title) } + : settings; + const currentNodes = getNodes().filter((node) => node.type !== 'ghost'); if (currentNodes.length === 1 && currentNodes[0].type === 'start') { - applyImportedFlow(flowData, settings); + applyImportedFlow(flowData, resolvedSettings); } else { - setImportedFlowData({ ...flowData, settings }); + setImportedFlowData({ ...flowData, settings: resolvedSettings }); setIsConfirmImportModalVisible(true); } } catch (error) { @@ -122,7 +139,7 @@ const ImportExportControls: FC = () => { fileInputRef.current.value = ''; } }, - [getNodes, applyImportedFlow, t], + [getNodes, applyImportedFlow, resolveImportedName, t], ); const closeImportModal = useCallback(() => { diff --git a/GUI/src/resources/api-constants.ts b/GUI/src/resources/api-constants.ts index 4719e86b..6430ce97 100644 --- a/GUI/src/resources/api-constants.ts +++ b/GUI/src/resources/api-constants.ts @@ -33,3 +33,4 @@ export const getAllEndpoints = (): string => `${baseUrl}/endpoints/all`; export const testEndpointUrl = (): string => `${baseUrl}/services/test-endpoint`; export const reindexEndpointUrl = (): string => `${baseUrl}/endpoints/reindex-endpoint`; export const importMultipleServices = (): string => `${baseUrl}/services/import-services`; +export const checkImportNames = (): string => `${baseUrl}/services/check-import-names`; From 42774cf0fff3a49b9f459b64a606743d83c8359d Mon Sep 17 00:00:00 2001 From: 1AhmedYasser <26207361+1AhmedYasser@users.noreply.github.com> Date: Fri, 22 May 2026 11:13:32 +0300 Subject: [PATCH 2/2] fix(961): Fixed lint --- GUI/src/components/Flow/Controls/ImportExportControls.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/GUI/src/components/Flow/Controls/ImportExportControls.tsx b/GUI/src/components/Flow/Controls/ImportExportControls.tsx index 74749f9b..85cbeaac 100644 --- a/GUI/src/components/Flow/Controls/ImportExportControls.tsx +++ b/GUI/src/components/Flow/Controls/ImportExportControls.tsx @@ -4,6 +4,7 @@ import { format } from 'date-fns'; import { ChangeEvent, FC, useCallback, useRef, useState } from 'react'; import { useTranslation } from 'react-i18next'; import { AiOutlineExport, AiOutlineImport } from 'react-icons/ai'; +import { checkImportNames } from 'resources/api-constants'; import api from 'services/api'; import { updateFlowInputRules } from 'services/flow-builder'; import useServiceStore from 'store/new-services.store'; @@ -18,7 +19,6 @@ import { serializeFlowArtifact, } from 'utils/service-flow-artifact'; import { removeTrailingUnderscores } from 'utils/string-util'; -import { checkImportNames } from 'resources/api-constants'; const ImportExportControls: FC = () => { const { getNodes, getEdges, setNodes, setEdges } = useReactFlow();