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/CHANGELOG.md b/CHANGELOG.md index d1459ade..185c2ec1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,14 @@ +# v0.9.1 + +### Fixes +- [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. + # v0.9.0 ### Features 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}/"} + }, + ] +} +``` 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 83e08c9f..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[]; }; @@ -126,7 +130,7 @@ export type SimpleDefinition = export interface EnumDefinition { title: string; description: string; - type: "string"; + type: "string" | "number" | "integer"; enum: string[]; } 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/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; }) 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/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/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); 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/ArrayInput.tsx b/frontend/src/features/workflowEditor/components/Drawers/PieceFormDrawer/PieceForm/PieceFormItem/InputElement/ArrayInput.tsx index 67688edf..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 @@ -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 | AnyOfArray; definitions?: any; upstreamOptions: UpstreamOptions; checkedFromUpstream: boolean; @@ -36,59 +33,33 @@ const ArrayInput: React.FC = React.memo( const formsData = useWatch({ name }); const subItemSchema = useMemo(() => { - let subItemSchema: any = schema?.items; - if (schema?.items?.$ref) { - const subItemSchemaName = schema.items.$ref.split("/").pop(); + 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]); 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), + () => (subItemSchema ? disableCheckboxOptions(subItemSchema) : false), [subItemSchema], ); - const options = useMemo(() => upstreamOptions[inputKey], []); + const options = useMemo(() => { + const upstreamKey = inputKey.replace("inputs.", ""); + return upstreamOptions[upstreamKey]; + }, [upstreamOptions]); const isFromUpstream = useCallback( (index: number) => { 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..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 @@ -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)) { @@ -151,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 9d7c3676..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,7 +1,9 @@ +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( @@ -115,3 +117,140 @@ export const extractCodeEditorLanguage = (property: StringProperty) => { ? property.widget.replace("codeeditor-", "") : "python"; }; + +export const extractArrayDefaultValue = ( + property: ArrayProperty | AnyOfArray, + definitions: Definitions, +) => { + if ("items" in property && "$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 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 = + subProperty.type === "string" + ? "" + : subProperty.type === "number" + ? 0.0 + : subProperty.type === "boolean" + ? false + : subProperty.type === "integer" + ? 0 + : null; + + return { + fromUpstream: getFromUpstream(property), + upstreamValue: "", + upstreamId: "", + value, + }; + } +}; + +function emptyFromUpstreamObject( + object: ObjectDefinition, + property: ArrayObjectProperty | AnyOfArray, + 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; +} 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/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") { 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"; 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' 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/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 128fe4e8..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['_shared_storage_usage_in_bytes'] + self._shared_storage_usage_in_bytes = result.get('_shared_storage_usage_in_bytes', 0) return result