From c7fad9753f00bc4802f827e1d255de03a20a33f1 Mon Sep 17 00:00:00 2001 From: Igor Krupenja Date: Mon, 28 Jul 2025 13:32:59 +0300 Subject: [PATCH 01/24] fix(640): use local db --- docker-compose.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index f1e85977d..66c379b31 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -45,8 +45,8 @@ services: - database environment: - sqlms.datasources.[0].name=byk - # - sqlms.datasources.[0].jdbcUrl=jdbc:postgresql://database:5432/services_db # For Local Use - - sqlms.datasources.[0].jdbcUrl=jdbc:postgresql://171.22.247.13:5435/services_db + - sqlms.datasources.[0].jdbcUrl=jdbc:postgresql://database:5432/services_db # For Local Use + # - sqlms.datasources.[0].jdbcUrl=jdbc:postgresql://171.22.247.13:5435/services_db - sqlms.datasources.[0].username=byk - sqlms.datasources.[0].password=01234 - logging.level.org.springframework.boot=INFO From ec4a0dfce03001a92cc8bb845aa47e9eb7626834 Mon Sep 17 00:00:00 2001 From: Igor Krupenja Date: Mon, 28 Jul 2025 13:49:28 +0300 Subject: [PATCH 02/24] fix(640): fix yaml path --- migrate.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/migrate.sh b/migrate.sh index 8c9451366..744911476 100755 --- a/migrate.sh +++ b/migrate.sh @@ -1,2 +1,2 @@ #!/bin/bash -docker run --rm --network bykstack -v $(pwd)/DSL/Liquibase:/liquibase/changelog liquibase/liquibase -v $(pwd)/DSL/Liquibase/changelog.yml:/liquibase/changelog.yml --defaultsFile=/liquibase/changelog/liquibase.properties --changelog-file=changelog.yml update +docker run --rm --network bykstack -v $(pwd)/DSL/Liquibase:/liquibase/changelog liquibase/liquibase -v $(pwd)/DSL/Liquibase/changelog.yaml:/liquibase/changelog.yaml --defaultsFile=/liquibase/changelog/liquibase.properties --changelog-file=changelog.yaml update From 6dc3beee8b17cd7f6e437ee257f580b58bb151c2 Mon Sep 17 00:00:00 2001 From: Igor Krupenja Date: Mon, 28 Jul 2025 14:01:22 +0300 Subject: [PATCH 03/24] fix(562): fix the bug --- migrate.sh | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/migrate.sh b/migrate.sh index 744911476..719eb42a0 100755 --- a/migrate.sh +++ b/migrate.sh @@ -1,2 +1,8 @@ #!/bin/bash -docker run --rm --network bykstack -v $(pwd)/DSL/Liquibase:/liquibase/changelog liquibase/liquibase -v $(pwd)/DSL/Liquibase/changelog.yaml:/liquibase/changelog.yaml --defaultsFile=/liquibase/changelog/liquibase.properties --changelog-file=changelog.yaml update +docker run --rm --network bykstack \ + -v $(pwd)/DSL/Liquibase:/workspace \ + -w /workspace \ + liquibase/liquibase \ + --defaultsFile=liquibase.properties \ + --changelog-file=changelog.yaml \ + update From f5d804e55797edb91f4f12c27fe192e38edeb5a9 Mon Sep 17 00:00:00 2001 From: Igor Krupenja Date: Mon, 28 Jul 2025 14:01:51 +0300 Subject: [PATCH 04/24] Revert "fix(640): use local db" This reverts commit c7fad9753f00bc4802f827e1d255de03a20a33f1. --- docker-compose.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index 66c379b31..f1e85977d 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -45,8 +45,8 @@ services: - database environment: - sqlms.datasources.[0].name=byk - - sqlms.datasources.[0].jdbcUrl=jdbc:postgresql://database:5432/services_db # For Local Use - # - sqlms.datasources.[0].jdbcUrl=jdbc:postgresql://171.22.247.13:5435/services_db + # - sqlms.datasources.[0].jdbcUrl=jdbc:postgresql://database:5432/services_db # For Local Use + - sqlms.datasources.[0].jdbcUrl=jdbc:postgresql://171.22.247.13:5435/services_db - sqlms.datasources.[0].username=byk - sqlms.datasources.[0].password=01234 - logging.level.org.springframework.boot=INFO From 062e6fc4359ec4aa7a2d52911b72669460d53815 Mon Sep 17 00:00:00 2001 From: 1AhmedYasser <26207361+1AhmedYasser@users.noreply.github.com> Date: Tue, 29 Jul 2025 00:22:07 +0300 Subject: [PATCH 05/24] chore(637): Separated Global Endpoints from canvas endpoints --- GUI/src/components/ApiEndpoint/index.tsx | 2 -- GUI/src/components/ApiEndpointCard/index.tsx | 4 +++- GUI/src/components/Flow/EdgeTypes/CustomEdge.tsx | 5 +++-- GUI/src/components/FlowBuilder/FlowBuilder.tsx | 5 ++++- .../components/FlowElementsPopup/ApiContent.tsx | 11 ++++++++++- GUI/src/components/FlowElementsPopup/index.tsx | 15 +++++++++++---- GUI/src/hooks/flow/useEdgeAdd.ts | 1 + GUI/src/pages/ServiceFlowPage.tsx | 1 - GUI/src/store/new-services.store.ts | 13 +++++++++++-- GUI/src/types/service-flow.ts | 2 ++ 10 files changed, 45 insertions(+), 14 deletions(-) diff --git a/GUI/src/components/ApiEndpoint/index.tsx b/GUI/src/components/ApiEndpoint/index.tsx index 6f08989fc..22c38fd2b 100644 --- a/GUI/src/components/ApiEndpoint/index.tsx +++ b/GUI/src/components/ApiEndpoint/index.tsx @@ -64,7 +64,6 @@ const ApiEndpoint: FC = ({ step, onClick }) => { }); useToastStore.getState().success({ title: t("serviceFlow.apiElements.deleteSuccess") }); deleteEndpointFromStore(endpoint.endpointId); - useServiceStore.getState().loadEndpointsResponseVariables(); } catch (error) { console.error(`Error deleting API endpoint: ${error}`); useToastStore.getState().error({ title: t("serviceFlow.apiElements.deleteError") }); @@ -143,7 +142,6 @@ const ApiEndpoint: FC = ({ step, onClick }) => { useServiceStore.getState().editEndpoint(stepData); setIsEditing(false); useToastStore.getState().success({ title: t("serviceFlow.apiElements.editSuccess") }); - useServiceStore.getState().loadEndpointsResponseVariables(); }, (error) => { console.error(`Error Editing API endpoint: ${error}`); diff --git a/GUI/src/components/ApiEndpointCard/index.tsx b/GUI/src/components/ApiEndpointCard/index.tsx index e9842649b..64e55cc98 100644 --- a/GUI/src/components/ApiEndpointCard/index.tsx +++ b/GUI/src/components/ApiEndpointCard/index.tsx @@ -14,6 +14,7 @@ type EndpointCardProps = { endpoint: EndpointData; isDeletable?: boolean; isNameDisabled?: boolean; + showCommonSwitch?: boolean; onNameChange?: (name: string) => void; onNameExists?: (exists: boolean) => void; onCommonChange?: (isCommon: boolean) => void; @@ -23,6 +24,7 @@ const ApiEndpointCard: FC = ({ endpoint, isDeletable = true, isNameDisabled = false, + showCommonSwitch = true, onNameExists, onNameChange, onCommonChange, @@ -138,7 +140,7 @@ const ApiEndpointCard: FC = ({ requestValues={requestValues} /> )} - {option?.value && ( + {showCommonSwitch && option?.value && ( { - onEdgeAdd(step); + onEdgeAdd(step).then(() => { + useServiceStore.getState().loadEndpointsResponseVariables(); + }); setDropdownOpen(false); setHasUnsavedChanges(true); }} @@ -226,7 +228,6 @@ function CustomEdge({ setEndpoint({ endpointId: uuid(), name: "", definitions: [], isNew: true }); useToastStore.getState().success({ title: t("serviceFlow.apiElements.createSuccess") }); setIsCreatingEndpoint(false); - useServiceStore.getState().loadEndpointsResponseVariables(); }, (error) => { console.error(`Error creating API endpoint: ${error}`); diff --git a/GUI/src/components/FlowBuilder/FlowBuilder.tsx b/GUI/src/components/FlowBuilder/FlowBuilder.tsx index 7229dd70f..cd1118b0b 100644 --- a/GUI/src/components/FlowBuilder/FlowBuilder.tsx +++ b/GUI/src/components/FlowBuilder/FlowBuilder.tsx @@ -93,7 +93,10 @@ const FlowBuilder: FC = ({ nodes, edges }) => { panOnScroll nodeTypes={nodeTypes} edgeTypes={edgeTypes} - onInit={setReactFlowInstance} + onInit={(instance) => { + setReactFlowInstance(instance); + useServiceStore.getState().loadEndpointsResponseVariables(); + }} nodesDraggable={false} onConnect={onConnect} onEdgesDelete={(edges) => { diff --git a/GUI/src/components/FlowElementsPopup/ApiContent.tsx b/GUI/src/components/FlowElementsPopup/ApiContent.tsx index e9c5b2bc4..7c06ef6f7 100644 --- a/GUI/src/components/FlowElementsPopup/ApiContent.tsx +++ b/GUI/src/components/FlowElementsPopup/ApiContent.tsx @@ -12,7 +12,16 @@ type ApiContentProps = { const ApiContent: FC = ({ nodeId, endpoint }) => { return ( - {endpoint && } + {endpoint && ( + { + endpoint.name = name; + }} + /> + )} ); diff --git a/GUI/src/components/FlowElementsPopup/index.tsx b/GUI/src/components/FlowElementsPopup/index.tsx index 448928907..f9d2212cd 100644 --- a/GUI/src/components/FlowElementsPopup/index.tsx +++ b/GUI/src/components/FlowElementsPopup/index.tsx @@ -44,7 +44,6 @@ const FlowElementsPopup: React.FC = () => { const isUserDefinedNode = node?.data?.stepType === "user-defined"; const serviceName = useServiceStore((state) => removeTrailingUnderscores(state.serviceNameDashed())); - const endpoints = useServiceStore((state) => state.endpoints); const rules = useServiceStore((state) => state.rules); const assignElements = useServiceStore((state) => state.assignElements); const endpointsVariables = useServiceStore((state) => state.endpointsResponseVariables); @@ -163,6 +162,15 @@ const FlowElementsPopup: React.FC = () => { saveMultiChoicePopup(node, updatedNode); } + if (stepType === StepType.UserDefined) { + const newLabel = node.data.label?.toString().split(" "); + if (node.data.endpoint?.name) { + newLabel[0] = node.data.endpoint?.name ?? node.data.label?.toString().split(" ")[0]; + node.data.label = newLabel.join(" "); + } + useServiceStore.getState().loadEndpointsResponseVariables(); + } + if (stepType === StepType.Assign) { const flatEndpointVariables = endpointsVariables.map((endpoint) => endpoint.chips).flat(); assignElements.forEach((element) => { @@ -204,8 +212,7 @@ const FlowElementsPopup: React.FC = () => { } try { - const finder = (e: any) => e.name === node.data.label || node.data.label.includes(e.name); - const endpoint = endpoints.find(finder)?.definitions[0]; + const endpoint = node.data.endpoint?.definitions[0]; if (!endpoint) return; @@ -431,7 +438,7 @@ const FlowElementsPopup: React.FC = () => { {stepType === StepType.UserDefined && ( e.name === node.data.label || node.data.label.includes(e.name))} + endpoint={node.data.endpoint} /> )} {stepType === StepType.MultiChoiceQuestion && ( diff --git a/GUI/src/hooks/flow/useEdgeAdd.ts b/GUI/src/hooks/flow/useEdgeAdd.ts index c3b2a602a..bda5f544c 100644 --- a/GUI/src/hooks/flow/useEdgeAdd.ts +++ b/GUI/src/hooks/flow/useEdgeAdd.ts @@ -30,6 +30,7 @@ function useEdgeAdd(id: string) { : "step", stepType: stepType, readonly: [StepType.Auth, StepType.FinishingStepEnd, StepType.FinishingStepRedirect].includes(stepType), + endpoint: step.data, setClickedNode: useServiceStore.getState().setClickedNode, }, className: [StepType.FinishingStepEnd, StepType.FinishingStepRedirect].includes(stepType) diff --git a/GUI/src/pages/ServiceFlowPage.tsx b/GUI/src/pages/ServiceFlowPage.tsx index 4fb094232..5cfdae7c7 100644 --- a/GUI/src/pages/ServiceFlowPage.tsx +++ b/GUI/src/pages/ServiceFlowPage.tsx @@ -52,7 +52,6 @@ const ServiceFlowPage: FC = () => { .getState() .loadService(id) .then(() => { - useServiceStore.getState().loadEndpointsResponseVariables(); useServiceStore .getState() .loadStepPreferences() diff --git a/GUI/src/store/new-services.store.ts b/GUI/src/store/new-services.store.ts index d41f5a388..d40595a3e 100644 --- a/GUI/src/store/new-services.store.ts +++ b/GUI/src/store/new-services.store.ts @@ -246,8 +246,17 @@ const useServiceStore = create((set, get, store) => ({ availableVariables: { prod: [], test: [] }, loadEndpointsResponseVariables: async () => { try { - const requests = get().endpoints.flatMap((e) => - e.definitions.map((endpoint) => ({ + const instance = get().reactFlowInstance; + if (!instance) return; + const endpointNodes = instance.getNodes().filter((node) => node.data.stepType === StepType.UserDefined) as Node[]; + if (endpointNodes.length === 0) { + set({ endpointsResponseVariables: [] }); + return; + }; + + const endpointsFromNodes = endpointNodes.map((node) => node.data.endpoint); + const requests = endpointsFromNodes.flatMap((e) => + e?.definitions.map((endpoint) => ({ url: endpoint.url, method: endpoint.methodType, headers: extractMapValues(endpoint.headers), diff --git a/GUI/src/types/service-flow.ts b/GUI/src/types/service-flow.ts index 1eab5992c..3fbe275e5 100644 --- a/GUI/src/types/service-flow.ts +++ b/GUI/src/types/service-flow.ts @@ -1,3 +1,4 @@ +import { EndpointData } from "./endpoint"; import { MultiChoiceQuestion } from "./multi-choice-question"; import { StepType } from "./step-type.enum"; import { Edge, Node } from "@xyflow/react"; @@ -24,6 +25,7 @@ export type NodeDataProps = { assignElements?: any; multiChoiceQuestion?: MultiChoiceQuestion; childrenCount?: number; + endpoint?: EndpointData }; export const initialNodes: Node[] = [ From 4f5d6a0110e6c8d04207bd380c759aa6175fe89f Mon Sep 17 00:00:00 2001 From: 1AhmedYasser <26207361+1AhmedYasser@users.noreply.github.com> Date: Tue, 29 Jul 2025 00:31:53 +0300 Subject: [PATCH 06/24] chore(637): Fixed Loading Variable --- GUI/src/store/new-services.store.ts | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/GUI/src/store/new-services.store.ts b/GUI/src/store/new-services.store.ts index d40595a3e..39bc61e55 100644 --- a/GUI/src/store/new-services.store.ts +++ b/GUI/src/store/new-services.store.ts @@ -272,19 +272,20 @@ const useServiceStore = create((set, get, store) => ({ const variables: EndpointResponseVariable[] = []; response.data.response.forEach((res: any, i: number) => { - const endpoint = get().endpoints[i]; + const endpoint = endpointsFromNodes[i]; const chips: Chip[] = []; + console.log("endpoint = ", endpoint); for (const [key, value] of Object.entries(res)) { chips.push({ name: key, - value: `${endpoint.name.replace(" ", "_")}_res.response.body.${key}`, + value: `${endpoint?.name.replace(" ", "_")}_res.response.body.${key}`, data: value, }); } const variable: EndpointResponseVariable = { - name: endpoint.name, + name: endpoint?.name ?? '', chips: chips, }; From 85e0184b82a352eb2093b38e3f18341b25dfc30d Mon Sep 17 00:00:00 2001 From: 1AhmedYasser <26207361+1AhmedYasser@users.noreply.github.com> Date: Tue, 29 Jul 2025 00:32:36 +0300 Subject: [PATCH 07/24] fix(637): Removed console.log --- GUI/src/store/new-services.store.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/GUI/src/store/new-services.store.ts b/GUI/src/store/new-services.store.ts index 39bc61e55..d21807986 100644 --- a/GUI/src/store/new-services.store.ts +++ b/GUI/src/store/new-services.store.ts @@ -275,7 +275,6 @@ const useServiceStore = create((set, get, store) => ({ const endpoint = endpointsFromNodes[i]; const chips: Chip[] = []; - console.log("endpoint = ", endpoint); for (const [key, value] of Object.entries(res)) { chips.push({ name: key, From 06586310a0a37856c5e325864e182491e5d75156 Mon Sep 17 00:00:00 2001 From: 1AhmedYasser <26207361+1AhmedYasser@users.noreply.github.com> Date: Tue, 29 Jul 2025 00:56:59 +0300 Subject: [PATCH 08/24] chore(637): added handleEndpointStep --- GUI/src/services/service-builder.ts | 54 +++++++++++++++++++++++++---- 1 file changed, 48 insertions(+), 6 deletions(-) diff --git a/GUI/src/services/service-builder.ts b/GUI/src/services/service-builder.ts index bb59b6c70..0c3e80f61 100644 --- a/GUI/src/services/service-builder.ts +++ b/GUI/src/services/service-builder.ts @@ -744,6 +744,10 @@ function getYamlContent(nodes: Node[], edges: Edge[], steps: Step[], name: strin return handleMultiChoiceQuestion(finishedFlow, parentStepName, parentNode, childNode, childNodeId); } + if (parentNode.data.stepType === StepType.UserDefined) { + return handleEndpointStep(parentNode, finishedFlow, parentStepName, childNode); + } + const nextStep = childNode ? toSnakeCase(childNode.data.label ?? "format_messages") : "format_messages"; const template = getTemplate(steps, parentNode, parentStepName, nextStep); @@ -905,6 +909,50 @@ function handleAssignStep( }); } +function handleEndpointStep( + parentNode: Node, + finishedFlow: Map, + parentStepName: string, + childNode: Node | undefined, +) { + const endpointDefinition = parentNode.data.endpoint?.definitions[0]; + const paramsVariables = endpointDefinition?.params?.variables; + const bodyVariables = endpointDefinition?.body?.variables; + const headersVariables = endpointDefinition?.headers?.variables; + const methodType = endpointDefinition?.methodType?.toLowerCase(); + + const stepConfig: any = { + call: `http.${methodType}`, + args: { + url: endpointDefinition?.url?.split("?")[0] ?? "", + }, + next: childNode ? toSnakeCase(childNode.data.label ?? "format_messages") : "format_messages", + }; + + if (Array.isArray(paramsVariables) && paramsVariables.length > 0) { + stepConfig.args.query = paramsVariables.reduce((acc: any, e: any) => { + acc[e.name] = e.value; + return acc; + }, {}); + } + + if (Array.isArray(bodyVariables) && bodyVariables.length > 0) { + stepConfig.args.body = bodyVariables.reduce((acc: any, e: any) => { + acc[e.name] = e.value; + return acc; + }, {}); + } + + if (Array.isArray(headersVariables) && headersVariables.length > 0) { + stepConfig.args.headers = headersVariables.reduce((acc: any, e: any) => { + acc[e.name] = e.value; + return acc; + }, {}); + } + + finishedFlow.set(parentStepName, stepConfig); +} + function handleMultiChoiceQuestion( finishedFlow: Map, parentStepName: string, @@ -990,12 +1038,6 @@ const getSwitchCase = (conditions: any[]) => { const getTemplate = (steps: Step[], node: Node, stepName: string, nextStep?: string) => { const data = getTemplateDataFromNode(node); - if (node.data.stepType === StepType.UserDefined) { - return { - ...getDefinedEndpointStep(steps, node), - next: nextStep ?? "format_messages", - }; - } return { template: `${data?.templateName}`, From 848fe6f7fea3fa16bdc81a4a240b945ad2a0442a Mon Sep 17 00:00:00 2001 From: 1AhmedYasser <26207361+1AhmedYasser@users.noreply.github.com> Date: Tue, 29 Jul 2025 01:00:08 +0300 Subject: [PATCH 09/24] chore(637): Removed Unused code --- GUI/src/services/service-builder.ts | 70 ----------------------------- 1 file changed, 70 deletions(-) diff --git a/GUI/src/services/service-builder.ts b/GUI/src/services/service-builder.ts index 0c3e80f61..ebb15c1eb 100644 --- a/GUI/src/services/service-builder.ts +++ b/GUI/src/services/service-builder.ts @@ -1006,36 +1006,6 @@ const getNestedPreDefinedEndpointVariables = (variable: EndpointVariableData, re } }; -const getPreDefinedEndpointVariables = (data?: { variables: EndpointVariableData[]; rawData: RawData }): string[] => { - if (!data) return []; - const result: string[] = []; - data.variables.forEach((v) => { - if (!v.value) getNestedPreDefinedEndpointVariables(v, result); - - if (v.value?.startsWith("{{")) result.push(getMapEntry(v.value)); - if (v.testValue?.startsWith("{{")) result.push(getMapEntry(v.testValue)); - }); - try { - getNestedPreDefinedRawVariables(JSON.parse(data.rawData?.value ?? "{}"), result); - getNestedPreDefinedRawVariables(JSON.parse(data.rawData?.testValue ?? "{}"), result); - } catch (e) { - console.error(e); - } - - return result; -}; - -const getSwitchCase = (conditions: any[]) => { - return { - switch: conditions.map((c) => { - return { - condition: c.case, - next: c.nextStep, - }; - }), - }; -}; - const getTemplate = (steps: Step[], node: Node, stepName: string, nextStep?: string) => { const data = getTemplateDataFromNode(node); @@ -1107,46 +1077,6 @@ const getTemplateDataFromNode = (node: Node): { templateName: string; body?: any } }; -const getDefinedEndpointStep = (steps: Step[], node: Node) => { - const name = removeTrailingUnderscores(useServiceStore.getState().serviceNameDashed()); - const endpoint = steps.find((e) => e.label === node.data.label?.toString().split(" ")[0])?.data; - const selectedEndpoint = endpoint?.definitions.find((e) => e.isSelected); - if (!selectedEndpoint || !endpoint) { - return { - return: "", - }; - } - - const isCommonPath = endpoint.isCommon ? "common/" : ""; - // For backwards compatibility, in case fileName was not defined - const defaultFileName = `${name}-${getEndpointName(endpoint)}`; - const fileName = endpoint.fileName ?? defaultFileName; - const paramss = rawDataIfVariablesMissing( - selectedEndpoint, - "params", - EndpointEnv.Live, - assignEndpointVariables(EndpointEnv.Live, "params", selectedEndpoint.params) - ); - const filteredParams = Object.fromEntries( - Object.entries(paramss).filter(([_, value]) => String(value).startsWith("${")) - ); - filteredParams["type"] = "prod"; - - return { - call: `${selectedEndpoint.methodType.toLowerCase() === "get" ? "http.get" : "http.post"}`, - args: { - url: `${import.meta.env.REACT_APP_API_URL}/services/endpoints/${isCommonPath}${fileName}?type=prod`, - body: { - headers: `\${new Map([${getPreDefinedEndpointVariables(selectedEndpoint.headers)}])}`, - body: `\${new Map([${getPreDefinedEndpointVariables(selectedEndpoint.body)}])}`, - params: `\${new Map([${getPreDefinedEndpointVariables(selectedEndpoint.params)}])}`, - }, - query: filteredParams, - }, - result: `${endpoint.name.replaceAll(" ", "_")}_res`, - }; -}; - const getEndpointName = (endpoint: EndpointData) => { return `${(endpoint.name.trim().length ?? 0) > 0 ? endpoint?.name.replaceAll(" ", "_") : endpoint?.endpointId}`; }; From 6ef11dbaac4658e228fef7c7aa770191edc58946 Mon Sep 17 00:00:00 2001 From: 1AhmedYasser <26207361+1AhmedYasser@users.noreply.github.com> Date: Tue, 29 Jul 2025 01:36:49 +0300 Subject: [PATCH 10/24] chore(638): Removed Endpoints Disk Writes --- .gitignore | 2 - ...152343-remove_file_name_from_endpoints.xml | 17 + ...152343-remove_file_name_from_endpoints.sql | 4 + .../rollback/20250516152343_rollback.sql | 5 + .../POST/endpoints/create_endpoint.sql | 4 +- .../POST/endpoints/delete_endpoint.sql | 4 +- .../delete_endpoints_by_service_id.sql | 2 - .../POST/endpoints/get_common_endpoints.sql | 1 - .../endpoints/get_endpoints_by_service_id.sql | 3 +- .../POST/endpoints/update_endpoint.sql | 5 +- .../services/GET/services/endpoints/.guard | 4 - .../endpoints/common/common-endpoint.yml | 71 --- .../common/service-endpoint-prod-configs.yml | 19 - .../common/service-endpoint-test-configs.yml | 19 - .../configs/service-endpoint-prod-configs.yml | 19 - .../configs/service-endpoint-test-configs.yml | 19 - .../common/service-endpoint-prod-info.yml | 25 -- .../common/service-endpoint-test-info.yml | 25 -- .../info/service-endpoint-prod-info.yml | 25 -- .../info/service-endpoint-test-info.yml | 25 -- .../services/endpoints/service-endpoint.yml | 71 --- .../POST/services/create-endpoint.yml | 4 - .../POST/services/delete-endpoint-files.yml | 132 ------ .../POST/services/delete-endpoint.yml | 21 - DSL/Ruuter/services/POST/services/delete.yml | 12 - .../services/POST/services/endpoints/.guard | 4 - .../endpoints/common/common-endpoint.yml | 71 --- .../common/service-endpoint-prod-configs.yml | 19 - .../common/service-endpoint-test-configs.yml | 19 - .../configs/service-endpoint-prod-configs.yml | 19 - .../configs/service-endpoint-test-configs.yml | 19 - .../common/service-endpoint-prod-info.yml | 25 -- .../common/service-endpoint-test-info.yml | 25 -- .../info/service-endpoint-prod-info.yml | 25 -- .../info/service-endpoint-test-info.yml | 25 -- .../services/endpoints/service-endpoint.yml | 71 --- .../POST/services/update-endpoint.yml | 4 - GUI/src/services/service-builder.ts | 406 +----------------- 38 files changed, 37 insertions(+), 1233 deletions(-) create mode 100644 DSL/Liquibase/changelog/20250516152343-remove_file_name_from_endpoints.xml create mode 100644 DSL/Liquibase/changelog/migrations/20250516152343-remove_file_name_from_endpoints.sql create mode 100644 DSL/Liquibase/changelog/migrations/rollback/20250516152343_rollback.sql delete mode 100644 DSL/Ruuter/services/GET/services/endpoints/.guard delete mode 100644 DSL/Ruuter/services/GET/services/endpoints/common/common-endpoint.yml delete mode 100644 DSL/Ruuter/services/GET/services/endpoints/configs/common/service-endpoint-prod-configs.yml delete mode 100644 DSL/Ruuter/services/GET/services/endpoints/configs/common/service-endpoint-test-configs.yml delete mode 100644 DSL/Ruuter/services/GET/services/endpoints/configs/service-endpoint-prod-configs.yml delete mode 100644 DSL/Ruuter/services/GET/services/endpoints/configs/service-endpoint-test-configs.yml delete mode 100644 DSL/Ruuter/services/GET/services/endpoints/info/common/service-endpoint-prod-info.yml delete mode 100644 DSL/Ruuter/services/GET/services/endpoints/info/common/service-endpoint-test-info.yml delete mode 100644 DSL/Ruuter/services/GET/services/endpoints/info/service-endpoint-prod-info.yml delete mode 100644 DSL/Ruuter/services/GET/services/endpoints/info/service-endpoint-test-info.yml delete mode 100644 DSL/Ruuter/services/GET/services/endpoints/service-endpoint.yml delete mode 100644 DSL/Ruuter/services/POST/services/delete-endpoint-files.yml delete mode 100644 DSL/Ruuter/services/POST/services/endpoints/.guard delete mode 100644 DSL/Ruuter/services/POST/services/endpoints/common/common-endpoint.yml delete mode 100644 DSL/Ruuter/services/POST/services/endpoints/configs/common/service-endpoint-prod-configs.yml delete mode 100644 DSL/Ruuter/services/POST/services/endpoints/configs/common/service-endpoint-test-configs.yml delete mode 100644 DSL/Ruuter/services/POST/services/endpoints/configs/service-endpoint-prod-configs.yml delete mode 100644 DSL/Ruuter/services/POST/services/endpoints/configs/service-endpoint-test-configs.yml delete mode 100644 DSL/Ruuter/services/POST/services/endpoints/info/common/service-endpoint-prod-info.yml delete mode 100644 DSL/Ruuter/services/POST/services/endpoints/info/common/service-endpoint-test-info.yml delete mode 100644 DSL/Ruuter/services/POST/services/endpoints/info/service-endpoint-prod-info.yml delete mode 100644 DSL/Ruuter/services/POST/services/endpoints/info/service-endpoint-test-info.yml delete mode 100644 DSL/Ruuter/services/POST/services/endpoints/service-endpoint.yml diff --git a/.gitignore b/.gitignore index 83eceb667..5c4c97e10 100644 --- a/.gitignore +++ b/.gitignore @@ -4,12 +4,10 @@ /DSL/Ruuter/services/POST/services/active /DSL/Ruuter/services/POST/services/draft /DSL/Ruuter/services/POST/services/inactive -/DSL/Ruuter/services/POST/services/endpoints /DSL/Ruuter/services/POST/services/inactive /DSL/Ruuter/services/GET/services/active /DSL/Ruuter/services/GET/services/draft /DSL/Ruuter/services/GET/services/inactive -/DSL/Ruuter/services/GET/services/endpoints /DSL/Ruuter/services/GET/services/inactive .DS_Store .vscode diff --git a/DSL/Liquibase/changelog/20250516152343-remove_file_name_from_endpoints.xml b/DSL/Liquibase/changelog/20250516152343-remove_file_name_from_endpoints.xml new file mode 100644 index 000000000..6c2ff2936 --- /dev/null +++ b/DSL/Liquibase/changelog/20250516152343-remove_file_name_from_endpoints.xml @@ -0,0 +1,17 @@ + + + + + + + + + + diff --git a/DSL/Liquibase/changelog/migrations/20250516152343-remove_file_name_from_endpoints.sql b/DSL/Liquibase/changelog/migrations/20250516152343-remove_file_name_from_endpoints.sql new file mode 100644 index 000000000..ee7504e23 --- /dev/null +++ b/DSL/Liquibase/changelog/migrations/20250516152343-remove_file_name_from_endpoints.sql @@ -0,0 +1,4 @@ +-- liquibase formatted sql +-- changeset 1AhmedYasser:20250516152343 + +ALTER TABLE endpoints DROP COLUMN file_name; diff --git a/DSL/Liquibase/changelog/migrations/rollback/20250516152343_rollback.sql b/DSL/Liquibase/changelog/migrations/rollback/20250516152343_rollback.sql new file mode 100644 index 000000000..c34aa60e4 --- /dev/null +++ b/DSL/Liquibase/changelog/migrations/rollback/20250516152343_rollback.sql @@ -0,0 +1,5 @@ +-- liquibase formatted sql +-- rollback + +-- Add back the file_name column as TEXT +ALTER TABLE endpoints ADD COLUMN file_name TEXT NOT NULL; diff --git a/DSL/Resql/services/POST/endpoints/create_endpoint.sql b/DSL/Resql/services/POST/endpoints/create_endpoint.sql index 0d763bfdf..579adfb52 100644 --- a/DSL/Resql/services/POST/endpoints/create_endpoint.sql +++ b/DSL/Resql/services/POST/endpoints/create_endpoint.sql @@ -3,7 +3,6 @@ INSERT INTO endpoints ( service_id, name, type, - file_name, is_common, definitions ) @@ -12,7 +11,6 @@ VALUES ( :serviceId::uuid, :name, :type::endpoint_type, - :fileName, :isCommon, :definitions::jsonb -); \ No newline at end of file +); diff --git a/DSL/Resql/services/POST/endpoints/delete_endpoint.sql b/DSL/Resql/services/POST/endpoints/delete_endpoint.sql index 2006f0ed5..ec9a9e547 100644 --- a/DSL/Resql/services/POST/endpoints/delete_endpoint.sql +++ b/DSL/Resql/services/POST/endpoints/delete_endpoint.sql @@ -3,7 +3,6 @@ INSERT INTO endpoints ( service_id, name, type, - file_name, is_common, definitions, deleted, @@ -15,7 +14,6 @@ SELECT service_id, name, type, - file_name, is_common, definitions, TRUE AS deleted, @@ -24,4 +22,4 @@ SELECT FROM endpoints WHERE endpoint_id = :id::uuid ORDER BY id DESC -LIMIT 1; \ No newline at end of file +LIMIT 1; diff --git a/DSL/Resql/services/POST/endpoints/delete_endpoints_by_service_id.sql b/DSL/Resql/services/POST/endpoints/delete_endpoints_by_service_id.sql index 07261fba9..0bd961deb 100644 --- a/DSL/Resql/services/POST/endpoints/delete_endpoints_by_service_id.sql +++ b/DSL/Resql/services/POST/endpoints/delete_endpoints_by_service_id.sql @@ -12,7 +12,6 @@ INSERT INTO endpoints ( service_id, name, type, - file_name, is_common, definitions, deleted, @@ -24,7 +23,6 @@ SELECT service_id, name, type, - file_name, is_common, definitions, TRUE AS deleted, diff --git a/DSL/Resql/services/POST/endpoints/get_common_endpoints.sql b/DSL/Resql/services/POST/endpoints/get_common_endpoints.sql index 4f0006a4e..329fcad5c 100644 --- a/DSL/Resql/services/POST/endpoints/get_common_endpoints.sql +++ b/DSL/Resql/services/POST/endpoints/get_common_endpoints.sql @@ -8,7 +8,6 @@ SELECT endpoint_id, name, type, - file_name, is_common, definitions FROM LatestEndpoints diff --git a/DSL/Resql/services/POST/endpoints/get_endpoints_by_service_id.sql b/DSL/Resql/services/POST/endpoints/get_endpoints_by_service_id.sql index eec808f65..ee2e8398c 100644 --- a/DSL/Resql/services/POST/endpoints/get_endpoints_by_service_id.sql +++ b/DSL/Resql/services/POST/endpoints/get_endpoints_by_service_id.sql @@ -8,9 +8,8 @@ SELECT endpoint_id, name, type, - file_name, is_common, definitions FROM LatestEndpoints WHERE deleted IS FALSE -ORDER BY id DESC; \ No newline at end of file +ORDER BY id DESC; diff --git a/DSL/Resql/services/POST/endpoints/update_endpoint.sql b/DSL/Resql/services/POST/endpoints/update_endpoint.sql index 09c80f9e3..428e6c7b1 100644 --- a/DSL/Resql/services/POST/endpoints/update_endpoint.sql +++ b/DSL/Resql/services/POST/endpoints/update_endpoint.sql @@ -1,10 +1,9 @@ -INSERT INTO endpoints (endpoint_id, service_id, name, type, file_name, is_common, definitions) +INSERT INTO endpoints (endpoint_id, service_id, name, type, is_common, definitions) VALUES ( :endpointId::uuid, :serviceId::uuid, :name, :type::endpoint_type, - :fileName, :isCommon, :definitions::jsonb -); \ No newline at end of file +); diff --git a/DSL/Ruuter/services/GET/services/endpoints/.guard b/DSL/Ruuter/services/GET/services/endpoints/.guard deleted file mode 100644 index 644353775..000000000 --- a/DSL/Ruuter/services/GET/services/endpoints/.guard +++ /dev/null @@ -1,4 +0,0 @@ -guard_allow_all: - return: "success" - status: 200 - next: end diff --git a/DSL/Ruuter/services/GET/services/endpoints/common/common-endpoint.yml b/DSL/Ruuter/services/GET/services/endpoints/common/common-endpoint.yml deleted file mode 100644 index 9202e4628..000000000 --- a/DSL/Ruuter/services/GET/services/endpoints/common/common-endpoint.yml +++ /dev/null @@ -1,71 +0,0 @@ -declaration: - call: declare - version: 0.1 - description: "Decription placeholder for 'COMMON-ENDPOINT'" - method: get - accepts: json - returns: json - namespace: service - allowlist: - params: - - field: type - type: string - description: "Parameter 'type'" - -extract_request_data: - assign: - type: ${incoming.params.type} - next: check_for_type - -check_for_type: - switch: - - condition: ${type == null} - next: return_no_type_error - next: check_for_environment - -check_for_environment: - switch: - - condition: ${type.toLowerCase() === 'prod'} - next: get_prod_info - next: get_test_info - -get_prod_info: - call: http.post - args: - url: "[#SERVICE_ENDPOINTS]:[#SERVICE_ENDPOINTS_PORT]/services/endpoints/info/service-endpoint-prod-info" - result: info - next: check_for_endpoint_url - -get_test_info: - call: http.post - args: - url: "[#SERVICE_ENDPOINTS]:[#SERVICE_ENDPOINTS_PORT]/services/endpoints/info/service-endpoint-test-info" - result: info - next: check_for_endpoint_url - -check_for_endpoint_url: - switch: - - condition: ${info.response.body.response[0].url == null} - next: return_no_url_provided - next: execute_endpoint - -execute_endpoint: - call: http.post - args: - url: ${info.response.body.response[0].url} - result: res - next: return_info - -return_info: - return: ${res.response.body} - next: end - -return_no_url_provided: - status: 400 - return: "No Url Provided" - next: end - -return_no_type_error: - status: 400 - return: "Please Specify Endpoint Type 'Prod' Or 'Test'" - next: end diff --git a/DSL/Ruuter/services/GET/services/endpoints/configs/common/service-endpoint-prod-configs.yml b/DSL/Ruuter/services/GET/services/endpoints/configs/common/service-endpoint-prod-configs.yml deleted file mode 100644 index f79de8acd..000000000 --- a/DSL/Ruuter/services/GET/services/endpoints/configs/common/service-endpoint-prod-configs.yml +++ /dev/null @@ -1,19 +0,0 @@ -declaration: - call: declare - version: 0.1 - description: "Decription placeholder for 'SERVICE-ENDPOINT-PROD-CONFIGS'" - method: get - accepts: json - returns: json - namespace: service - -assign_step: - assign: - sensitive: - api_key: '112218ssQQ212Prod' - username: 'User100' - password: 'pwd158' - -return_value: - wrapper: false - return: ${sensitive} diff --git a/DSL/Ruuter/services/GET/services/endpoints/configs/common/service-endpoint-test-configs.yml b/DSL/Ruuter/services/GET/services/endpoints/configs/common/service-endpoint-test-configs.yml deleted file mode 100644 index 5c400ad73..000000000 --- a/DSL/Ruuter/services/GET/services/endpoints/configs/common/service-endpoint-test-configs.yml +++ /dev/null @@ -1,19 +0,0 @@ -declaration: - call: declare - version: 0.1 - description: "Decription placeholder for 'SERVICE-ENDPOINT-TEST-CONFIGS'" - method: get - accepts: json - returns: json - namespace: service - -assign_step: - assign: - sensitive: - api_key: '112218ssQQ212TEST' - username: 'User20' - password: 'pwd18' - -return_value: - wrapper: false - return: ${sensitive} diff --git a/DSL/Ruuter/services/GET/services/endpoints/configs/service-endpoint-prod-configs.yml b/DSL/Ruuter/services/GET/services/endpoints/configs/service-endpoint-prod-configs.yml deleted file mode 100644 index f79de8acd..000000000 --- a/DSL/Ruuter/services/GET/services/endpoints/configs/service-endpoint-prod-configs.yml +++ /dev/null @@ -1,19 +0,0 @@ -declaration: - call: declare - version: 0.1 - description: "Decription placeholder for 'SERVICE-ENDPOINT-PROD-CONFIGS'" - method: get - accepts: json - returns: json - namespace: service - -assign_step: - assign: - sensitive: - api_key: '112218ssQQ212Prod' - username: 'User100' - password: 'pwd158' - -return_value: - wrapper: false - return: ${sensitive} diff --git a/DSL/Ruuter/services/GET/services/endpoints/configs/service-endpoint-test-configs.yml b/DSL/Ruuter/services/GET/services/endpoints/configs/service-endpoint-test-configs.yml deleted file mode 100644 index 5c400ad73..000000000 --- a/DSL/Ruuter/services/GET/services/endpoints/configs/service-endpoint-test-configs.yml +++ /dev/null @@ -1,19 +0,0 @@ -declaration: - call: declare - version: 0.1 - description: "Decription placeholder for 'SERVICE-ENDPOINT-TEST-CONFIGS'" - method: get - accepts: json - returns: json - namespace: service - -assign_step: - assign: - sensitive: - api_key: '112218ssQQ212TEST' - username: 'User20' - password: 'pwd18' - -return_value: - wrapper: false - return: ${sensitive} diff --git a/DSL/Ruuter/services/GET/services/endpoints/info/common/service-endpoint-prod-info.yml b/DSL/Ruuter/services/GET/services/endpoints/info/common/service-endpoint-prod-info.yml deleted file mode 100644 index 075d6da0a..000000000 --- a/DSL/Ruuter/services/GET/services/endpoints/info/common/service-endpoint-prod-info.yml +++ /dev/null @@ -1,25 +0,0 @@ -declaration: - call: declare - version: 0.1 - description: "Decription placeholder for 'SERVICE-ENDPOINT-PROD-INFO'" - method: get - accepts: json - returns: json - namespace: service - -getConfigs: - call: http.get - args: - url: "[#SERVICE_ENDPOINTS]:[#SERVICE_ENDPOINTS_PORT]/services/endpoints/configs/service-endpoint-prod-configs" - result: configs - -assign_step: - assign: - info: - url: https://httpbin.org/post - user_id: 10 - headers: - token: 'isdfbkajsdhkajsdhjsbckajsgdyasudhqwddasax' - -return_value: - return: ${[info , configs.response.body]} diff --git a/DSL/Ruuter/services/GET/services/endpoints/info/common/service-endpoint-test-info.yml b/DSL/Ruuter/services/GET/services/endpoints/info/common/service-endpoint-test-info.yml deleted file mode 100644 index d2a5aeab7..000000000 --- a/DSL/Ruuter/services/GET/services/endpoints/info/common/service-endpoint-test-info.yml +++ /dev/null @@ -1,25 +0,0 @@ -declaration: - call: declare - version: 0.1 - description: "Decription placeholder for 'SERVICE-ENDPOINT-TEST-INFO'" - method: get - accepts: json - returns: json - namespace: service - -getConfigs: - call: http.get - args: - url: "[#SERVICE_ENDPOINTS]:[#SERVICE_ENDPOINTS_PORT]/services/endpoints/configs/service-endpoint-test-configs" - result: configs - -assign_step: - assign: - info: - url: https://httpbin.org/anything - user_id: 20 - headers: - token: 'htbaslaiscvasjaskasyiuhashbxjhasgdqqysasjdhasd' - -return_value: - return: ${[info , configs.response.body]} diff --git a/DSL/Ruuter/services/GET/services/endpoints/info/service-endpoint-prod-info.yml b/DSL/Ruuter/services/GET/services/endpoints/info/service-endpoint-prod-info.yml deleted file mode 100644 index 075d6da0a..000000000 --- a/DSL/Ruuter/services/GET/services/endpoints/info/service-endpoint-prod-info.yml +++ /dev/null @@ -1,25 +0,0 @@ -declaration: - call: declare - version: 0.1 - description: "Decription placeholder for 'SERVICE-ENDPOINT-PROD-INFO'" - method: get - accepts: json - returns: json - namespace: service - -getConfigs: - call: http.get - args: - url: "[#SERVICE_ENDPOINTS]:[#SERVICE_ENDPOINTS_PORT]/services/endpoints/configs/service-endpoint-prod-configs" - result: configs - -assign_step: - assign: - info: - url: https://httpbin.org/post - user_id: 10 - headers: - token: 'isdfbkajsdhkajsdhjsbckajsgdyasudhqwddasax' - -return_value: - return: ${[info , configs.response.body]} diff --git a/DSL/Ruuter/services/GET/services/endpoints/info/service-endpoint-test-info.yml b/DSL/Ruuter/services/GET/services/endpoints/info/service-endpoint-test-info.yml deleted file mode 100644 index d2a5aeab7..000000000 --- a/DSL/Ruuter/services/GET/services/endpoints/info/service-endpoint-test-info.yml +++ /dev/null @@ -1,25 +0,0 @@ -declaration: - call: declare - version: 0.1 - description: "Decription placeholder for 'SERVICE-ENDPOINT-TEST-INFO'" - method: get - accepts: json - returns: json - namespace: service - -getConfigs: - call: http.get - args: - url: "[#SERVICE_ENDPOINTS]:[#SERVICE_ENDPOINTS_PORT]/services/endpoints/configs/service-endpoint-test-configs" - result: configs - -assign_step: - assign: - info: - url: https://httpbin.org/anything - user_id: 20 - headers: - token: 'htbaslaiscvasjaskasyiuhashbxjhasgdqqysasjdhasd' - -return_value: - return: ${[info , configs.response.body]} diff --git a/DSL/Ruuter/services/GET/services/endpoints/service-endpoint.yml b/DSL/Ruuter/services/GET/services/endpoints/service-endpoint.yml deleted file mode 100644 index 1f7752219..000000000 --- a/DSL/Ruuter/services/GET/services/endpoints/service-endpoint.yml +++ /dev/null @@ -1,71 +0,0 @@ -declaration: - call: declare - version: 0.1 - description: "Decription placeholder for 'SERVICE-ENDPOINT'" - method: get - accepts: json - returns: json - namespace: service - allowlist: - params: - - field: type - type: string - description: "Parameter 'type'" - -extract_request_data: - assign: - type: ${incoming.params.type} - next: check_for_type - -check_for_type: - switch: - - condition: ${type == null} - next: return_no_type_error - next: check_for_environment - -check_for_environment: - switch: - - condition: ${type.toLowerCase() === 'prod'} - next: get_prod_info - next: get_test_info - -get_prod_info: - call: http.get - args: - url: "[#SERVICE_ENDPOINTS]:[#SERVICE_ENDPOINTS_PORT]/services/endpoints/info/service-endpoint-prod-info" - result: info - next: check_for_endpoint_url - -get_test_info: - call: http.get - args: - url: "[#SERVICE_ENDPOINTS]:[#SERVICE_ENDPOINTS_PORT]/services/endpoints/info/service-endpoint-test-info" - result: info - next: check_for_endpoint_url - -check_for_endpoint_url: - switch: - - condition: ${info.response.body.response[0].url == null} - next: return_no_url_provided - next: execute_endpoint - -execute_endpoint: - call: http.post - args: - url: ${info.response.body.response[0].url} - result: res - next: return_info - -return_info: - return: ${res.response.body} - next: end - -return_no_url_provided: - status: 400 - return: "No Url Provided" - next: end - -return_no_type_error: - status: 400 - return: "Please Specify Endpoint Type 'Prod' Or 'Test'" - next: end diff --git a/DSL/Ruuter/services/POST/services/create-endpoint.yml b/DSL/Ruuter/services/POST/services/create-endpoint.yml index 9a7555005..7917956ae 100644 --- a/DSL/Ruuter/services/POST/services/create-endpoint.yml +++ b/DSL/Ruuter/services/POST/services/create-endpoint.yml @@ -14,9 +14,6 @@ declaration: - field: name type: string description: "Endpoint name" - - field: fileName - type: string - description: "Endpoint file name" - field: type type: string description: "Endpoint type" @@ -37,7 +34,6 @@ create_endpoint: body: endpointId: ${incoming.body.endpointId} name: ${incoming.body.name} - fileName: ${incoming.body.fileName} type: ${incoming.body.type} isCommon: ${incoming.body.isCommon} serviceId: ${incoming.body.serviceId ?? ''} diff --git a/DSL/Ruuter/services/POST/services/delete-endpoint-files.yml b/DSL/Ruuter/services/POST/services/delete-endpoint-files.yml deleted file mode 100644 index ad41d8452..000000000 --- a/DSL/Ruuter/services/POST/services/delete-endpoint-files.yml +++ /dev/null @@ -1,132 +0,0 @@ -declaration: - call: declare - version: 0.1 - description: "Decription placeholder for 'DELETE-ENDPOINTS'" - method: post - accepts: json - returns: json - namespace: service - allowlist: - body: - - field: name - type: string - description: "Body field 'name'" - - field: endpoint_name - type: string - description: "Body field 'endpoint_name'" - -extract_request_data: - assign: - name: ${incoming.body.name} - endpoint_name: ${incoming.body.endpoint_name ?? ''} - -delete_get_endpoints: - call: http.post - args: - url: "[#SERVICE_DMAPPER]/file-manager/delete-all-that-starts-with" - body: - path: "[#RUUTER_SERVICES_GET_PATH]/endpoints" - keyword: "${name}-${endpoint_name}" - result: results - -delete_get_endpoints_configs: - call: http.post - args: - url: "[#SERVICE_DMAPPER]/file-manager/delete-all-that-starts-with" - body: - path: "[#RUUTER_SERVICES_GET_PATH]/endpoints/configs" - keyword: "${name}-${endpoint_name}" - result: results - -delete_get_endpoints_info: - call: http.post - args: - url: "[#SERVICE_DMAPPER]/file-manager/delete-all-that-starts-with" - body: - path: "[#RUUTER_SERVICES_GET_PATH]/endpoints/info" - keyword: "${name}-${endpoint_name}" - result: results - -delete_post_endpoints: - call: http.post - args: - url: "[#SERVICE_DMAPPER]/file-manager/delete-all-that-starts-with" - body: - path: "[#RUUTER_SERVICES_POST_PATH]/endpoints" - keyword: "${name}-${endpoint_name}" - result: results - -delete_post_endpoints_configs: - call: http.post - args: - url: "[#SERVICE_DMAPPER]/file-manager/delete-all-that-starts-with" - body: - path: "[#RUUTER_SERVICES_POST_PATH]/endpoints/configs" - keyword: "${name}-${endpoint_name}" - result: results - -delete_post_endpoints_info: - call: http.post - args: - url: "[#SERVICE_DMAPPER]/file-manager/delete-all-that-starts-with" - body: - path: "[#RUUTER_SERVICES_POST_PATH]/endpoints/info" - keyword: "${name}-${endpoint_name}" - result: results - -delete_get_common_endpoints: - call: http.post - args: - url: "[#SERVICE_DMAPPER]/file-manager/delete-all-that-starts-with" - body: - path: "[#RUUTER_SERVICES_GET_PATH]/endpoints/common" - keyword: "${name}-${endpoint_name}" - result: results - -delete_get_common_endpoints_configs: - call: http.post - args: - url: "[#SERVICE_DMAPPER]/file-manager/delete-all-that-starts-with" - body: - path: "[#RUUTER_SERVICES_GET_PATH]/endpoints/configs/common" - keyword: "${name}-${endpoint_name}" - result: results - -delete_get_common_endpoints_info: - call: http.post - args: - url: "[#SERVICE_DMAPPER]/file-manager/delete-all-that-starts-with" - body: - path: "[#RUUTER_SERVICES_GET_PATH]/endpoints/info/common" - keyword: "${name}-${endpoint_name}" - result: results - -delete_post_common_endpoints: - call: http.post - args: - url: "[#SERVICE_DMAPPER]/file-manager/delete-all-that-starts-with" - body: - path: "[#RUUTER_SERVICES_POST_PATH]/endpoints/common" - keyword: "${name}-${endpoint_name}" - result: results - -delete_post_common_endpoints_configs: - call: http.post - args: - url: "[#SERVICE_DMAPPER]/file-manager/delete-all-that-starts-with" - body: - path: "[#RUUTER_SERVICES_POST_PATH]/endpoints/configs/common" - keyword: "${name}-${endpoint_name}" - result: results - -delete_post_common_endpoints_info: - call: http.post - args: - url: "[#SERVICE_DMAPPER]/file-manager/delete-all-that-starts-with" - body: - path: "[#RUUTER_SERVICES_POST_PATH]/endpoints/info/common" - keyword: "${name}-${endpoint_name}" - result: results - -return_result: - return: "Service Endpoints are deleted successfully" diff --git a/DSL/Ruuter/services/POST/services/delete-endpoint.yml b/DSL/Ruuter/services/POST/services/delete-endpoint.yml index b0a5d29be..bf5f6319c 100644 --- a/DSL/Ruuter/services/POST/services/delete-endpoint.yml +++ b/DSL/Ruuter/services/POST/services/delete-endpoint.yml @@ -7,31 +7,10 @@ declaration: returns: json namespace: service allowlist: - headers: - - field: cookie - type: string - description: "Cookie field" body: - field: id type: string description: "Endpoint UUID" - - field: service_name - type: string - description: "Service Name" - - field: endpoint_name - type: string - description: "Endpoint Name" - -delete_endpoint_files: - call: http.post - args: - url: "[#SERVICE_RUUTER]/services/delete-endpoint-files" - headers: - cookie: ${incoming.headers.cookie} - body: - name: ${incoming.body.service_name} - endpoint_name: ${incoming.body.endpoint_name} - result: delete_files_res delete_endpoint: call: http.post diff --git a/DSL/Ruuter/services/POST/services/delete.yml b/DSL/Ruuter/services/POST/services/delete.yml index c25e8b1b5..544e8aea4 100644 --- a/DSL/Ruuter/services/POST/services/delete.yml +++ b/DSL/Ruuter/services/POST/services/delete.yml @@ -113,18 +113,6 @@ delete_endpoints_by_service_id: body: serviceId: ${id} result: delete_endpoint_results - next: delete_endpoint_files - -delete_endpoint_files: - call: http.post - args: - url: "[#SERVICE_RUUTER]/services/delete-endpoint-files" - headers: - cookie: ${incoming.headers.cookie} - body: - name: ${name_res.response.body[0].name} - endpoint_name: "" - result: delete_endpoint_files_results next: delete_mcq_files delete_mcq_files: diff --git a/DSL/Ruuter/services/POST/services/endpoints/.guard b/DSL/Ruuter/services/POST/services/endpoints/.guard deleted file mode 100644 index 644353775..000000000 --- a/DSL/Ruuter/services/POST/services/endpoints/.guard +++ /dev/null @@ -1,4 +0,0 @@ -guard_allow_all: - return: "success" - status: 200 - next: end diff --git a/DSL/Ruuter/services/POST/services/endpoints/common/common-endpoint.yml b/DSL/Ruuter/services/POST/services/endpoints/common/common-endpoint.yml deleted file mode 100644 index 9143870e4..000000000 --- a/DSL/Ruuter/services/POST/services/endpoints/common/common-endpoint.yml +++ /dev/null @@ -1,71 +0,0 @@ -declaration: - call: declare - version: 0.1 - description: "Decription placeholder for 'COMMON-ENDPOINT'" - method: post - accepts: json - returns: json - namespace: service - allowlist: - body: - - field: type - type: string - description: "Body field 'type'" - -extract_request_data: - assign: - type: ${incoming.body.type} - next: check_for_type - -check_for_type: - switch: - - condition: ${type == null} - next: return_no_type_error - next: check_for_environment - -check_for_environment: - switch: - - condition: ${type.toLowerCase() === 'prod'} - next: get_prod_info - next: get_test_info - -get_prod_info: - call: http.post - args: - url: "[#SERVICE_ENDPOINTS]:[#SERVICE_ENDPOINTS_PORT]/services/endpoints/info/service-endpoint-prod-info" - result: info - next: check_for_endpoint_url - -get_test_info: - call: http.post - args: - url: "[#SERVICE_ENDPOINTS]:[#SERVICE_ENDPOINTS_PORT]/services/endpoints/info/service-endpoint-test-info" - result: info - next: check_for_endpoint_url - -check_for_endpoint_url: - switch: - - condition: ${info.response.body.response[0].url == null} - next: return_no_url_provided - next: execute_endpoint - -execute_endpoint: - call: http.post - args: - url: ${info.response.body.response[0].url} - result: res - next: return_info - -return_info: - return: ${res.response.body} - next: end - -return_no_url_provided: - status: 400 - return: "No Url Provided" - next: end - -return_no_type_error: - status: 400 - return: "Please Specify Endpoint Type 'Prod' Or 'Test'" - next: end diff --git a/DSL/Ruuter/services/POST/services/endpoints/configs/common/service-endpoint-prod-configs.yml b/DSL/Ruuter/services/POST/services/endpoints/configs/common/service-endpoint-prod-configs.yml deleted file mode 100644 index 6d8a30513..000000000 --- a/DSL/Ruuter/services/POST/services/endpoints/configs/common/service-endpoint-prod-configs.yml +++ /dev/null @@ -1,19 +0,0 @@ -declaration: - call: declare - version: 0.1 - description: "Decription placeholder for 'SERVICE-ENDPOINT-PROD-CONFIGS'" - method: post - accepts: json - returns: json - namespace: service - -assign_step: - assign: - sensitive: - api_key: '112218ssQQ212Prod' - username: 'User100' - password: 'pwd158' - -return_value: - wrapper: false - return: ${sensitive} diff --git a/DSL/Ruuter/services/POST/services/endpoints/configs/common/service-endpoint-test-configs.yml b/DSL/Ruuter/services/POST/services/endpoints/configs/common/service-endpoint-test-configs.yml deleted file mode 100644 index c07f0bcbe..000000000 --- a/DSL/Ruuter/services/POST/services/endpoints/configs/common/service-endpoint-test-configs.yml +++ /dev/null @@ -1,19 +0,0 @@ -declaration: - call: declare - version: 0.1 - description: "Decription placeholder for 'SERVICE-ENDPOINT-TEST-CONFIGS'" - method: post - accepts: json - returns: json - namespace: service - -assign_step: - assign: - sensitive: - api_key: '112218ssQQ212TEST' - username: 'User20' - password: 'pwd18' - -return_value: - wrapper: false - return: ${sensitive} diff --git a/DSL/Ruuter/services/POST/services/endpoints/configs/service-endpoint-prod-configs.yml b/DSL/Ruuter/services/POST/services/endpoints/configs/service-endpoint-prod-configs.yml deleted file mode 100644 index 6d8a30513..000000000 --- a/DSL/Ruuter/services/POST/services/endpoints/configs/service-endpoint-prod-configs.yml +++ /dev/null @@ -1,19 +0,0 @@ -declaration: - call: declare - version: 0.1 - description: "Decription placeholder for 'SERVICE-ENDPOINT-PROD-CONFIGS'" - method: post - accepts: json - returns: json - namespace: service - -assign_step: - assign: - sensitive: - api_key: '112218ssQQ212Prod' - username: 'User100' - password: 'pwd158' - -return_value: - wrapper: false - return: ${sensitive} diff --git a/DSL/Ruuter/services/POST/services/endpoints/configs/service-endpoint-test-configs.yml b/DSL/Ruuter/services/POST/services/endpoints/configs/service-endpoint-test-configs.yml deleted file mode 100644 index c07f0bcbe..000000000 --- a/DSL/Ruuter/services/POST/services/endpoints/configs/service-endpoint-test-configs.yml +++ /dev/null @@ -1,19 +0,0 @@ -declaration: - call: declare - version: 0.1 - description: "Decription placeholder for 'SERVICE-ENDPOINT-TEST-CONFIGS'" - method: post - accepts: json - returns: json - namespace: service - -assign_step: - assign: - sensitive: - api_key: '112218ssQQ212TEST' - username: 'User20' - password: 'pwd18' - -return_value: - wrapper: false - return: ${sensitive} diff --git a/DSL/Ruuter/services/POST/services/endpoints/info/common/service-endpoint-prod-info.yml b/DSL/Ruuter/services/POST/services/endpoints/info/common/service-endpoint-prod-info.yml deleted file mode 100644 index f66ea0318..000000000 --- a/DSL/Ruuter/services/POST/services/endpoints/info/common/service-endpoint-prod-info.yml +++ /dev/null @@ -1,25 +0,0 @@ -declaration: - call: declare - version: 0.1 - description: "Decription placeholder for 'SERVICE-ENDPOINT-PROD-INFO'" - method: post - accepts: json - returns: json - namespace: service - -getConfigs: - call: http.post - args: - url: "[#SERVICE_ENDPOINTS]:[#SERVICE_ENDPOINTS_PORT]/services/endpoints/configs/service-endpoint-prod-configs" - result: configs - -assign_step: - assign: - info: - url: https://httpbin.org/post - user_id: 10 - headers: - token: 'isdfbkajsdhkajsdhjsbckajsgdyasudhqwddasax' - -return_value: - return: ${[info , configs.response.body]} diff --git a/DSL/Ruuter/services/POST/services/endpoints/info/common/service-endpoint-test-info.yml b/DSL/Ruuter/services/POST/services/endpoints/info/common/service-endpoint-test-info.yml deleted file mode 100644 index e3d604c00..000000000 --- a/DSL/Ruuter/services/POST/services/endpoints/info/common/service-endpoint-test-info.yml +++ /dev/null @@ -1,25 +0,0 @@ -declaration: - call: declare - version: 0.1 - description: "Decription placeholder for 'SERVICE-ENDPOINT-TEST-INFO'" - method: post - accepts: json - returns: json - namespace: service - -getConfigs: - call: http.post - args: - url: "[#SERVICE_ENDPOINTS]:[#SERVICE_ENDPOINTS_PORT]/services/endpoints/configs/service-endpoint-test-configs" - result: configs - -assign_step: - assign: - info: - url: https://httpbin.org/anything - user_id: 20 - headers: - token: 'htbaslaiscvasjaskasyiuhashbxjhasgdqqysasjdhasd' - -return_value: - return: ${[info , configs.response.body]} diff --git a/DSL/Ruuter/services/POST/services/endpoints/info/service-endpoint-prod-info.yml b/DSL/Ruuter/services/POST/services/endpoints/info/service-endpoint-prod-info.yml deleted file mode 100644 index f66ea0318..000000000 --- a/DSL/Ruuter/services/POST/services/endpoints/info/service-endpoint-prod-info.yml +++ /dev/null @@ -1,25 +0,0 @@ -declaration: - call: declare - version: 0.1 - description: "Decription placeholder for 'SERVICE-ENDPOINT-PROD-INFO'" - method: post - accepts: json - returns: json - namespace: service - -getConfigs: - call: http.post - args: - url: "[#SERVICE_ENDPOINTS]:[#SERVICE_ENDPOINTS_PORT]/services/endpoints/configs/service-endpoint-prod-configs" - result: configs - -assign_step: - assign: - info: - url: https://httpbin.org/post - user_id: 10 - headers: - token: 'isdfbkajsdhkajsdhjsbckajsgdyasudhqwddasax' - -return_value: - return: ${[info , configs.response.body]} diff --git a/DSL/Ruuter/services/POST/services/endpoints/info/service-endpoint-test-info.yml b/DSL/Ruuter/services/POST/services/endpoints/info/service-endpoint-test-info.yml deleted file mode 100644 index e3d604c00..000000000 --- a/DSL/Ruuter/services/POST/services/endpoints/info/service-endpoint-test-info.yml +++ /dev/null @@ -1,25 +0,0 @@ -declaration: - call: declare - version: 0.1 - description: "Decription placeholder for 'SERVICE-ENDPOINT-TEST-INFO'" - method: post - accepts: json - returns: json - namespace: service - -getConfigs: - call: http.post - args: - url: "[#SERVICE_ENDPOINTS]:[#SERVICE_ENDPOINTS_PORT]/services/endpoints/configs/service-endpoint-test-configs" - result: configs - -assign_step: - assign: - info: - url: https://httpbin.org/anything - user_id: 20 - headers: - token: 'htbaslaiscvasjaskasyiuhashbxjhasgdqqysasjdhasd' - -return_value: - return: ${[info , configs.response.body]} diff --git a/DSL/Ruuter/services/POST/services/endpoints/service-endpoint.yml b/DSL/Ruuter/services/POST/services/endpoints/service-endpoint.yml deleted file mode 100644 index a25f1f56c..000000000 --- a/DSL/Ruuter/services/POST/services/endpoints/service-endpoint.yml +++ /dev/null @@ -1,71 +0,0 @@ -declaration: - call: declare - version: 0.1 - description: "Decription placeholder for 'SERVICE-ENDPOINT'" - method: post - accepts: json - returns: json - namespace: service - allowlist: - body: - - field: type - type: string - description: "Body field 'type'" - -extract_request_data: - assign: - type: ${incoming.body.type} - next: check_for_type - -check_for_type: - switch: - - condition: ${type == null} - next: return_no_type_error - next: check_for_environment - -check_for_environment: - switch: - - condition: ${type.toLowerCase() === 'prod'} - next: get_prod_info - next: get_test_info - -get_prod_info: - call: http.post - args: - url: "[#SERVICE_ENDPOINTS]:[#SERVICE_ENDPOINTS_PORT]/services/endpoints/info/service-endpoint-prod-info" - result: info - next: check_for_endpoint_url - -get_test_info: - call: http.post - args: - url: "[#SERVICE_ENDPOINTS]:[#SERVICE_ENDPOINTS_PORT]/services/endpoints/info/service-endpoint-test-info" - result: info - next: check_for_endpoint_url - -check_for_endpoint_url: - switch: - - condition: ${info.response.body.response[0].url == null} - next: return_no_url_provided - next: execute_endpoint - -execute_endpoint: - call: http.post - args: - url: ${info.response.body.response[0].url} - result: res - next: return_info - -return_info: - return: ${res.response.body} - next: end - -return_no_url_provided: - status: 400 - return: "No Url Provided" - next: end - -return_no_type_error: - status: 400 - return: "Please Specify Endpoint Type 'Prod' Or 'Test'" - next: end diff --git a/DSL/Ruuter/services/POST/services/update-endpoint.yml b/DSL/Ruuter/services/POST/services/update-endpoint.yml index d72ce2e18..5b2304a3e 100644 --- a/DSL/Ruuter/services/POST/services/update-endpoint.yml +++ b/DSL/Ruuter/services/POST/services/update-endpoint.yml @@ -11,9 +11,6 @@ declaration: - field: name type: string description: "Endpoint name" - - field: fileName - type: string - description: "Endpoint file name" - field: type type: string description: "Endpoint type" @@ -47,7 +44,6 @@ update_endpoint: body: endpointId: ${id} name: ${incoming.body.name} - fileName: ${incoming.body.fileName} type: ${incoming.body.type} isCommon: ${incoming.body.isCommon} serviceId: ${incoming.body.serviceId ?? ''} diff --git a/GUI/src/services/service-builder.ts b/GUI/src/services/service-builder.ts index ebb15c1eb..c2f372e4f 100644 --- a/GUI/src/services/service-builder.ts +++ b/GUI/src/services/service-builder.ts @@ -7,331 +7,29 @@ import { createEndpoint, createNewService, editService, - jsonToYml, testService, updateEndpoint, } from "resources/api-constants"; import useServiceStore from "store/new-services.store"; import useToastStore from "store/toasts.store"; -import { RawData, Step, StepType } from "types"; -import { EndpointData, EndpointDefinition, EndpointEnv, EndpointVariableData } from "types/endpoint"; +import { Step, StepType } from "types"; +import { EndpointData, EndpointVariableData } from "types/endpoint"; import api from "../services/api-dev"; import { NodeDataProps } from "types/service-flow"; import { getLastDigits, removeTrailingUnderscores, toSnakeCase } from "utils/string-util"; import { format } from "date-fns"; import { AxiosError } from "axios"; -// refactor this file later - -const getEndpointVariables = ( - key: string, - data?: { - variables: EndpointVariableData[]; - rawData: RawData; - } -): { [key: string]: any } => { - if (!data) return {}; - const result: { [key: string]: any } = {}; - data.variables.forEach((v) => { - if (["schema", "array"].includes(v.type)) { - if (v.type === "array" && v.arrayType !== "schema") { - if (v.value) result[v.name] = `\${[info.response.body.${key}["${v.name}"]]}`; - return; - } - const nestedResult: string[] = []; - getNestedVariables(v, key, v.name, nestedResult); - result[v.name] = `\${new Map([${nestedResult}])}`; - return; - } - - if (v.value) { - if (v.value.startsWith("${")) { - result[v.name] = `\${incoming.params.${v.name}}`; - } else { - result[v.name] = `\${info.response.body.${key}["${v.name}"]}`; - } - } - }); - if (Object.keys(result).length === 0) { - try { - [data.rawData.value, data.rawData.testValue].forEach((rawData) => { - if (!rawData) return; - const parsedData = JSON.parse(rawData); - Object.keys(parsedData).forEach((k) => { - if (typeof parsedData[k] === "object") { - const nestedResult: string[] = []; - getNestedRawData(parsedData[k], key, k, nestedResult); - result[k] = `\${new Map([${nestedResult}])}`; - return; - } - result[k] = `\${info.response.body.${key}["${k}"]}`; - }); - }); - } catch (e) { - console.log(e); - } - } - return result; -}; - -const getNestedVariables = (variable: EndpointVariableData, key: string, path: string, result: string[]) => { - const variableData = variable.type === "schema" ? variable.schemaData : variable.arrayData; - if (variableData instanceof Array) { - variableData.forEach((v) => { - if (["schema", "array"].includes(v.type)) { - getNestedVariables(v, key, `${path}.${v.name}`, result); - return; - } - result.push(`["${path}.${v.name}", info.response.body.${key}["${path}.${v.name}"]]`); - }); - } -}; - -const getNestedRawData = (data: { [key: string]: any }, key: string, path: string, result: string[]) => { - Object.keys(data).forEach((k) => { - if (typeof data[k] === "object") { - getNestedRawData(data[k], key, `${path}.${k}`, result); - return; - } - result.push(`["${path}.${k}", info.response.body.${key}["${path}.${k}"]]`); - }); -}; - -// Since we currently cannot mark variables as sensitive from GUI, we set all as sensitive -const saveEndpointInfo = async ( - selectedEndpoint: EndpointDefinition, - env: EndpointEnv, - endpointName: string, - endpoint: EndpointData -) => { - await saveEndpointConfig(selectedEndpoint, env, endpointName, endpoint); - - const steps = new Map(); - steps.set("get-configs", { - call: "http.post", - args: { - url: `${import.meta.env.REACT_APP_API_URL}/services/endpoints/configs/${ - endpoint.isCommon ? "common/" : "" - }${endpointName}-${env === EndpointEnv.Live ? "prod" : "test"}-configs`, - body: { - params: "${incoming.body.params}", - headers: "${incoming.body.headers}", - body: "${incoming.body.body}", - }, - }, - result: "configs", - }); - steps.set("return_value", { - wrapper: false, - return: "${configs.response.body}", - }); - const result = Object.fromEntries(steps.entries()); - - await api - .post( - jsonToYml(), - { result }, - { - params: { - location: `${import.meta.env.REACT_APP_RUUTER_SERVICES_POST_PATH}/endpoints/info/${ - endpoint.isCommon ? "common/" : "" - }${endpointName}-${env === EndpointEnv.Live ? "prod" : "test"}-info.yml`, - }, - } - ) - .then(console.log) - .catch(console.log); -}; - -const saveEndpointConfig = async ( - endpoint: EndpointDefinition, - env: EndpointEnv, - endpointName: string, - data: EndpointData -) => { - const headers = rawDataIfVariablesMissing( - endpoint, - "headers", - env, - assignEndpointVariables(env, "headers", endpoint.headers) - ); - const body = rawDataIfVariablesMissing(endpoint, "body", env, assignEndpointVariables(env, "body", endpoint.body)); - const params = rawDataIfVariablesMissing( - endpoint, - "params", - env, - assignEndpointVariables(env, "params", endpoint.params) - ); - const filteredParams = Object.fromEntries( - Object.entries(params).filter(([_, value]) => !String(value).startsWith("${")) - ); - - const filteredBody = Object.fromEntries(Object.entries(body).filter(([_, value]) => !String(value).startsWith("${"))); - - const steps = new Map(); - const variables: { [key: string]: string } = {}; - assignValues(headers, "headers", variables); - assignValues(body ? filteredBody : body, "body", variables); - assignValues(params ? filteredParams : params, "params", variables); - steps.set("prepare_step", { - assign: variables, - }); - const bodyStr = Object.keys(body ?? {}).map((b) => `["${b.replaceAll("__", ".")}", body_${b}]`); - steps.set("combine_step", { - assign: { - sensitive: `\${new Map([${ - typeof headers === "string" - ? `["headers", headers]` - : `["headers", new Map([${Object.keys(headers ?? {}).map( - (h) => `["${h.replaceAll("__", ".")}", headers_${h}]` - )}])]` - }, ${typeof body === "string" ? `["body", body]` : `["body", new Map([${bodyStr}])]`}, ${ - typeof params === "string" - ? `["params", params]` - : `["params", new Map([${Object.keys(filteredParams ?? {}).map( - (p) => `["${p.replaceAll("__", ".")}", params_${p}]` - )}])]` - }])}`, - }, - }); - steps.set("return_value", { wrapper: false, return: "${sensitive}" }); - const result = Object.fromEntries(steps.entries()); - - await api - .post( - jsonToYml(), - { result }, - { - params: { - location: `${import.meta.env.REACT_APP_RUUTER_SERVICES_POST_PATH}/endpoints/configs/${ - data.isCommon ? "common/" : "" - }${endpointName}-${env === EndpointEnv.Live ? "prod" : "test"}-configs.yml`, - }, - } - ) - .then(console.log) - .catch(console.log); -}; - -const rawDataIfVariablesMissing = ( - endpoint: EndpointDefinition, - key: "headers" | "body" | "params", - env: EndpointEnv, - data: { [key: string]: string } -): { [key: string]: any } | string => { - if (Object.keys(data).length > 0) return data; - const rawData = - endpoint[key]?.rawData[env === EndpointEnv.Live ? "value" : "testValue"] ?? endpoint[key]?.rawData.value ?? ""; - if (rawData === "") return ""; - try { - assignNestedRawVariables(JSON.parse(rawData), key, "", data); - return data; - } catch (e) { - console.error(e); - return ""; - } -}; -const assignValues = (data: string | { [key: string]: string }, key: string, variables: { [key: string]: string }) => { - if (typeof data === "string") variables[key] = data; - else - Object.keys(data).forEach((v) => { - variables[`${key}_${v}`] = data[v]; - }); -}; - -const assignNestedRawVariables = ( - data: { [key: string]: any }, - key: string, - path: string, - result: { [key: string]: string } -) => { - Object.keys(data).forEach((k) => { - if (typeof data[k] === "object") { - return assignNestedRawVariables(data[k], key, path.length === 0 ? k : `${path}__${k}`, result); - } - result[path.length > 0 ? `${path}__${k}` : k] = - typeof data[k] === "string" && data[k].startsWith("{{") - ? data[k].replace("{{", `\${incoming.body.${key}["`).replace("}}", `"]}`) - : data[k]; - }); -}; - -const assignNestedVariable = ( - variable: EndpointVariableData, - key: string, - env: EndpointEnv, - path: string, - result: { [key: string]: string } -) => { - const variableData = variable.type === "schema" ? variable.schemaData : variable.arrayData; - if (variableData instanceof Array) { - variableData.forEach((v) => { - if (["schema", "array"].includes(v.type)) assignNestedVariable(v, key, env, `${path}__${v.name}`, result); - if (!v.value) return; - - result[`${path}__${v.name}`] = (env === EndpointEnv.Test && v.testValue ? v.testValue : v.value) - .replace("{{", `\${incoming.body.${key}["`) - .replace("}}", `"]}`); - }); - } -}; - -const assignEndpointVariables = ( - env: EndpointEnv, - key: string, - data?: { variables: EndpointVariableData[]; rawData: RawData } -): { [key: string]: string } => { - if (!data) return {}; - const result: { [key: string]: string } = {}; - data.variables.forEach((v) => { - if (!v.value) { - assignNestedVariable(v, key, env, v.name, result); - return; - } - // if test value is missing use live value - result[v.name] = (env === EndpointEnv.Test && v.testValue ? v.testValue : v.value) - .replace("{{", `\${incoming.body.${key}["`) - .replace("}}", `"]}`); - }); - return result; -}; - export async function saveEndpoints(endpoints: EndpointData[], onSuccess?: () => void, onError?: (e: any) => void) { const tasks: Promise[] = []; const serviceId = useServiceStore.getState().serviceId; - const serviceName = removeTrailingUnderscores(useServiceStore.getState().serviceNameDashed()); + for (const endpoint of endpoints) { const selectedEndpointType = endpoint.definitions.find((e) => e.isSelected); if (!selectedEndpointType) continue; - - const endpointName = `${serviceName.replaceAll(" ", "_")}-${getEndpointName(endpoint)}`; - endpoint.fileName = endpointName; - for (const env of [EndpointEnv.Live, EndpointEnv.Test]) { - await saveEndpointInfo(selectedEndpointType, env, endpointName, endpoint); - } - const steps = buildSteps(endpointName, endpoint, selectedEndpointType); - const result = Object.fromEntries(steps.entries()); - endpoint.serviceId = serviceId; endpoint.isCommon = endpoint.isCommon ?? false; - const isCommonPath = endpoint.isCommon ? "common/" : ""; - - tasks.push( - api.post( - jsonToYml(), - { result }, - { - params: { - location: `${ - import.meta.env.REACT_APP_RUUTER_SERVICES_PATH - }/${selectedEndpointType.methodType.toUpperCase()}/${ - import.meta.env.REACT_APP_RUUTER_SERVICES_DIR_PATH - }/endpoints/${isCommonPath}${endpointName}.yml`, - }, - } - ) - ); } endpoints.forEach((endpoint) => { @@ -361,91 +59,6 @@ async function createEndpointAndUpdateState(endpoint: EndpointData): Promise { - const steps = new Map(); - steps.set("extract_request_data", { - assign: { - type: "${incoming.params.type}", - }, - next: "check_for_type", - }); - steps.set("check_for_type", { - switch: [{ condition: "${type == null}", next: "return_no_type_error" }], - next: "check_for_environment", - }); - steps.set("check_for_environment", { - switch: [{ condition: "${type.toLowerCase() == 'prod'}", next: "get_prod_info" }], - next: "get_test_info", - }); - steps.set("get_prod_info", { - call: "http.post", - args: { - url: `${import.meta.env.REACT_APP_API_URL}/services/endpoints/info/${ - endpoint.isCommon ? "common/" : "" - }${endpointName}-prod-info`, - body: { - params: "${incoming.body != null ? incoming.body.params ?? new Map() : new Map()}", - headers: "${incoming.body != null ? incoming.body.headers ?? new Map() : new Map()}", - body: "${incoming.body != null ? incoming.body.body ?? new Map() : new Map()}", - }, - }, - result: "info", - next: "assign_endpoint_url", - }); - steps.set("get_test_info", { - call: `http.post`, - args: { - url: `${import.meta.env.REACT_APP_API_URL}/services/endpoints/info/${ - endpoint.isCommon ? "common/" : "" - }${endpointName}-test-info`, - body: { - params: "${incoming.body != null ? incoming.body.params ?? new Map() : new Map()}", - headers: "${incoming.body != null ? incoming.body.headers ?? new Map() : new Map()}", - body: "${incoming.body != null ? incoming.body.body ?? new Map() : new Map()}", - }, - }, - result: "info", - next: "assign_endpoint_url", - }); - const endpointParams = getEndpointVariables("params", selectedEndpointType.params); - const endpointHeaders = getEndpointVariables("headers", selectedEndpointType.headers); - const endpointBody = getEndpointVariables("body", selectedEndpointType.body); - const headers = Object.keys(endpointHeaders).length > 0 ? endpointHeaders : undefined; - const params = Object.keys(endpointParams).length > 0 ? endpointParams : undefined; - const body = Object.keys(endpointBody).length > 0 ? endpointBody : undefined; - - let endpointUrl = selectedEndpointType.url?.split("?")[0]; - steps.set("assign_endpoint_url", { - assign: { - endpoint_url: endpointUrl, - }, - next: "execute_endpoint", - }); - steps.set("execute_endpoint", { - call: selectedEndpointType.methodType.toLowerCase() === "get" ? "http.get" : "http.post", - args: { - url: "${endpoint_url}", - query: params, - headers, - body, - }, - result: "res", - next: "return_result", - }); - steps.set("return_result", { - wrapper: false, - return: "${res.response.body}", - next: "end", - }); - steps.set("return_no_type_error", { - status: "400", - return: "Please Specify Endpoint Type 'prod' Or 'test'", - next: "end", - }); - - return steps; -}; - interface SaveFlowConfig { steps: Step[]; name: string; @@ -725,11 +338,11 @@ function getYamlContent(nodes: Node[], edges: Edge[], steps: Step[], name: strin const parentStepName = toSnakeCase(parentNode.data.label); if (parentNode.data.stepType === StepType.Textfield) { - return handleTextField(finishedFlow, parentStepName, parentNode, childNode, childNodeId); + return handleTextField(finishedFlow, parentStepName, parentNode, childNode); } if (parentNode.data.stepType === StepType.Assign) { - return handleAssignStep(parentNode, finishedFlow, parentStepName, childNode, childNodeId); + return handleAssignStep(parentNode, finishedFlow, parentStepName, childNode); } if (parentNode.data.stepType === StepType.Condition) { @@ -741,7 +354,7 @@ function getYamlContent(nodes: Node[], edges: Edge[], steps: Step[], name: strin } if (parentNode.data.stepType === StepType.MultiChoiceQuestion) { - return handleMultiChoiceQuestion(finishedFlow, parentStepName, parentNode, childNode, childNodeId); + return handleMultiChoiceQuestion(finishedFlow, parentStepName, parentNode, childNode); } if (parentNode.data.stepType === StepType.UserDefined) { @@ -826,7 +439,6 @@ function handleTextField( parentStepName: string, parentNode: Node, childNode: Node | undefined, - childNodeId: any ) { const htmlToMarkdown = new NodeHtmlMarkdown({ textReplace: [ @@ -888,7 +500,6 @@ function handleAssignStep( finishedFlow: Map, parentStepName: string, childNode: Node | undefined, - childNodeId: any ) { const invalidElementsExist = hasInvalidElements(parentNode.data.assignElements ?? []); const isInvalid = @@ -958,7 +569,6 @@ function handleMultiChoiceQuestion( parentStepName: string, parentNode: Node, childNode: Node | undefined, - childNodeId: any ) { return finishedFlow.set(parentStepName, { assign: { @@ -1077,10 +687,6 @@ const getTemplateDataFromNode = (node: Node): { templateName: string; body?: any } }; -const getEndpointName = (endpoint: EndpointData) => { - return `${(endpoint.name.trim().length ?? 0) > 0 ? endpoint?.name.replaceAll(" ", "_") : endpoint?.endpointId}`; -}; - export const saveFlowClick = async (status: "draft" | "ready" = "ready") => { const name = removeTrailingUnderscores(useServiceStore.getState().serviceNameDashed()); const serviceId = useServiceStore.getState().serviceId; From 24656dee4fe8793771a8d8d187319f2206f77630 Mon Sep 17 00:00:00 2001 From: Igor Krupenja Date: Tue, 29 Jul 2025 16:02:03 +0300 Subject: [PATCH 11/24] fix(634): fix the bug --- DSL/Resql/services/POST/get-common-services-list.sql | 4 ++-- DSL/Resql/services/POST/get-services-list.sql | 4 ++-- GUI/src/components/ServicesTable/index.tsx | 10 ++++++---- GUI/src/store/services.store.ts | 6 +++--- 4 files changed, 13 insertions(+), 11 deletions(-) diff --git a/DSL/Resql/services/POST/get-common-services-list.sql b/DSL/Resql/services/POST/get-common-services-list.sql index 5c8002e0e..663ee2d27 100644 --- a/DSL/Resql/services/POST/get-common-services-list.sql +++ b/DSL/Resql/services/POST/get-common-services-list.sql @@ -16,9 +16,9 @@ FROM services JOIN MaxServices ON id = maxId WHERE NOT deleted AND is_common ORDER BY - CASE WHEN :sorting = 'id asc' THEN id END ASC, CASE WHEN :sorting = 'name asc' THEN name END ASC, CASE WHEN :sorting = 'name desc' THEN name END DESC, CASE WHEN :sorting = 'state asc' THEN current_state END ASC, - CASE WHEN :sorting = 'state desc' THEN current_state END DESC + CASE WHEN :sorting = 'state desc' THEN current_state END DESC, + name ASC OFFSET ((GREATEST(:page, 1) - 1) * :page_size) LIMIT :page_size; diff --git a/DSL/Resql/services/POST/get-services-list.sql b/DSL/Resql/services/POST/get-services-list.sql index 530127dce..65e3f75a7 100644 --- a/DSL/Resql/services/POST/get-services-list.sql +++ b/DSL/Resql/services/POST/get-services-list.sql @@ -15,9 +15,9 @@ FROM services JOIN MaxServices ON id = maxId WHERE NOT deleted AND NOT is_common ORDER BY - CASE WHEN :sorting = 'id asc' THEN id END ASC, CASE WHEN :sorting = 'name asc' THEN name END ASC, CASE WHEN :sorting = 'name desc' THEN name END DESC, CASE WHEN :sorting = 'state asc' THEN current_state END ASC, - CASE WHEN :sorting = 'state desc' THEN current_state END DESC + CASE WHEN :sorting = 'state desc' THEN current_state END DESC, + name ASC OFFSET ((GREATEST(:page, 1) - 1) * :page_size) LIMIT :page_size; diff --git a/GUI/src/components/ServicesTable/index.tsx b/GUI/src/components/ServicesTable/index.tsx index a0b42d0ba..82847d6e9 100644 --- a/GUI/src/components/ServicesTable/index.tsx +++ b/GUI/src/components/ServicesTable/index.tsx @@ -33,7 +33,7 @@ const ServicesTable: FC = ({ isCommon = false }) => { pageIndex: 0, pageSize: 10, }); - const [sorting, setSorting] = useState([]); + const [sorting, setSorting] = useState([{ id: "name", desc: false }]); useEffect(() => { if (!isCommon) { @@ -201,9 +201,10 @@ const ServicesTable: FC = ({ isCommon = false }) => { - {readyPopupText != t("overview.popup.connectionPending").toString() && readyPopupText != t("overview.popup.setActive").toString() && ( - - )} + {readyPopupText != t("overview.popup.connectionPending").toString() && + readyPopupText != t("overview.popup.setActive").toString() && ( + + )} {getActiveAndConnectionButton()} )} @@ -231,6 +232,7 @@ const ServicesTable: FC = ({ isCommon = false }) => { } }} setSorting={(state: SortingState) => { + console.log("igor state", state); setSorting(state); if (!isCommon) { useServiceListStore.getState().loadServicesList(pagination, state); diff --git a/GUI/src/store/services.store.ts b/GUI/src/store/services.store.ts index 5df82015b..0aaf76f00 100644 --- a/GUI/src/store/services.store.ts +++ b/GUI/src/store/services.store.ts @@ -79,8 +79,8 @@ const useServiceListStore = create((set, get, store) => ({ commonServices: [], notCommonServices: [], loadServicesList: async (pagination, sorting) => { - const order = sorting[0]?.desc ? "desc" : "asc"; - const sort = sorting.length === 0 ? "id asc" : sorting[0]?.id + " " + order; + const order = sorting[0].desc ? "desc" : "asc"; + const sort = sorting.length === 0 ? "name asc" : sorting[0].id + " " + order; const result = await api.post(getServicesList(), { page: pagination.pageIndex + 1, page_size: pagination.pageSize, @@ -242,7 +242,7 @@ const useServiceListStore = create((set, get, store) => ({ serviceId: selectedService.serviceId, serviceName: selectedService.name, serviceMethod: selectedService.type, - serviceSlot: selectedService.slot ?? '', + serviceSlot: selectedService.slot ?? "", intent: intent, }); useToastStore.getState().success({ title: successMessage }); From 6c5fe069eb92460025e2110dad235333a487698f Mon Sep 17 00:00:00 2001 From: Igor Krupenja Date: Tue, 29 Jul 2025 16:13:38 +0300 Subject: [PATCH 12/24] fix(634): fix deletion --- GUI/src/store/services.store.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/GUI/src/store/services.store.ts b/GUI/src/store/services.store.ts index 0aaf76f00..795af56df 100644 --- a/GUI/src/store/services.store.ts +++ b/GUI/src/store/services.store.ts @@ -79,8 +79,8 @@ const useServiceListStore = create((set, get, store) => ({ commonServices: [], notCommonServices: [], loadServicesList: async (pagination, sorting) => { - const order = sorting[0].desc ? "desc" : "asc"; - const sort = sorting.length === 0 ? "name asc" : sorting[0].id + " " + order; + const order = sorting[0]?.desc ? "desc" : "asc"; + const sort = sorting.length === 0 ? "name asc" : sorting[0]?.id + " " + order; const result = await api.post(getServicesList(), { page: pagination.pageIndex + 1, page_size: pagination.pageSize, From 876ff0449e6f0faf0991540ff008d2eddbc85000 Mon Sep 17 00:00:00 2001 From: 1AhmedYasser <26207361+1AhmedYasser@users.noreply.github.com> Date: Wed, 30 Jul 2025 00:11:03 +0300 Subject: [PATCH 13/24] chore(647): Fixed Canvas Endpoint State --- .../FlowElementsPopup/ApiContent.tsx | 21 ++++++++++++++----- .../components/FlowElementsPopup/index.tsx | 16 ++++++++++---- GUI/src/store/new-services.store.ts | 2 ++ 3 files changed, 30 insertions(+), 9 deletions(-) diff --git a/GUI/src/components/FlowElementsPopup/ApiContent.tsx b/GUI/src/components/FlowElementsPopup/ApiContent.tsx index 7c06ef6f7..2944bf508 100644 --- a/GUI/src/components/FlowElementsPopup/ApiContent.tsx +++ b/GUI/src/components/FlowElementsPopup/ApiContent.tsx @@ -1,4 +1,4 @@ -import { FC } from "react"; +import { FC, useEffect, useMemo } from "react"; import Track from "../Track"; import PreviousVariables from "./PreviousVariables"; import { EndpointData } from "types/endpoint"; @@ -7,18 +7,29 @@ import ApiEndpointCard from "components/ApiEndpointCard"; type ApiContentProps = { readonly nodeId: string; readonly endpoint: EndpointData | undefined; + readonly onEndpointChange?: (endpoint: EndpointData) => void; }; -const ApiContent: FC = ({ nodeId, endpoint }) => { +const ApiContent: FC = ({ nodeId, endpoint, onEndpointChange }) => { + const endpointCopy = useMemo(() => { + return endpoint ? JSON.parse(JSON.stringify(endpoint)) : undefined; + }, [endpoint]); + + useEffect(() => { + if (onEndpointChange && endpointCopy) { + onEndpointChange(endpointCopy); + } + }, [endpointCopy, onEndpointChange]); + return ( - {endpoint && ( + {endpointCopy && ( { - endpoint.name = name; + endpointCopy.name = name; }} /> )} diff --git a/GUI/src/components/FlowElementsPopup/index.tsx b/GUI/src/components/FlowElementsPopup/index.tsx index f9d2212cd..44697bf48 100644 --- a/GUI/src/components/FlowElementsPopup/index.tsx +++ b/GUI/src/components/FlowElementsPopup/index.tsx @@ -31,6 +31,7 @@ import { Edge, getConnectedEdges, getIncomers, getOutgoers, Node } from "@xyflow import { MultiChoiceQuestionButton } from "types/multi-choice-question"; import useServiceListStore from "store/services.store"; import api from "../../services/api-dev"; +import { EndpointData } from "types/endpoint"; const FlowElementsPopup: React.FC = () => { const { t } = useTranslation(); @@ -92,6 +93,8 @@ const FlowElementsPopup: React.FC = () => { node?.data.multiChoiceQuestion?.buttons ?? defaultMultiChoiceQuestionButtons ); + const [nodeEndpoint, setNodeEndpoint] = useState(node?.data.endpoint); + const stepType = node?.data.stepType; useEffect(() => { @@ -151,6 +154,7 @@ const FlowElementsPopup: React.FC = () => { question: multiChoiceQuestionQuestion, buttons: multiChoiceQuestionButtons, }, + endpoint: nodeEndpoint ?? node.data?.endpoint, }, }; @@ -163,10 +167,10 @@ const FlowElementsPopup: React.FC = () => { } if (stepType === StepType.UserDefined) { - const newLabel = node.data.label?.toString().split(" "); - if (node.data.endpoint?.name) { - newLabel[0] = node.data.endpoint?.name ?? node.data.label?.toString().split(" ")[0]; - node.data.label = newLabel.join(" "); + const newLabel = updatedNode.data.label?.toString().split(" "); + if (updatedNode.data.endpoint?.name) { + newLabel[0] = updatedNode.data.endpoint?.name ?? node.data.label?.toString().split(" ")[0]; + updatedNode.data.label = newLabel.join(" "); } useServiceStore.getState().loadEndpointsResponseVariables(); } @@ -439,6 +443,10 @@ const FlowElementsPopup: React.FC = () => { { + if (!endpoint) return; + setNodeEndpoint(endpoint); + }} /> )} {stepType === StepType.MultiChoiceQuestion && ( diff --git a/GUI/src/store/new-services.store.ts b/GUI/src/store/new-services.store.ts index d21807986..58ab34872 100644 --- a/GUI/src/store/new-services.store.ts +++ b/GUI/src/store/new-services.store.ts @@ -739,6 +739,8 @@ const useServiceStore = create((set, get, store) => ({ fileContent: updatedNode.data.fileContent, signOption: updatedNode.data.signOption, multiChoiceQuestion: updatedNode.data.multiChoiceQuestion, + endpoint: updatedNode.data.endpoint, + label: updatedNode.data.label, }, }; }) From 90a6bbf83bba8d7461c10d5ae307c453234a29bb Mon Sep 17 00:00:00 2001 From: 1AhmedYasser <26207361+1AhmedYasser@users.noreply.github.com> Date: Wed, 30 Jul 2025 00:12:06 +0300 Subject: [PATCH 14/24] chore(647): Removed AutoComplete List --- .../Endpoints/RequestVariables/ValueCell/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/GUI/src/components/ApiEndpointCard/Endpoints/RequestVariables/ValueCell/index.tsx b/GUI/src/components/ApiEndpointCard/Endpoints/RequestVariables/ValueCell/index.tsx index 21e39dd80..c9d61848e 100644 --- a/GUI/src/components/ApiEndpointCard/Endpoints/RequestVariables/ValueCell/index.tsx +++ b/GUI/src/components/ApiEndpointCard/Endpoints/RequestVariables/ValueCell/index.tsx @@ -39,7 +39,7 @@ const ValueCell: React.FC = ({ row, requestValues, updateRowValu
{ onValueChange(row.id, v); From 9fb4448b8a94587deaf43e9b15bbe04271f8fe3b Mon Sep 17 00:00:00 2001 From: 1AhmedYasser <26207361+1AhmedYasser@users.noreply.github.com> Date: Wed, 30 Jul 2025 00:21:07 +0300 Subject: [PATCH 15/24] chore(649): Cleanup --- GUI/src/components/ApiEndpointCard/index.tsx | 5 +---- GUI/src/pages/ServiceFlowPage.tsx | 1 - 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/GUI/src/components/ApiEndpointCard/index.tsx b/GUI/src/components/ApiEndpointCard/index.tsx index 64e55cc98..13ab00b9d 100644 --- a/GUI/src/components/ApiEndpointCard/index.tsx +++ b/GUI/src/components/ApiEndpointCard/index.tsx @@ -63,10 +63,7 @@ const ApiEndpointCard: FC = ({ - {t("newService.endpoint.live")} - - - {t(testEnvExists ? "newService.endpoint.testEnv" : "newService.endpoint.addTestEnv")} + {t("newService.endpoint.single")} {isDeletable && ( diff --git a/GUI/src/pages/ServiceFlowPage.tsx b/GUI/src/pages/ServiceFlowPage.tsx index 5cfdae7c7..cf821d4a8 100644 --- a/GUI/src/pages/ServiceFlowPage.tsx +++ b/GUI/src/pages/ServiceFlowPage.tsx @@ -249,7 +249,6 @@ const ServiceFlowPage: FC = () => {
- {isChooseSlotsModalVisible && ( Date: Wed, 30 Jul 2025 00:37:24 +0300 Subject: [PATCH 16/24] chore(647): Handled Name Duplication --- GUI/src/components/FlowElementsPopup/index.tsx | 13 ++++++++++++- GUI/src/i18n/en/common.json | 4 +++- GUI/src/i18n/et/common.json | 4 +++- 3 files changed, 18 insertions(+), 3 deletions(-) diff --git a/GUI/src/components/FlowElementsPopup/index.tsx b/GUI/src/components/FlowElementsPopup/index.tsx index 44697bf48..12d6aee9f 100644 --- a/GUI/src/components/FlowElementsPopup/index.tsx +++ b/GUI/src/components/FlowElementsPopup/index.tsx @@ -32,6 +32,7 @@ import { MultiChoiceQuestionButton } from "types/multi-choice-question"; import useServiceListStore from "store/services.store"; import api from "../../services/api-dev"; import { EndpointData } from "types/endpoint"; +import useToastStore from "store/toasts.store"; const FlowElementsPopup: React.FC = () => { const { t } = useTranslation(); @@ -41,6 +42,7 @@ const FlowElementsPopup: React.FC = () => { const [jsonRequestContent, setJsonRequestContent] = useState(null); const node = useServiceStore((state) => state.selectedNode); const selectedService = useServiceListStore((state) => state.selectedService); + const instance = useServiceStore.getState().reactFlowInstance; const isUserDefinedNode = node?.data?.stepType === "user-defined"; @@ -170,6 +172,16 @@ const FlowElementsPopup: React.FC = () => { const newLabel = updatedNode.data.label?.toString().split(" "); if (updatedNode.data.endpoint?.name) { newLabel[0] = updatedNode.data.endpoint?.name ?? node.data.label?.toString().split(" ")[0]; + const nodeWithSameLabel = instance + ?.getNodes() + .find((n) => n.data.label === newLabel.join(" ") && n.id !== updatedNode.id); + if (nodeWithSameLabel) { + useToastStore.getState().error({ + title: t("newService.toast.elementNameAlreadyExists"), + message: t("newService.toast.elementNameAlreadyExistsMessage"), + }); + return; + } updatedNode.data.label = newLabel.join(" "); } useServiceStore.getState().loadEndpointsResponseVariables(); @@ -257,7 +269,6 @@ const FlowElementsPopup: React.FC = () => { }; const saveMultiChoicePopup = (originalNode: Node, updatedNode: Node) => { - const instance = useServiceStore.getState().reactFlowInstance; if (!instance) return; const currentButtons = originalNode.data.multiChoiceQuestion?.buttons ?? defaultMultiChoiceQuestionButtons; diff --git a/GUI/src/i18n/en/common.json b/GUI/src/i18n/en/common.json index 27fee144a..f95cc2474 100644 --- a/GUI/src/i18n/en/common.json +++ b/GUI/src/i18n/en/common.json @@ -259,7 +259,9 @@ "testResultError": "Test result - error", "servieNotFound": "Service not found", "serviceNotFoundEndpointsMessage": "Please save the service first to be able to add endpoints", - "serviceNameAlreadyExists": "Service name already exists" + "serviceNameAlreadyExists": "Service name already exists", + "elementNameAlreadyExists": "Element name already exists", + "elementNameAlreadyExistsMessage": "An Element with the same name already exists" }, "popup": { "unsavedChanges": "You have unsaved changes. Are you sure you want to leave? Unsaved changes will be lost." diff --git a/GUI/src/i18n/et/common.json b/GUI/src/i18n/et/common.json index 01fac8145..fe5e4e355 100644 --- a/GUI/src/i18n/et/common.json +++ b/GUI/src/i18n/et/common.json @@ -259,7 +259,9 @@ "testResultError": "Testi tulemus - viga", "servieNotFound": "Teenust ei leitud", "serviceNotFoundEndpointsMessage": "Salvesta teenus kõigepealt, et saaksid lisada otspunkte", - "serviceNameAlreadyExists": "Teenuse nimi on juba olemas" + "serviceNameAlreadyExists": "Teenuse nimi on juba olemas", + "elementNameAlreadyExists": "Elementi nimi on juba olemas", + "elementNameAlreadyExistsMessage": "Elementi sama nimega element juba eksisteerib" }, "popup": { "unsavedChanges": "Sul on salvestamata muudatusi. Kas soovid kindlasti lahkuda? Salvestamata muudatused lähevad kaotsi." From ecd6db108e902f7f13610bd6f8db8c5effd907b4 Mon Sep 17 00:00:00 2001 From: 1AhmedYasser <26207361+1AhmedYasser@users.noreply.github.com> Date: Wed, 30 Jul 2025 00:41:04 +0300 Subject: [PATCH 17/24] chore(647): Clear Endpoint State when canceling adding new endpoint --- GUI/src/components/Flow/EdgeTypes/CustomEdge.tsx | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/GUI/src/components/Flow/EdgeTypes/CustomEdge.tsx b/GUI/src/components/Flow/EdgeTypes/CustomEdge.tsx index 70013a0e5..68eaf9970 100644 --- a/GUI/src/components/Flow/EdgeTypes/CustomEdge.tsx +++ b/GUI/src/components/Flow/EdgeTypes/CustomEdge.tsx @@ -199,7 +199,13 @@ function CustomEdge({ {isAddEndpointModalVisible && ( - setIsAddEndpointModalVisible(false)}> + { + setEndpoint({ endpointId: uuid(), name: "", definitions: [], isNew: true }); + setIsAddEndpointModalVisible(false); + }} + > -