From b54c0a91ad67c92715c9f8f384437dab87b1fc4c Mon Sep 17 00:00:00 2001 From: vinicvaz Date: Tue, 20 Feb 2024 07:06:10 -0300 Subject: [PATCH 01/12] fix k8s operator to allow old pieces without shared storage --- src/domino/VERSION | 2 +- src/domino/custom_operators/k8s_operator.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/domino/VERSION b/src/domino/VERSION index 899f24fc..f514a2f0 100644 --- a/src/domino/VERSION +++ b/src/domino/VERSION @@ -1 +1 @@ -0.9.0 \ No newline at end of file +0.9.1 \ No newline at end of file diff --git a/src/domino/custom_operators/k8s_operator.py b/src/domino/custom_operators/k8s_operator.py index 128fe4e8..7f7d2c2e 100644 --- a/src/domino/custom_operators/k8s_operator.py +++ b/src/domino/custom_operators/k8s_operator.py @@ -510,7 +510,7 @@ def execute(self, context: Context): ti.xcom_push(key='pod_name', value=self.pod.metadata.name) ti.xcom_push(key='pod_namespace', value=self.pod.metadata.namespace) if self.do_xcom_push: - self._shared_storage_usage_in_bytes = result['_shared_storage_usage_in_bytes'] + self._shared_storage_usage_in_bytes = result.get('_shared_storage_usage_in_bytes', None) return result From 62d544008d15b312d81c9be467148d54436aaf4c Mon Sep 17 00:00:00 2001 From: Nathan Vieira Marcelino Date: Tue, 20 Feb 2024 12:40:53 -0300 Subject: [PATCH 02/12] docs: add docs of debbug frontend --- .gitignore | 6 ------ frontend/README.md | 51 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+), 6 deletions(-) diff --git a/.gitignore b/.gitignore index 88290ff2..5cf39cd2 100644 --- a/.gitignore +++ b/.gitignore @@ -3,8 +3,6 @@ pieces_repository_test/* airflow/* domino_data/* -.vscode/* - **/**.pyc **/**.swn **/**.swl @@ -186,10 +184,6 @@ pip-selfcheck.json ### VisualStudioCode ### .vscode/* -!.vscode/settings.json -!.vscode/tasks.json -!.vscode/launch.json -!.vscode/extensions.json ### VisualStudioCode Patch ### # Ignore all local history of files diff --git a/frontend/README.md b/frontend/README.md index 23a68bf9..22f0889e 100644 --- a/frontend/README.md +++ b/frontend/README.md @@ -45,3 +45,54 @@ DOCKER_BUILDKIT=1 docker build -f ./Dockerfile.prod -t domino-frontend . ``` ### [Project Structure](./docs/project-structure.md) + + +### Debug + +#### VSCode: + +Create a `.vscode` folder in the root project and add a `launch.json` file in it: + +```json +{ + "version": "0.2.0", + "configurations": [ + // Google Chrome configuration + { + "type": "chrome", + "request": "launch", + "name": "Chrome Debug", + "userDataDir": false, + "url": "http://localhost:3000", + "webRoot": "${workspaceFolder}/frontend/src", + "enableContentValidation": false, + "sourceMapPathOverrides": { + "webpack:///./src/*": "${webRoot}/*" + }, + "runtimeArgs": [ + "--remote-debugging-port=9222" + ], + "sourceMaps": true, + "pathMapping": {"url": "/src/", "path": "${webRoot}/"} + }, + // Microsoft Edge configuration + { + "type": "msedge", + "request": "launch", + "name": "Edge Debug", + "userDataDir": false, + "url": "http://localhost:3000", + "webRoot": "${workspaceFolder}/frontend/src", + "enableContentValidation": false, + "sourceMapPathOverrides": { + "webpack:///./src/*": "${webRoot}/*" + }, + "runtimeArgs": [ + "--remote-debugging-port=9222" + ], + "sourceMaps": true, + "pathMapping": {"url": "/src/", "path": "${webRoot}/"} + }, + ] +} +``` From fcfeeafc3cdcce5fbfb9da53d248514c052c33a5 Mon Sep 17 00:00:00 2001 From: vinicvaz Date: Wed, 21 Feb 2024 14:03:53 -0300 Subject: [PATCH 03/12] fix shared storage usage default value --- src/domino/custom_operators/docker_operator.py | 2 +- src/domino/custom_operators/k8s_operator.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/domino/custom_operators/docker_operator.py b/src/domino/custom_operators/docker_operator.py index ef30516e..9ed0f75f 100644 --- a/src/domino/custom_operators/docker_operator.py +++ b/src/domino/custom_operators/docker_operator.py @@ -191,5 +191,5 @@ def execute(self, context: Context) -> Optional[str]: # env var format = {"name": "value"} self._prepare_execute_environment(context=context) result = super().execute(context=context) - self._shared_storage_usage_in_bytes = result.get('_shared_storage_usage_in_bytes', None) + self._shared_storage_usage_in_bytes = result.get('_shared_storage_usage_in_bytes', 0) return result diff --git a/src/domino/custom_operators/k8s_operator.py b/src/domino/custom_operators/k8s_operator.py index 7f7d2c2e..63d2e081 100644 --- a/src/domino/custom_operators/k8s_operator.py +++ b/src/domino/custom_operators/k8s_operator.py @@ -510,7 +510,7 @@ def execute(self, context: Context): ti.xcom_push(key='pod_name', value=self.pod.metadata.name) ti.xcom_push(key='pod_namespace', value=self.pod.metadata.namespace) if self.do_xcom_push: - self._shared_storage_usage_in_bytes = result.get('_shared_storage_usage_in_bytes', None) + self._shared_storage_usage_in_bytes = result.get('_shared_storage_usage_in_bytes', 0) return result From cad7c49d1d2ea36cf8efaf60667c554c6c80aace Mon Sep 17 00:00:00 2001 From: Nathan Vieira Marcelino Date: Wed, 21 Feb 2024 18:07:51 -0300 Subject: [PATCH 04/12] fix: default array object new entries --- frontend/src/@types/piece/schema.d.ts | 2 +- .../CustomTabMenu/TaskResult.tsx | 3 +- .../PieceFormItem/InputElement/ArrayInput.tsx | 50 ++--------- .../InputElement/InputElement.tsx | 4 +- .../PieceFormItem/InputElement/utils.ts | 88 +++++++++++++++++++ 5 files changed, 100 insertions(+), 47 deletions(-) diff --git a/frontend/src/@types/piece/schema.d.ts b/frontend/src/@types/piece/schema.d.ts index 83e08c9f..28aa1f72 100644 --- a/frontend/src/@types/piece/schema.d.ts +++ b/frontend/src/@types/piece/schema.d.ts @@ -126,7 +126,7 @@ export type SimpleDefinition = export interface EnumDefinition { title: string; description: string; - type: "string"; + type: "string" | "number" | "integer"; enum: string[]; } diff --git a/frontend/src/features/myWorkflows/components/WorkflowDetail/CustomTabMenu/TaskResult.tsx b/frontend/src/features/myWorkflows/components/WorkflowDetail/CustomTabMenu/TaskResult.tsx index a27d0271..ef955953 100644 --- a/frontend/src/features/myWorkflows/components/WorkflowDetail/CustomTabMenu/TaskResult.tsx +++ b/frontend/src/features/myWorkflows/components/WorkflowDetail/CustomTabMenu/TaskResult.tsx @@ -16,9 +16,8 @@ export const TaskResult = ({ isLoading, }: ITaskResultProps) => { const style: CSSProperties = { - height: "100%", width: "100%", - overflowY: "scroll", + overflowY: "auto", overflowX: "hidden", wordWrap: "break-word", whiteSpace: "pre-wrap", diff --git a/frontend/src/features/workflowEditor/components/Drawers/PieceFormDrawer/PieceForm/PieceFormItem/InputElement/ArrayInput.tsx b/frontend/src/features/workflowEditor/components/Drawers/PieceFormDrawer/PieceForm/PieceFormItem/InputElement/ArrayInput.tsx index 67688edf..de5781b9 100644 --- a/frontend/src/features/workflowEditor/components/Drawers/PieceFormDrawer/PieceForm/PieceFormItem/InputElement/ArrayInput.tsx +++ b/frontend/src/features/workflowEditor/components/Drawers/PieceFormDrawer/PieceForm/PieceFormItem/InputElement/ArrayInput.tsx @@ -3,23 +3,20 @@ import DeleteIcon from "@mui/icons-material/Delete"; import { Card, CardContent, IconButton, Grid } from "@mui/material"; import CheckboxInput from "components/CheckboxInput"; import { type WorkflowPieceData } from "features/workflowEditor/context/types"; -import { - type UpstreamOptions, - getFromUpstream, -} from "features/workflowEditor/utils"; +import { type UpstreamOptions } from "features/workflowEditor/utils"; import React, { useCallback, useMemo } from "react"; import { useWatch, useFieldArray, useFormContext } from "react-hook-form"; import { disableCheckboxOptions } from "../../../../../../utils/disableCheckboxOptions"; import SelectUpstreamInput from "./SelectUpstreamInput"; -import { isObjectType } from "./utils"; +import { extractArrayDefaultValue, isObjectType } from "./utils"; import { InputElement } from "."; interface ArrayInputItemProps { inputKey: `inputs.${string}`; - schema: any; + schema: ArrayProperty; definitions?: any; upstreamOptions: UpstreamOptions; checkedFromUpstream: boolean; @@ -37,51 +34,18 @@ const ArrayInput: React.FC = React.memo( const subItemSchema = useMemo(() => { let subItemSchema: any = schema?.items; - if (schema?.items?.$ref) { - const subItemSchemaName = schema.items.$ref.split("/").pop(); + if ("$ref" in schema?.items) { + const subItemSchemaName = schema.items.$ref.split("/").pop() as string; subItemSchema = definitions?.[subItemSchemaName]; } return subItemSchema; }, [definitions, schema]); const handleAddInput = useCallback(() => { - function empty(object: Record, fromUpstream = false) { - Object.keys(object).forEach(function (k) { - if (object[k] && typeof object[k] === "object") { - return empty(object[k]); - } - if (fromUpstream) { - object[k] = getFromUpstream(schema, definitions, k); - } else { - object[k] = schema[k]?.default; - } - }); - return object; - } - const defaultValue = schema?.default?.length ? schema.default[0] : ""; - const isObject = typeof defaultValue === "object"; - let defaultObj = { - fromUpstream: getFromUpstream(schema), - upstreamArgument: "", - upstreamId: "", - upstreamValue: "", - value: schema?.default ?? null, - } as unknown; - - if (isObject) { - const emptyObjValue = empty({ ...defaultValue }); - const emptyObjFromUpstream = empty({ ...defaultValue }, true); - defaultObj = { - fromUpstream: emptyObjFromUpstream, - upstreamArgument: emptyObjValue, - upstreamId: emptyObjValue, - upstreamValue: emptyObjValue, - value: defaultValue, - } as unknown; - } + const defaultObj = extractArrayDefaultValue(schema, definitions); append([defaultObj] as any); - }, [append, definitions, schema]); + }, [append, definitions, schema, fields]); const disableUpstream = useMemo( () => disableCheckboxOptions(subItemSchema), diff --git a/frontend/src/features/workflowEditor/components/Drawers/PieceFormDrawer/PieceForm/PieceFormItem/InputElement/InputElement.tsx b/frontend/src/features/workflowEditor/components/Drawers/PieceFormDrawer/PieceForm/PieceFormItem/InputElement/InputElement.tsx index e0ad13fe..a5675118 100644 --- a/frontend/src/features/workflowEditor/components/Drawers/PieceFormDrawer/PieceForm/PieceFormItem/InputElement/InputElement.tsx +++ b/frontend/src/features/workflowEditor/components/Drawers/PieceFormDrawer/PieceForm/PieceFormItem/InputElement/InputElement.tsx @@ -109,7 +109,9 @@ const InputElement: React.FC = React.memo( name={isItemArray ? `${itemKey}.value` : itemKey} label={schema.title} - type={(schema as StringProperty).format} + type={ + (schema as StringProperty)?.format ?? (optionalType as FormatType) + } /> ); } else if (isCodeEditorType(schema, optionalType)) { diff --git a/frontend/src/features/workflowEditor/components/Drawers/PieceFormDrawer/PieceForm/PieceFormItem/InputElement/utils.ts b/frontend/src/features/workflowEditor/components/Drawers/PieceFormDrawer/PieceForm/PieceFormItem/InputElement/utils.ts index 9d7c3676..b3eb06e6 100644 --- a/frontend/src/features/workflowEditor/components/Drawers/PieceFormDrawer/PieceForm/PieceFormItem/InputElement/utils.ts +++ b/frontend/src/features/workflowEditor/components/Drawers/PieceFormDrawer/PieceForm/PieceFormItem/InputElement/utils.ts @@ -1,3 +1,5 @@ +import { getFromUpstream } from "features/workflowEditor/utils"; + export const getOptionalType = ( property: Property | EnumDefinition | EnumDefinition, ): TypeName | FormatType | undefined => { @@ -115,3 +117,89 @@ export const extractCodeEditorLanguage = (property: StringProperty) => { ? property.widget.replace("codeeditor-", "") : "python"; }; + +export const extractArrayDefaultValue = ( + property: ArrayProperty, + definitions: Definitions, +) => { + if ("$ref" in property.items) { + const definition = getDefinition( + definitions, + property.items, + ) as ObjectDefinition; + + return { + fromUpstream: emptyFromUpstreamObject( + definition, + property as ArrayObjectProperty, + definitions, + ), + upstreamValue: emptyObject(definition, ""), + upstreamId: emptyObject(definition, ""), + value: emptyObject(definition), + }; + } else { + const value = + property.items.type === "string" + ? "" + : property.items.type === "number" + ? 0.0 + : property.items.type === "boolean" + ? false + : property.items.type === "integer" + ? 0 + : null; + + return { + fromUpstream: getFromUpstream(property), + upstreamValue: "", + upstreamId: "", + value, + }; + } +}; + +function getDefinition(definitions: Definitions, ref: Reference) { + const typeClass = ref.$ref.split("/").pop() as string; + const definition = definitions?.[typeClass] ? definitions[typeClass] : null; + return definition; +} + +function emptyFromUpstreamObject( + object: ObjectDefinition, + property: ArrayObjectProperty, + definitions: Definitions, +) { + const newObject: Record = {}; + + Object.keys(object.properties).forEach((k) => { + const fromUpstream = getFromUpstream(property, definitions, k); + newObject[k] = fromUpstream; + }); + return newObject; +} + +function emptyObject(objectDefinition: ObjectDefinition, defaultValue?: any) { + const newObject: Record = {}; + + for (const [key, property] of Object.entries(objectDefinition.properties)) { + if ("anyOf" in property) { + newObject[key] = ""; + } else { + const value = + property.type === "string" + ? "" + : property.type === "number" + ? 0.0 + : property.type === "boolean" + ? false + : property.type === "integer" + ? 0 + : null; + + newObject[key] = defaultValue ?? value; + } + } + + return newObject; +} From c28f63418894097092bf634adf04d914dcbf2ffe Mon Sep 17 00:00:00 2001 From: Nathan Vieira Marcelino Date: Thu, 22 Feb 2024 14:16:56 -0300 Subject: [PATCH 05/12] fix: inputs errors messages --- .../src/components/DatetimeInput/index.tsx | 61 +++++++++++++++---- .../PieceFormDrawer/ContainerResourceForm.tsx | 4 +- .../InputElement/InputElement.tsx | 5 +- .../workflowEditor/utils/validation.ts | 12 +++- 4 files changed, 64 insertions(+), 18 deletions(-) diff --git a/frontend/src/components/DatetimeInput/index.tsx b/frontend/src/components/DatetimeInput/index.tsx index 350f67e7..94e31089 100644 --- a/frontend/src/components/DatetimeInput/index.tsx +++ b/frontend/src/components/DatetimeInput/index.tsx @@ -1,3 +1,4 @@ +import { FormHelperText } from "@mui/material"; import { DatePicker, DateTimePicker, @@ -14,28 +15,34 @@ import { type Path, useFormContext, } from "react-hook-form"; +import { fetchFromObject } from "utils"; interface Props { label: string; name: Path; type?: "time" | "date" | "date-time"; - defaultValue?: Date; + defaultValue?: string | null; } function DatetimeInput({ label, name, type = "date", - defaultValue = new Date(), + defaultValue = null, }: Props) { - const { control } = useFormContext(); + const { + control, + formState: { errors }, + } = useFormContext(); + + const error = fetchFromObject(errors, name); switch (type) { case "date-time": { - const defaultDateTime = dayjs( - defaultValue ?? new Date(), - "YYYY-MM-DD HH:mm", - ); + const defaultDateTime = + typeof defaultValue === "string" + ? dayjs(new Date(defaultValue), "YYYY-MM-DD HH:mm") + : defaultValue; return ( ({ label={label} ampm={false} format="DD/MM/YYYY HH:mm" - value={dayjs(value)} + value={value ? dayjs(value) : null} onChange={(e) => { e?.isValid() ? onChange(e.toISOString()) : onChange(null); }} + slotProps={{ + textField: { + error: !!error, + helperText: ( + {error?.message} + ), + }, + }} {...rest} /> @@ -62,7 +77,10 @@ function DatetimeInput({ ); } case "time": { - const defaultTime = dayjs(defaultValue ?? new Date(), "HH:mm"); + const defaultTime = + typeof defaultValue === "string" + ? dayjs(defaultValue, "HH:mm") + : defaultValue; return ( ({ label={label} format="HH:mm" sx={{ width: "100%" }} - value={dayjs(value as string, "HH:mm")} + value={value ? dayjs(value as string, "HH:mm") : null} onChange={(e) => { e?.isValid() ? onChange(dayjs(e).format("HH:mm") as any) : onChange(null); }} + slotProps={{ + textField: { + error: !!error, + helperText: ( + {error?.message} + ), + }, + }} {...rest} /> @@ -94,7 +120,10 @@ function DatetimeInput({ case "date": default: // eslint-disable-next-line no-case-declarations - const defaultDate = dayjs(defaultValue ?? new Date(), "YYYY-MM-DD"); + const defaultDate = + typeof defaultValue === "string" + ? dayjs(defaultValue, "YYYY-MM-DD") + : defaultValue; return ( ({ views={["day", "month", "year"]} format="DD/MM/YYYY" sx={{ width: "100%" }} - value={dayjs(value as string)} + value={value ? dayjs(value as string) : null} onChange={(e) => { e?.isValid() ? onChange(dayjs(e).format("YYYY-MM-DD") as any) : onChange(null); }} + slotProps={{ + textField: { + error: !!error, + helperText: ( + {error?.message} + ), + }, + }} {...rest} /> diff --git a/frontend/src/features/workflowEditor/components/Drawers/PieceFormDrawer/ContainerResourceForm.tsx b/frontend/src/features/workflowEditor/components/Drawers/PieceFormDrawer/ContainerResourceForm.tsx index 87af18d3..57fda23c 100644 --- a/frontend/src/features/workflowEditor/components/Drawers/PieceFormDrawer/ContainerResourceForm.tsx +++ b/frontend/src/features/workflowEditor/components/Drawers/PieceFormDrawer/ContainerResourceForm.tsx @@ -29,14 +29,14 @@ export const ContainerResourceFormSchema: yup.ObjectSchema (isNaN(value) ? undefined : value)) .max(maxAcceptedCpu) .min(minAcceptedCpu) .required(), max: yup .number() .integer() - .typeError("Must be a number") + .transform((value) => (isNaN(value) ? undefined : value)) .max(maxAcceptedCpu) .when("min", ([min], schema) => schema.min(min)) .required(), diff --git a/frontend/src/features/workflowEditor/components/Drawers/PieceFormDrawer/PieceForm/PieceFormItem/InputElement/InputElement.tsx b/frontend/src/features/workflowEditor/components/Drawers/PieceFormDrawer/PieceForm/PieceFormItem/InputElement/InputElement.tsx index e0ad13fe..6967dc46 100644 --- a/frontend/src/features/workflowEditor/components/Drawers/PieceFormDrawer/PieceForm/PieceFormItem/InputElement/InputElement.tsx +++ b/frontend/src/features/workflowEditor/components/Drawers/PieceFormDrawer/PieceForm/PieceFormItem/InputElement/InputElement.tsx @@ -109,7 +109,10 @@ const InputElement: React.FC = React.memo( name={isItemArray ? `${itemKey}.value` : itemKey} label={schema.title} - type={(schema as StringProperty).format} + defaultValue={(schema as StringProperty)?.default} + type={ + (schema as StringProperty)?.format ?? (optionalType as FormatType) + } /> ); } else if (isCodeEditorType(schema, optionalType)) { diff --git a/frontend/src/features/workflowEditor/utils/validation.ts b/frontend/src/features/workflowEditor/utils/validation.ts index ab00dc08..5d1c4487 100644 --- a/frontend/src/features/workflowEditor/utils/validation.ts +++ b/frontend/src/features/workflowEditor/utils/validation.ts @@ -74,7 +74,10 @@ function getValidationValueBySchemaType(schema: any, required: boolean) { if (fromUpstream) { return yup.mixed().notRequired(); } - return yup.number().typeError("Must must be a number").required(); // number is always required + return yup + .number() + .transform((value) => (isNaN(value) ? undefined : value)) + .required(); // number is always required }), }); } else if (schema.type === "integer" && !schema.format) { @@ -87,7 +90,7 @@ function getValidationValueBySchemaType(schema: any, required: boolean) { return yup .number() .integer() - .typeError("Must must be a number") + .transform((value) => (isNaN(value) ? undefined : value)) .required(); // number is always required }), }); @@ -108,7 +111,10 @@ function getValidationValueBySchemaType(schema: any, required: boolean) { if (fromUpstream) { return yup.mixed().notRequired(); } - return yup.date().required(); // date is always required + return yup + .date() + .transform((value) => (isNaN(value) ? undefined : value)) + .required(); // date is always required }), }); } else if (schema.type === "string" && schema?.format === "time") { From 5aa47cf1b655028f38e0a00e4f6153ead6972cc6 Mon Sep 17 00:00:00 2001 From: vinicvaz Date: Thu, 22 Feb 2024 15:38:09 -0300 Subject: [PATCH 06/12] update default pieces version --- rest/core/settings.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/rest/core/settings.py b/rest/core/settings.py index 5d96b398..d051a48d 100644 --- a/rest/core/settings.py +++ b/rest/core/settings.py @@ -43,35 +43,35 @@ class Settings(BaseSettings): DEFAULT_REPOSITORIES_LIST: list[dict] = [ dict( path="Tauffer-Consulting/default_domino_pieces", - version='0.8.0', + version='0.8.1', source='github', require_token=False, url='https://github.com/Tauffer-Consulting/default_domino_pieces' ), dict( path="Tauffer-Consulting/openai_domino_pieces", - version='0.7.1', + version='0.7.2', source='github', require_token=True, url='https://github.com/Tauffer-Consulting/openai_domino_pieces' ), dict( path="Tauffer-Consulting/social_media_domino_pieces", - version='0.5.2', + version='0.5.4', source='github', require_token=True, url='https://github.com/Tauffer-Consulting/social_media_domino_pieces' ), dict( path="Tauffer-Consulting/data_apis_domino_pieces", - version='0.2.1', + version='0.2.3', source='github', require_token=True, url='https://github.com/Tauffer-Consulting/data_apis_domino_pieces' ), dict( path="Tauffer-Consulting/ml_domino_pieces", - version='0.2.1', + version='0.2.2', source='github', require_token=True, url='https://github.com/Tauffer-Consulting/ml_domino_pieces' From e8f909b4d64751bc429aae09fed5f080cda36773 Mon Sep 17 00:00:00 2001 From: Nathan Vieira Marcelino Date: Thu, 22 Feb 2024 16:34:44 -0300 Subject: [PATCH 07/12] fix: import with incompatible versions should not handle json --- .../src/features/workflowEditor/components/ButtonsMenu/index.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/frontend/src/features/workflowEditor/components/ButtonsMenu/index.tsx b/frontend/src/features/workflowEditor/components/ButtonsMenu/index.tsx index b6303c7f..31df0d85 100644 --- a/frontend/src/features/workflowEditor/components/ButtonsMenu/index.tsx +++ b/frontend/src/features/workflowEditor/components/ButtonsMenu/index.tsx @@ -95,6 +95,7 @@ export const ButtonsMenu: React.FC = ({ setIncompatiblesPieces(differences); incompatiblePiecesModalRef.current?.open(); + return; } handleImported(json); From a0958163c595512f46d3c402de0c9a3dfc8b62a1 Mon Sep 17 00:00:00 2001 From: vinicvaz Date: Fri, 23 Feb 2024 10:45:58 -0300 Subject: [PATCH 08/12] typo --- frontend/src/context/workspaces/workspaces.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/context/workspaces/workspaces.tsx b/frontend/src/context/workspaces/workspaces.tsx index b79f421f..d449050b 100644 --- a/frontend/src/context/workspaces/workspaces.tsx +++ b/frontend/src/context/workspaces/workspaces.tsx @@ -181,7 +181,7 @@ export const WorkspacesProvider: FC = ({ async (name: string) => await postWorkspace({ name }) .then((data) => { - toast.success(`Workflow ${name} created successfully`); + toast.success(`Workspace ${name} created successfully`); void workspacesRefresh(); return data; }) From 3cc48591c955ba79920286f94e7a606653e3e500 Mon Sep 17 00:00:00 2001 From: Nathan Vieira Marcelino Date: Fri, 23 Feb 2024 11:26:34 -0300 Subject: [PATCH 09/12] fix: object array with optional inputs --- frontend/src/@types/piece/index.d.ts | 2 + frontend/src/@types/piece/schema.d.ts | 18 +++-- .../components/WorkflowDetail/index.tsx | 16 ++-- .../PieceFormItem/InputElement/ArrayInput.tsx | 14 ++-- .../InputElement/InputElement.tsx | 2 + .../PieceFormItem/InputElement/utils.ts | 81 +++++++++++++++---- .../PieceForm/PieceFormItem/index.tsx | 7 +- .../workflowEditor/utils/getDefinition.ts | 5 ++ .../workflowEditor/utils/getFromUpstream.ts | 41 +++++++++- .../features/workflowEditor/utils/index.ts | 5 +- frontend/src/utils/getDefinition.ts | 16 ---- frontend/src/utils/index.ts | 1 - 12 files changed, 150 insertions(+), 58 deletions(-) create mode 100644 frontend/src/features/workflowEditor/utils/getDefinition.ts delete mode 100644 frontend/src/utils/getDefinition.ts diff --git a/frontend/src/@types/piece/index.d.ts b/frontend/src/@types/piece/index.d.ts index aec5da75..d9dbd844 100644 --- a/frontend/src/@types/piece/index.d.ts +++ b/frontend/src/@types/piece/index.d.ts @@ -15,6 +15,8 @@ declare global { type Property = import("./schema").Property; type SimpleProperty = import("./schema").SimpleProperty; type ArrayProperty = import("./schema").ArrayProperty; + type AnyOfArray = import("./schema").AnyOfArray; + type AnyOf = import("./schema").AnyOf; type AnyOfProperty = import("./schema").AnyOfProperty; type StringProperty = import("./schema").StringProperty; diff --git a/frontend/src/@types/piece/schema.d.ts b/frontend/src/@types/piece/schema.d.ts index 28aa1f72..e5732631 100644 --- a/frontend/src/@types/piece/schema.d.ts +++ b/frontend/src/@types/piece/schema.d.ts @@ -98,17 +98,21 @@ export interface Reference { $ref: `#/$defs/${string}`; } -type AnyOf = DefaultPropertyAttrs & { - anyOf: Array<{ - type: "null" | "number" | "integer" | "string" | "boolean"; - widget?: `codeeditor-${string}` | "textarea"; - format?: "date" | "time" | "date-time"; - }>; +export type AnyOf = DefaultPropertyAttrs & { + anyOf: Array< + { + type: "null" | "number" | "integer" | "string" | "boolean"; + widget?: `codeeditor-${string}` | "textarea"; + format?: "date" | "time" | "date-time"; + } & DefaultPropertyAttrs + >; default?: any; }; export type AnyOfArray = DefaultPropertyAttrs & { - anyOf: Array<{ items: AnyOf["anyOf"]; type: "array" } | { type: "null" }>; + anyOf: Array< + { items: AnyOf["anyOf"] | Reference; type: "array" } | { type: "null" } + >; default?: any[]; }; diff --git a/frontend/src/features/myWorkflows/components/WorkflowDetail/index.tsx b/frontend/src/features/myWorkflows/components/WorkflowDetail/index.tsx index 6ba18d72..2369001c 100644 --- a/frontend/src/features/myWorkflows/components/WorkflowDetail/index.tsx +++ b/frontend/src/features/myWorkflows/components/WorkflowDetail/index.tsx @@ -59,6 +59,15 @@ export const WorkflowDetail: React.FC = () => { const fetchWorkflowTasks = useAuthenticatedGetWorkflowRunTasks(); const handleRunWorkflow = useAuthenticatedPostWorkflowRunId(); + const triggerRun = () => { + if (workflow?.id) { + void handleRunWorkflow({ id: String(workflow.id) }); + setInterval(() => { + setAutoUpdate(true); + }, 1500); + } + }; + const refreshDetails = useCallback(() => { void workflowRunDetailRef.current?.refreshTaskLogs(); void workflowRunDetailRef.current?.refreshTaskResults(); @@ -208,12 +217,7 @@ export const WorkflowDetail: React.FC = () => { {/* WorkflowRunsTable */} { - if (workflow?.id) { - void handleRunWorkflow({ id: String(workflow.id) }); - setAutoUpdate(true); - } - }} + triggerRun={triggerRun} refresh={refresh} selectedRun={selectedRun} ref={workflowRunsTableRef} diff --git a/frontend/src/features/workflowEditor/components/Drawers/PieceFormDrawer/PieceForm/PieceFormItem/InputElement/ArrayInput.tsx b/frontend/src/features/workflowEditor/components/Drawers/PieceFormDrawer/PieceForm/PieceFormItem/InputElement/ArrayInput.tsx index de5781b9..72e395ce 100644 --- a/frontend/src/features/workflowEditor/components/Drawers/PieceFormDrawer/PieceForm/PieceFormItem/InputElement/ArrayInput.tsx +++ b/frontend/src/features/workflowEditor/components/Drawers/PieceFormDrawer/PieceForm/PieceFormItem/InputElement/ArrayInput.tsx @@ -16,7 +16,7 @@ import { InputElement } from "."; interface ArrayInputItemProps { inputKey: `inputs.${string}`; - schema: ArrayProperty; + schema: ArrayProperty | AnyOfArray; definitions?: any; upstreamOptions: UpstreamOptions; checkedFromUpstream: boolean; @@ -33,11 +33,15 @@ const ArrayInput: React.FC = React.memo( const formsData = useWatch({ name }); const subItemSchema = useMemo(() => { - let subItemSchema: any = schema?.items; - if ("$ref" in schema?.items) { - const subItemSchemaName = schema.items.$ref.split("/").pop() as string; + let subItemSchema = + "items" in schema + ? schema.items + : (schema.anyOf.find((s) => s.type === "array") as any)?.items; + if (subItemSchema && "$ref" in subItemSchema && subItemSchema?.$ref) { + const subItemSchemaName = subItemSchema.$ref.split("/").pop() as string; subItemSchema = definitions?.[subItemSchemaName]; } + return subItemSchema; }, [definitions, schema]); @@ -48,7 +52,7 @@ const ArrayInput: React.FC = React.memo( }, [append, definitions, schema, fields]); const disableUpstream = useMemo( - () => disableCheckboxOptions(subItemSchema), + () => (subItemSchema ? disableCheckboxOptions(subItemSchema) : false), [subItemSchema], ); diff --git a/frontend/src/features/workflowEditor/components/Drawers/PieceFormDrawer/PieceForm/PieceFormItem/InputElement/InputElement.tsx b/frontend/src/features/workflowEditor/components/Drawers/PieceFormDrawer/PieceForm/PieceFormItem/InputElement/InputElement.tsx index 6967dc46..8a7c337f 100644 --- a/frontend/src/features/workflowEditor/components/Drawers/PieceFormDrawer/PieceForm/PieceFormItem/InputElement/InputElement.tsx +++ b/frontend/src/features/workflowEditor/components/Drawers/PieceFormDrawer/PieceForm/PieceFormItem/InputElement/InputElement.tsx @@ -154,6 +154,8 @@ const InputElement: React.FC = React.memo( /> ); } else { + console.log("optionalType", optionalType); + return (
Unknown widget type for {schema.title} diff --git a/frontend/src/features/workflowEditor/components/Drawers/PieceFormDrawer/PieceForm/PieceFormItem/InputElement/utils.ts b/frontend/src/features/workflowEditor/components/Drawers/PieceFormDrawer/PieceForm/PieceFormItem/InputElement/utils.ts index b3eb06e6..5b8c315f 100644 --- a/frontend/src/features/workflowEditor/components/Drawers/PieceFormDrawer/PieceForm/PieceFormItem/InputElement/utils.ts +++ b/frontend/src/features/workflowEditor/components/Drawers/PieceFormDrawer/PieceForm/PieceFormItem/InputElement/utils.ts @@ -1,9 +1,9 @@ -import { getFromUpstream } from "features/workflowEditor/utils"; +import { getDefinition, getFromUpstream } from "features/workflowEditor/utils"; export const getOptionalType = ( property: Property | EnumDefinition | EnumDefinition, ): TypeName | FormatType | undefined => { - if ("anyOf" in property && property.anyOf.length === 2) { + if (property && "anyOf" in property && property.anyOf.length === 2) { const hasNullType = property.anyOf.some((item) => item.type === "null"); if (hasNullType) { const itemSchema = property.anyOf.find( @@ -119,10 +119,10 @@ export const extractCodeEditorLanguage = (property: StringProperty) => { }; export const extractArrayDefaultValue = ( - property: ArrayProperty, + property: ArrayProperty | AnyOfArray, definitions: Definitions, ) => { - if ("$ref" in property.items) { + if ("items" in property && "$ref" in property.items) { const definition = getDefinition( definitions, property.items, @@ -138,15 +138,72 @@ export const extractArrayDefaultValue = ( upstreamId: emptyObject(definition, ""), value: emptyObject(definition), }; + } else if ( + "anyOf" in property && + property.anyOf.find((s) => s.type === "array" && "$ref" in s.items) + ) { + const anyOf = property.anyOf.find( + (s) => s.type === "array" && "$ref" in s.items, + ) as { items: Reference; type: "array" }; + + const subProperty = getDefinition( + definitions, + anyOf.items, + ) as ObjectDefinition; + + const response = { + fromUpstream: emptyFromUpstreamObject(subProperty, property, definitions), + upstreamValue: emptyObject(subProperty, ""), + upstreamId: emptyObject(subProperty, ""), + value: emptyObject(subProperty), + }; + + console.log("ta caindo aqui", response); + + return response; + } else if ( + "anyOf" in property && + property.anyOf.find((s) => s.type === "array" && !("$ref" in s.items)) + ) { + const anyOf = property.anyOf.find( + (s) => s.type === "array" && "$ref" in s.items, + ) as { items: AnyOf["anyOf"]; type: "array" }; + + const subProperty = anyOf.items.find((i) => i.type !== "null"); + + const value = + subProperty?.type === "string" + ? "" + : subProperty?.type === "number" + ? 0.0 + : subProperty?.type === "boolean" + ? false + : subProperty?.type === "integer" + ? 0 + : null; + + return { + fromUpstream: getFromUpstream(property), + upstreamValue: "", + upstreamId: "", + value, + }; } else { + const subProperty = ( + property as + | ArrayBooleanProperty + | ArrayNumberProperty + | ArrayStringProperty + ).items; + const value = - property.items.type === "string" + subProperty.type === "string" ? "" - : property.items.type === "number" + : subProperty.type === "number" ? 0.0 - : property.items.type === "boolean" + : subProperty.type === "boolean" ? false - : property.items.type === "integer" + : subProperty.type === "integer" ? 0 : null; @@ -159,15 +216,9 @@ export const extractArrayDefaultValue = ( } }; -function getDefinition(definitions: Definitions, ref: Reference) { - const typeClass = ref.$ref.split("/").pop() as string; - const definition = definitions?.[typeClass] ? definitions[typeClass] : null; - return definition; -} - function emptyFromUpstreamObject( object: ObjectDefinition, - property: ArrayObjectProperty, + property: ArrayObjectProperty | AnyOfArray, definitions: Definitions, ) { const newObject: Record = {}; diff --git a/frontend/src/features/workflowEditor/components/Drawers/PieceFormDrawer/PieceForm/PieceFormItem/index.tsx b/frontend/src/features/workflowEditor/components/Drawers/PieceFormDrawer/PieceForm/PieceFormItem/index.tsx index 0c60c05a..6fe3efad 100644 --- a/frontend/src/features/workflowEditor/components/Drawers/PieceFormDrawer/PieceForm/PieceFormItem/index.tsx +++ b/frontend/src/features/workflowEditor/components/Drawers/PieceFormDrawer/PieceForm/PieceFormItem/index.tsx @@ -8,6 +8,7 @@ import React, { useMemo } from "react"; import { useWatch } from "react-hook-form"; import { InputElement, ArrayInput, isArrayInput } from "./InputElement"; +import { getOptionalType } from "./InputElement/utils"; interface PieceFormItemProps { schema: Property; @@ -30,6 +31,8 @@ const PieceFormItem: React.FC = ({ name: `inputs.${itemKey}.fromUpstream`, }); + const optionalType = getOptionalType(schema); + return ( = ({ sx={{ paddingTop: "10px" }} > - {isArrayInput(schema) ? ( + {isArrayInput(schema, optionalType) ? ( s.type === "array" && "$ref" in s.items) && + definitions && + key + ) { + const anyOf = itemSchema.anyOf.find( + (s) => s.type === "array" && "$ref" in s.items, + ) as { items: Reference; type: "array" }; + + const subProperty = getDefinition( + definitions, + anyOf.items, + ) as ObjectDefinition; + + const property = subProperty?.properties[key]; + + if ("from_upstream" in property) { + switch (property?.from_upstream) { + case "always": + return true; + + case "allowed": + case "never": + default: + return false; + } + } else { + return false; + } + } + switch ((itemSchema as Property)?.from_upstream) { case "always": return true; diff --git a/frontend/src/features/workflowEditor/utils/index.ts b/frontend/src/features/workflowEditor/utils/index.ts index 69ddd2b2..08292410 100644 --- a/frontend/src/features/workflowEditor/utils/index.ts +++ b/frontend/src/features/workflowEditor/utils/index.ts @@ -1,7 +1,8 @@ +export * from "./disableCheckboxOptions"; +export * from "./getDefinition"; export * from "./getFromUpstream"; +export * from "./graph"; export * from "./importWorkflow"; export * from "./jsonSchema"; export * from "./upstreamOptions"; export * from "./validation"; -export * from "./graph"; -export * from "./disableCheckboxOptions"; diff --git a/frontend/src/utils/getDefinition.ts b/frontend/src/utils/getDefinition.ts deleted file mode 100644 index 8a3532a7..00000000 --- a/frontend/src/utils/getDefinition.ts +++ /dev/null @@ -1,16 +0,0 @@ -export function getDefinition( - schema: Property | SimpleProperty | EnumDefinition, - definitions: Definitions, -) { - if ("items" in schema && "$ref" in schema.items) { - const definitionName = schema.items.$ref.split("/").pop() as string; - return definitions[definitionName]; - } else if ("allOf" in schema) { - const definitionName = schema.allOf[0].$ref.split("/").pop() as string; - return definitions[definitionName]; - } else if ("items" in schema) { - return schema.items; - } else { - return schema; - } -} diff --git a/frontend/src/utils/index.ts b/frontend/src/utils/index.ts index 3cd15901..881ba8c4 100644 --- a/frontend/src/utils/index.ts +++ b/frontend/src/utils/index.ts @@ -3,7 +3,6 @@ export { fetchFromObject } from "./fetchFromObject"; export { yupResolver } from "./validationResolver"; export { getIdSlice, getUuidSlice, getUuid } from "./getUuidSlice"; export { generateTaskName } from "./generateTaskName"; -export { getDefinition } from "./getDefinition"; export { lazyImport } from "./lazyImports"; export { useInterval } from "./useInterval"; export { useMouseProximity } from "./useMouseProximity"; From 8a29c29c14082adef70590d965854c3c296d14fc Mon Sep 17 00:00:00 2001 From: Nathan Vieira Marcelino Date: Fri, 23 Feb 2024 11:49:38 -0300 Subject: [PATCH 10/12] chore: CHANGELOG.md --- CHANGELOG.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index efc97e20..9e4f53b1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,14 @@ +# v0.8.5 + +### Fixes +- [x] fix k8s operator to allow old pieces without shared storage usage info +- [x] fix errors messages on some inputs +- [x] fix import incompatible JSONs should not add anything to the workflow +- [x] fix new entries of object arrays + +### Docs +- [x] added how to debug in frontend docs + # v0.8.4 ### Features From 17023a37d78fe4b22d6aa37d25baf0b665ebba8c Mon Sep 17 00:00:00 2001 From: Nathan Vieira Marcelino Date: Fri, 23 Feb 2024 13:50:09 -0300 Subject: [PATCH 11/12] fix: array upstream --- .../PieceForm/PieceFormItem/InputElement/ArrayInput.tsx | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/frontend/src/features/workflowEditor/components/Drawers/PieceFormDrawer/PieceForm/PieceFormItem/InputElement/ArrayInput.tsx b/frontend/src/features/workflowEditor/components/Drawers/PieceFormDrawer/PieceForm/PieceFormItem/InputElement/ArrayInput.tsx index 72e395ce..fde5d913 100644 --- a/frontend/src/features/workflowEditor/components/Drawers/PieceFormDrawer/PieceForm/PieceFormItem/InputElement/ArrayInput.tsx +++ b/frontend/src/features/workflowEditor/components/Drawers/PieceFormDrawer/PieceForm/PieceFormItem/InputElement/ArrayInput.tsx @@ -56,7 +56,10 @@ const ArrayInput: React.FC = React.memo( [subItemSchema], ); - const options = useMemo(() => upstreamOptions[inputKey], []); + const options = useMemo(() => { + const upstreamKey = inputKey.replace("inputs.", ""); + return upstreamOptions[upstreamKey]; + }, [upstreamOptions]); const isFromUpstream = useCallback( (index: number) => { From fe8e95fa90483e71bf6b040d6f93ccc0b398dd0e Mon Sep 17 00:00:00 2001 From: vinicvaz Date: Fri, 23 Feb 2024 14:10:39 -0300 Subject: [PATCH 12/12] update changelog --- CHANGELOG.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 35cc8d6b..185c2ec1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,13 +1,13 @@ # v0.9.1 ### Fixes -- [x] fix k8s operator to allow old pieces without shared storage usage info -- [x] fix errors messages on some inputs -- [x] fix import incompatible JSONs should not add anything to the workflow -- [x] fix new entries of object arrays - +- [x] Fix Domino k8s Operator to allow handle old pieces without shared storage usage info. +- [x] Fix errors messages on some inputs. +- [x] Fix import incompatible JSONs should not add anything to the workflow. +- [x] Fix new entries of object arrays. + ### Docs -- [x] added how to debug in frontend docs +- [x] Added how to debug in frontend docs. # v0.9.0