From 1145b53e1feeaa26a30f3b1e3069dd04daaef81e Mon Sep 17 00:00:00 2001 From: luiz Date: Fri, 19 May 2023 15:21:32 +0200 Subject: [PATCH 001/328] initial commit --- docker-compose-dev.yaml | 7 ++ domino/custom_operators/docker_operator.py | 4 +- .../components/domino-form-item.component.tsx | 80 +++++++++++++++++++ .../components/domino-form.component.tsx | 34 ++++++++ .../components/sidebar-form.component.tsx | 49 +++++++----- rest/core/settings.py | 2 +- 6 files changed, 152 insertions(+), 24 deletions(-) create mode 100644 frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item.component.tsx create mode 100644 frontend/src/pages/private/workflows/workflows-editor/components/domino-form.component.tsx diff --git a/docker-compose-dev.yaml b/docker-compose-dev.yaml index 8864b2f1..dbe0c2d5 100644 --- a/docker-compose-dev.yaml +++ b/docker-compose-dev.yaml @@ -42,6 +42,7 @@ services: - /var/run/docker.sock:/var/run/docker.sock postgres: image: postgres:13 + container_name: airflow-postgres environment: POSTGRES_USER: airflow POSTGRES_PASSWORD: airflow @@ -57,6 +58,7 @@ services: redis: image: redis:latest + container_name: airflow-redis expose: - 6379 healthcheck: @@ -92,6 +94,7 @@ services: airflow-triggerer: <<: *airflow-common + container_name: airflow-triggerer command: triggerer healthcheck: test: @@ -111,6 +114,7 @@ services: airflow-init: <<: *airflow-common + container_name: airflow-init entrypoint: /bin/bash # yamllint disable rule:line-length command: @@ -189,6 +193,7 @@ services: airflow-cli: <<: *airflow-common + container_name: airflow-cli profiles: - debug environment: @@ -205,6 +210,7 @@ services: # See: https://docs.docker.com/compose/profiles/ flower: <<: *airflow-common + container_name: airflow-flower command: celery flower profiles: - flower @@ -308,6 +314,7 @@ services: - DOMINO_DB_HOST=domino_postgres - DOMINO_DB_PORT=5432 - DOMINO_DB_NAME=postgres + - DOMINO_DEFAULT_PIECES_REPOSITORY_VERSION=0.2.0 - DOMINO_DEFAULT_PIECES_REPOSITORY_TOKEN=${DOMINO_DEFAULT_PIECES_REPOSITORY_TOKEN} - DOMINO_GITHUB_ACCESS_TOKEN_WORKFLOWS=${DOMINO_GITHUB_ACCESS_TOKEN_WORKFLOWS} - DOMINO_GITHUB_WORKFLOWS_REPOSITORY=${DOMINO_GITHUB_WORKFLOWS_REPOSITORY} diff --git a/domino/custom_operators/docker_operator.py b/domino/custom_operators/docker_operator.py index 0bd0b4a3..30711eef 100644 --- a/domino/custom_operators/docker_operator.py +++ b/domino/custom_operators/docker_operator.py @@ -40,8 +40,8 @@ def __init__( # # TODO remove mounts=[ # TODO remove - # Mount(source='/media/luiz/storage2/Github/domino/domino', target='/home/domino/domino_py/domino', type='bind', read_only=True), - # Mount(source='/media/luiz/storage2/Github/default_domino_pieces', target='/home/domino/pieces_repository/', type='bind', read_only=True), + Mount(source='/media/luiz/storage2/Github/domino/domino', target='/home/domino/domino_py/domino', type='bind', read_only=True), + Mount(source='/media/luiz/storage2/Github/default_domino_pieces', target='/home/domino/pieces_repository/', type='bind', read_only=True), ] if self.workflow_shared_storage and str(self.workflow_shared_storage.source.value).lower() == str(getattr(StorageSource, 'local').value).lower(): mounts.append( diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item.component.tsx b/frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item.component.tsx new file mode 100644 index 00000000..f59f80be --- /dev/null +++ b/frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item.component.tsx @@ -0,0 +1,80 @@ +import React, { useState } from 'react'; +import { TextField, Select, MenuItem, Checkbox, FormControlLabel, Box } from '@mui/material'; + + +interface DominoFormItemProps { + schema: any; + key: string; + value: any; + onChange: (val: any) => void; +} + +const DominoFormItem: React.FC = ({ schema, key, value, onChange }) => { + const [checked, setChecked] = useState(false); + + const handleInputChange = (event: React.ChangeEvent) => { + onChange(event.target.value); + }; + + const handleSelectChange = (event: React.ChangeEvent<{ name?: string; value: unknown }>) => { + onChange(event.target.value as string); + }; + + const handleCheckboxChange = (event: React.ChangeEvent) => { + setChecked(event.target.checked); + }; + + let inputElement: JSX.Element; + + if (checked) { + const options = ['Option 1', 'Option 2', 'Option 3']; + inputElement = ( + + ); + } else if (schema.enum) { + inputElement = ( + + ); + } else if (schema.type === 'boolean') { + inputElement = } label="" />; + } else if (schema.type === 'number') { + inputElement = ; + } else { + inputElement = ; + } + + return ( + + {inputElement} + + + ); +}; + +export default DominoFormItem; diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/domino-form.component.tsx b/frontend/src/pages/private/workflows/workflows-editor/components/domino-form.component.tsx new file mode 100644 index 00000000..2e911935 --- /dev/null +++ b/frontend/src/pages/private/workflows/workflows-editor/components/domino-form.component.tsx @@ -0,0 +1,34 @@ +import React, { useState } from 'react'; +import DominoFormItem from './domino-form-item.component'; + +interface DominoFormProps { + schema: any; + initialData: any; +} + +const DominoForm: React.FC = ({ schema, initialData }) => { + const [formData, setFormData] = useState(initialData); + + const handleChange = (key: string) => (value: any) => { + console.log('handleChange', key, value); + // setFormData(prevData => ({ ...prevData, [key]: value })); + }; + + return ( +
+ {Object.keys(schema.properties).map(key => ( +
+ {/* */} + +
+ ))} +
+ ); +}; + +export default DominoForm; diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component.tsx b/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component.tsx index 8faeb7d0..e1906a52 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component.tsx +++ b/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component.tsx @@ -10,6 +10,9 @@ import { operatorStorageSchema } from 'common/schemas/storageSchemas' import { containerResourcesSchema } from 'common/schemas/containerResourcesSchemas' import { toast } from 'react-toastify' +import DominoForm from './domino-form.component' + + const handleDefaultsAjv = createAjv({ useDefaults: true }) interface ISidebarFormProps { @@ -142,18 +145,18 @@ const SidebarForm = (props: ISidebarFormProps) => { } else { handleOnChange({ data: forageData }) // If the form has checkboxes, we need to update the storage data - if (isPieceForm && !forageData.storage){ + if (isPieceForm && !forageData.storage) { const defaultStorageData = extractDefaultValues(operatorStorageSchema) handleOnChangeStorage({ data: defaultStorageData }) - }else if (isPieceForm){ + } else if (isPieceForm) { handleOnChangeStorage({ data: forageData.storage }) } - if (isPieceForm && !forageData.containerResources){ + if (isPieceForm && !forageData.containerResources) { const defaultContainerResourcesData = extractDefaultValues(containerResourcesSchema) - handleOnChangeContainerResources({data: defaultContainerResourcesData}) - } else if (isPieceForm){ - handleOnChangeContainerResources({data: forageData.containerResources}) + handleOnChangeContainerResources({ data: defaultContainerResourcesData }) + } else if (isPieceForm) { + handleOnChangeContainerResources({ data: forageData.containerResources }) } setFormData(forageData) } @@ -273,19 +276,19 @@ const SidebarForm = (props: ISidebarFormProps) => { setFormData(auxFormData) }, - [ - formJsonSchema, - formId, - fetchForageWorkflowEdges, - fetchForagePieceById, - setForageUpstreamMap, - getForageUpstreamMap, - formData, - getForageCheckboxStates, - setForageCheckboxStates, - setNameKeyUpstreamArgsMap, - getNameKeyUpstreamArgsMap - ]) + [ + formJsonSchema, + formId, + fetchForageWorkflowEdges, + fetchForagePieceById, + setForageUpstreamMap, + getForageUpstreamMap, + formData, + getForageCheckboxStates, + setForageCheckboxStates, + setNameKeyUpstreamArgsMap, + getNameKeyUpstreamArgsMap + ]) useEffect(() => { // This is a hack because customizing jsonforms ui for accepting multi column would be harder than create a custom checkbox column @@ -337,7 +340,11 @@ const SidebarForm = (props: ISidebarFormProps) => { } - + {/* { onChange={handleOnChange} ajv={handleDefaultsAjv} cells={materialCells} - /> + /> */} { isPieceForm ? diff --git a/rest/core/settings.py b/rest/core/settings.py index d0fae3a6..81ae14d1 100644 --- a/rest/core/settings.py +++ b/rest/core/settings.py @@ -48,7 +48,7 @@ class Settings(BaseSettings): # Default domino pieces repository DOMINO_DEFAULT_PIECES_REPOSITORY = os.environ.get('DOMINO_DEFAULT_PIECES_REPOSITORY', "Tauffer-Consulting/default_domino_pieces") - DOMINO_DEFAULT_PIECES_REPOSITORY_VERSION = os.environ.get('DOMINO_DEFAULT_PIECES_REPOSITORY_VERSION', "0.0.9") + DOMINO_DEFAULT_PIECES_REPOSITORY_VERSION = os.environ.get('DOMINO_DEFAULT_PIECES_REPOSITORY_VERSION', "0.2.0") DOMINO_DEFAULT_PIECES_REPOSITORY_SOURCE = os.environ.get('DOMINO_DEFAULT_PIECES_REPOSITORY_SOURCE', "github") DOMINO_DEFAULT_PIECES_REPOSITORY_TOKEN: EmptyStrToNone = os.environ.get('DOMINO_DEFAULT_PIECES_REPOSITORY_TOKEN', "") From c920b288c651f91a07540446b35f9c0fe264b195 Mon Sep 17 00:00:00 2001 From: luiz Date: Fri, 19 May 2023 16:34:41 +0200 Subject: [PATCH 002/328] m --- docker-compose-dev.yaml | 2 +- frontend/src/index.css | 2 +- .../components/domino-form-item.component.tsx | 50 ++++++++++++++++--- .../components/domino-form.component.tsx | 3 +- .../components/sidebar-form.component.tsx | 2 - rest/core/settings.py | 2 +- 6 files changed, 47 insertions(+), 14 deletions(-) diff --git a/docker-compose-dev.yaml b/docker-compose-dev.yaml index dbe0c2d5..570b8e5c 100644 --- a/docker-compose-dev.yaml +++ b/docker-compose-dev.yaml @@ -314,7 +314,7 @@ services: - DOMINO_DB_HOST=domino_postgres - DOMINO_DB_PORT=5432 - DOMINO_DB_NAME=postgres - - DOMINO_DEFAULT_PIECES_REPOSITORY_VERSION=0.2.0 + - DOMINO_DEFAULT_PIECES_REPOSITORY_VERSION=0.2.1 - DOMINO_DEFAULT_PIECES_REPOSITORY_TOKEN=${DOMINO_DEFAULT_PIECES_REPOSITORY_TOKEN} - DOMINO_GITHUB_ACCESS_TOKEN_WORKFLOWS=${DOMINO_GITHUB_ACCESS_TOKEN_WORKFLOWS} - DOMINO_GITHUB_WORKFLOWS_REPOSITORY=${DOMINO_GITHUB_WORKFLOWS_REPOSITORY} diff --git a/frontend/src/index.css b/frontend/src/index.css index 0a799926..fbd65cf6 100644 --- a/frontend/src/index.css +++ b/frontend/src/index.css @@ -12,7 +12,7 @@ body, } .sidebar-jsonforms-grid * { - border: none !important; + /* border: none !important; */ box-shadow: none !important; } diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item.component.tsx b/frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item.component.tsx index f59f80be..37f846b8 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item.component.tsx +++ b/frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item.component.tsx @@ -1,5 +1,13 @@ import React, { useState } from 'react'; -import { TextField, Select, MenuItem, Checkbox, FormControlLabel, Box } from '@mui/material'; +import { + TextField, + Select, + MenuItem, + Checkbox, + FormControlLabel, + Box, + FormControl +} from '@mui/material'; interface DominoFormItemProps { @@ -26,6 +34,8 @@ const DominoFormItem: React.FC = ({ schema, key, value, onC let inputElement: JSX.Element; + // console.log('schema', schema); + if (checked) { const options = ['Option 1', 'Option 2', 'Option 3']; inputElement = ( @@ -55,18 +65,42 @@ const DominoFormItem: React.FC = ({ schema, key, value, onC ); } else if (schema.type === 'boolean') { - inputElement = } label="" />; + inputElement = } + label={schema.title} + />; } else if (schema.type === 'number') { - inputElement = ; - } else { inputElement = ; + } else if (schema.type === 'integer') { + inputElement = ; + } else { + inputElement = ( + + ); } return ( diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/domino-form.component.tsx b/frontend/src/pages/private/workflows/workflows-editor/components/domino-form.component.tsx index 2e911935..1ceb68d9 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/components/domino-form.component.tsx +++ b/frontend/src/pages/private/workflows/workflows-editor/components/domino-form.component.tsx @@ -14,11 +14,12 @@ const DominoForm: React.FC = ({ schema, initialData }) => { // setFormData(prevData => ({ ...prevData, [key]: value })); }; + // console.log('schema', schema); + return (
{Object.keys(schema.properties).map(key => (
- {/* */} { const { formSchema, diff --git a/rest/core/settings.py b/rest/core/settings.py index 81ae14d1..36e0d703 100644 --- a/rest/core/settings.py +++ b/rest/core/settings.py @@ -48,7 +48,7 @@ class Settings(BaseSettings): # Default domino pieces repository DOMINO_DEFAULT_PIECES_REPOSITORY = os.environ.get('DOMINO_DEFAULT_PIECES_REPOSITORY', "Tauffer-Consulting/default_domino_pieces") - DOMINO_DEFAULT_PIECES_REPOSITORY_VERSION = os.environ.get('DOMINO_DEFAULT_PIECES_REPOSITORY_VERSION', "0.2.0") + DOMINO_DEFAULT_PIECES_REPOSITORY_VERSION = os.environ.get('DOMINO_DEFAULT_PIECES_REPOSITORY_VERSION', "0.2.1") DOMINO_DEFAULT_PIECES_REPOSITORY_SOURCE = os.environ.get('DOMINO_DEFAULT_PIECES_REPOSITORY_SOURCE', "github") DOMINO_DEFAULT_PIECES_REPOSITORY_TOKEN: EmptyStrToNone = os.environ.get('DOMINO_DEFAULT_PIECES_REPOSITORY_TOKEN', "") From 44a791ff074d5569e0daf4eaebeae04967b03d84 Mon Sep 17 00:00:00 2001 From: luiz Date: Fri, 19 May 2023 17:13:02 +0200 Subject: [PATCH 003/328] m --- .../components/domino-form-item.component.tsx | 27 +++++++++++-------- .../components/domino-form.component.tsx | 4 +-- .../components/sidebar-form.component.tsx | 10 +++---- 3 files changed, 23 insertions(+), 18 deletions(-) diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item.component.tsx b/frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item.component.tsx index 37f846b8..19c27769 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item.component.tsx +++ b/frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item.component.tsx @@ -12,14 +12,16 @@ import { interface DominoFormItemProps { schema: any; - key: string; + itemKey: any; value: any; onChange: (val: any) => void; } -const DominoFormItem: React.FC = ({ schema, key, value, onChange }) => { +const DominoFormItem: React.FC = ({ schema, itemKey, value, onChange }) => { const [checked, setChecked] = useState(false); + let itemSchema: any = schema.properties[itemKey]; + const handleInputChange = (event: React.ChangeEvent) => { onChange(event.target.value); }; @@ -51,42 +53,45 @@ const DominoFormItem: React.FC = ({ schema, key, value, onC ))} ); - } else if (schema.enum) { + } else if (itemSchema?.allOf && itemSchema.allOf.length > 0) { + const typeClass = itemSchema.allOf[0]['$ref'].split("/").pop(); + const valuesOptions: Array = schema?.definitions?.[typeClass].enum; inputElement = ( ); - } else if (schema.type === 'boolean') { + } else if (itemSchema.type === 'boolean') { inputElement = } - label={schema.title} + label={itemSchema.title} />; - } else if (schema.type === 'number') { + } else if (itemSchema.type === 'number') { inputElement = ; - } else if (schema.type === 'integer') { + } else if (itemSchema.type === 'integer') { inputElement = ; @@ -96,7 +101,7 @@ const DominoFormItem: React.FC = ({ schema, key, value, onC fullWidth multiline variant="outlined" - label={schema.title} + label={itemSchema.title} // value={value} onChange={handleInputChange} /> diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/domino-form.component.tsx b/frontend/src/pages/private/workflows/workflows-editor/components/domino-form.component.tsx index 1ceb68d9..f21ea11f 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/components/domino-form.component.tsx +++ b/frontend/src/pages/private/workflows/workflows-editor/components/domino-form.component.tsx @@ -21,8 +21,8 @@ const DominoForm: React.FC = ({ schema, initialData }) => { {Object.keys(schema.properties).map(key => (
diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component.tsx b/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component.tsx index 8a184c35..d65bd667 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component.tsx +++ b/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component.tsx @@ -63,7 +63,7 @@ const SidebarForm = (props: ISidebarFormProps) => { }, [formSchema]) useEffect(() => { - setFormWidthSpace(isPieceForm ? 9 : 12) + setFormWidthSpace(isPieceForm ? 12 : 12) }, [isPieceForm]) @@ -327,10 +327,10 @@ const SidebarForm = (props: ISidebarFormProps) => { { isPieceForm ? - + Input Argument - + Upstream @@ -352,14 +352,14 @@ const SidebarForm = (props: ISidebarFormProps) => { cells={materialCells} /> */} - { + {/* { isPieceForm ? {checkboxes} : null - } + } */} { isPieceForm ? From 9f6949cf0ff1f8586e22150a1d4af9fbfa8acb05 Mon Sep 17 00:00:00 2001 From: luiz Date: Fri, 19 May 2023 17:29:30 +0200 Subject: [PATCH 004/328] better layout --- docker-compose-dev.yaml | 2 +- .../components/domino-form-item.component.tsx | 37 ++++++++++++------- rest/core/settings.py | 2 +- 3 files changed, 25 insertions(+), 16 deletions(-) diff --git a/docker-compose-dev.yaml b/docker-compose-dev.yaml index 570b8e5c..b6663c9b 100644 --- a/docker-compose-dev.yaml +++ b/docker-compose-dev.yaml @@ -314,7 +314,7 @@ services: - DOMINO_DB_HOST=domino_postgres - DOMINO_DB_PORT=5432 - DOMINO_DB_NAME=postgres - - DOMINO_DEFAULT_PIECES_REPOSITORY_VERSION=0.2.1 + - DOMINO_DEFAULT_PIECES_REPOSITORY_VERSION=0.2.2 - DOMINO_DEFAULT_PIECES_REPOSITORY_TOKEN=${DOMINO_DEFAULT_PIECES_REPOSITORY_TOKEN} - DOMINO_GITHUB_ACCESS_TOKEN_WORKFLOWS=${DOMINO_GITHUB_ACCESS_TOKEN_WORKFLOWS} - DOMINO_GITHUB_WORKFLOWS_REPOSITORY=${DOMINO_GITHUB_WORKFLOWS_REPOSITORY} diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item.component.tsx b/frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item.component.tsx index 19c27769..5b8a7ee9 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item.component.tsx +++ b/frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item.component.tsx @@ -6,7 +6,8 @@ import { Checkbox, FormControlLabel, Box, - FormControl + FormControl, + InputLabel } from '@mui/material'; @@ -57,17 +58,19 @@ const DominoFormItem: React.FC = ({ schema, itemKey, value, const typeClass = itemSchema.allOf[0]['$ref'].split("/").pop(); const valuesOptions: Array = schema?.definitions?.[typeClass].enum; inputElement = ( - + + {itemKey} + + ); } else if (itemSchema.type === 'boolean') { inputElement = = ({ schema, itemKey, value, checked={value} onChange={handleInputChange} />} + labelPlacement="start" label={itemSchema.title} />; } else if (itemSchema.type === 'number') { @@ -102,14 +106,19 @@ const DominoFormItem: React.FC = ({ schema, itemKey, value, multiline variant="outlined" label={itemSchema.title} - // value={value} + value={value} onChange={handleInputChange} /> ); } return ( - + {inputElement} diff --git a/rest/core/settings.py b/rest/core/settings.py index 36e0d703..7f3c6ccb 100644 --- a/rest/core/settings.py +++ b/rest/core/settings.py @@ -48,7 +48,7 @@ class Settings(BaseSettings): # Default domino pieces repository DOMINO_DEFAULT_PIECES_REPOSITORY = os.environ.get('DOMINO_DEFAULT_PIECES_REPOSITORY', "Tauffer-Consulting/default_domino_pieces") - DOMINO_DEFAULT_PIECES_REPOSITORY_VERSION = os.environ.get('DOMINO_DEFAULT_PIECES_REPOSITORY_VERSION', "0.2.1") + DOMINO_DEFAULT_PIECES_REPOSITORY_VERSION = os.environ.get('DOMINO_DEFAULT_PIECES_REPOSITORY_VERSION', "0.2.2") DOMINO_DEFAULT_PIECES_REPOSITORY_SOURCE = os.environ.get('DOMINO_DEFAULT_PIECES_REPOSITORY_SOURCE', "github") DOMINO_DEFAULT_PIECES_REPOSITORY_TOKEN: EmptyStrToNone = os.environ.get('DOMINO_DEFAULT_PIECES_REPOSITORY_TOKEN', "") From 227e2e670b5c2bad9f6312c1e17d3721006dd4f6 Mon Sep 17 00:00:00 2001 From: luiz Date: Sat, 20 May 2023 19:10:35 +0200 Subject: [PATCH 005/328] array type --- .../domino-form-item-array.component.tsx | 109 ++++++++++++++++++ .../components/domino-form-item.component.tsx | 48 +++++--- .../components/domino-form.component.tsx | 19 +-- .../components/sidebar-form.component.tsx | 3 + 4 files changed, 158 insertions(+), 21 deletions(-) create mode 100644 frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item-array.component.tsx diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item-array.component.tsx b/frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item-array.component.tsx new file mode 100644 index 00000000..a83802e2 --- /dev/null +++ b/frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item-array.component.tsx @@ -0,0 +1,109 @@ +import React, { useState } from 'react'; +import { + Card, + CardHeader, + CardContent, + IconButton, + Box, + Checkbox, + Input, + Select, + MenuItem, + SelectChangeEvent +} from '@mui/material'; +import TextField from '@mui/material/TextField'; +import DeleteIcon from '@mui/icons-material/Delete'; +import AddIcon from '@mui/icons-material/Add'; + +interface ArrayInputCardProps { + title: string; +} + +const ArrayInputCard: React.FC = ({ title }) => { + const [arrayItems, setArrayItems] = useState(['']); + const [checkedFromUpstream, setCheckedFromUpstream] = useState(false) + + const handleArrayItemChange = (index: number, value: string) => { + const updatedItems = [...arrayItems]; + updatedItems[index] = value; + setArrayItems(updatedItems); + }; + + const handleAddItem = () => { + setArrayItems([...arrayItems, '']); + }; + + const handleDeleteItem = (index: number) => { + const updatedItems = [...arrayItems]; + updatedItems.splice(index, 1); + setArrayItems(updatedItems); + }; + + // FomrUpstream logic + const handleCheckboxFromUpstreamChange = (event: React.ChangeEvent) => { + setCheckedFromUpstream(event.target.checked); + }; + const handleSelectFromUpstreamChange = (event: SelectChangeEvent) => { + console.log(event.target.value); + }; + + // create element + const createInputElement = (item: string, index: number) => { + let inputElement: JSX.Element; + if (checkedFromUpstream) { + const options = ['upstream 1', 'upstream 2', 'upstream 3', 'upstream 4']; + inputElement = ( + + ); + } else { + inputElement = handleArrayItemChange(index, e.target.value)} + /> + } + return inputElement; + } + + return ( + + + + + } + /> + + {arrayItems.map((item, index) => ( + + {createInputElement(item, index)} + + handleDeleteItem(index)} aria-label="Delete"> + + + + ))} + + + ); +}; + +export default ArrayInputCard; diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item.component.tsx b/frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item.component.tsx index 5b8a7ee9..23c8665e 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item.component.tsx +++ b/frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item.component.tsx @@ -7,8 +7,14 @@ import { FormControlLabel, Box, FormControl, - InputLabel + InputLabel, + SelectChangeEvent, + Card, CardContent, CardHeader, IconButton } from '@mui/material'; +import Delete from '@mui/icons-material'; +import AddIcon from '@mui/icons-material/Add'; + +import ArrayInputCard from './domino-form-item-array.component'; interface DominoFormItemProps { @@ -19,33 +25,45 @@ interface DominoFormItemProps { } const DominoFormItem: React.FC = ({ schema, itemKey, value, onChange }) => { - const [checked, setChecked] = useState(false); + const [checkedFromUpstream, setCheckedFromUpstream] = useState(false); + + // console.log(itemKey); + // console.log(value) let itemSchema: any = schema.properties[itemKey]; + // if value is undefined, read the defautl value from the schema + if (value === undefined) { + value = itemSchema.default; + } + + // Handle input change const handleInputChange = (event: React.ChangeEvent) => { onChange(event.target.value); }; - const handleSelectChange = (event: React.ChangeEvent<{ name?: string; value: unknown }>) => { + const handleSelectChange = (event: SelectChangeEvent) => { onChange(event.target.value as string); }; - const handleCheckboxChange = (event: React.ChangeEvent) => { - setChecked(event.target.checked); + // FomrUpstream logic + const handleCheckboxFromUpstreamChange = (event: React.ChangeEvent) => { + setCheckedFromUpstream(event.target.checked); }; - let inputElement: JSX.Element; + const handleSelectFromUpstreamChange = (event: SelectChangeEvent) => { + console.log(event.target.value); + }; - // console.log('schema', schema); + let inputElement: JSX.Element; - if (checked) { - const options = ['Option 1', 'Option 2', 'Option 3']; + if (checkedFromUpstream) { + const options = ['upstream 1', 'upstream 2', 'upstream 3', 'upstream 4']; inputElement = ( {valuesOptions.map((option: string) => ( @@ -99,6 +117,8 @@ const DominoFormItem: React.FC = ({ schema, itemKey, value, value={value} onChange={handleInputChange} />; + } else if (itemSchema.type === 'array') { + inputElement = } else { inputElement = ( = ({ schema, itemKey, value, {inputElement} - + ); }; diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/domino-form.component.tsx b/frontend/src/pages/private/workflows/workflows-editor/components/domino-form.component.tsx index f21ea11f..764136a6 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/components/domino-form.component.tsx +++ b/frontend/src/pages/private/workflows/workflows-editor/components/domino-form.component.tsx @@ -1,20 +1,25 @@ -import React, { useState } from 'react'; +import React, { useState, useCallback, useEffect } from 'react'; import DominoFormItem from './domino-form-item.component'; + +type initialDataType = Record; + interface DominoFormProps { schema: any; - initialData: any; + initialData: initialDataType; + onChange: ({ errors, data }: { errors?: any, data: any }) => void; } -const DominoForm: React.FC = ({ schema, initialData }) => { +const DominoForm: React.FC = ({ schema, initialData, onChange }) => { const [formData, setFormData] = useState(initialData); const handleChange = (key: string) => (value: any) => { - console.log('handleChange', key, value); - // setFormData(prevData => ({ ...prevData, [key]: value })); + setFormData(prevData => ({ ...prevData, [key]: value })); }; - // console.log('schema', schema); + const submitFormToParent = useEffect(() => { + onChange({ data: formData }); + }, [formData]); return ( @@ -32,4 +37,4 @@ const DominoForm: React.FC = ({ schema, initialData }) => { ); }; -export default DominoForm; +export default React.memo(DominoForm); diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component.tsx b/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component.tsx index 4dd613fa..450101ca 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component.tsx +++ b/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component.tsx @@ -68,6 +68,8 @@ const SidebarForm = (props: ISidebarFormProps) => { const handleOnChange = useCallback(async ({ errors, data }: { errors?: any, data: any }) => { + console.log('formid', formId) + console.log('data', data) // On change update form data in forage try { var upstreamMap = await getForageUpstreamMap() @@ -340,6 +342,7 @@ const SidebarForm = (props: ISidebarFormProps) => { {/* Date: Sun, 21 May 2023 11:33:38 +0200 Subject: [PATCH 006/328] improve arrays and custompythonpiece --- docker-compose-dev.yaml | 2 +- frontend/package.json | 1 + .../domino-form-item-array.component.tsx | 51 ++-- .../components/domino-form-item.component.tsx | 54 +++- frontend/yarn.lock | 262 +++++++++++++++++- 5 files changed, 330 insertions(+), 40 deletions(-) diff --git a/docker-compose-dev.yaml b/docker-compose-dev.yaml index b6663c9b..e49bdf96 100644 --- a/docker-compose-dev.yaml +++ b/docker-compose-dev.yaml @@ -314,7 +314,7 @@ services: - DOMINO_DB_HOST=domino_postgres - DOMINO_DB_PORT=5432 - DOMINO_DB_NAME=postgres - - DOMINO_DEFAULT_PIECES_REPOSITORY_VERSION=0.2.2 + - DOMINO_DEFAULT_PIECES_REPOSITORY_VERSION=0.3.0 - DOMINO_DEFAULT_PIECES_REPOSITORY_TOKEN=${DOMINO_DEFAULT_PIECES_REPOSITORY_TOKEN} - DOMINO_GITHUB_ACCESS_TOKEN_WORKFLOWS=${DOMINO_GITHUB_ACCESS_TOKEN_WORKFLOWS} - DOMINO_GITHUB_WORKFLOWS_REPOSITORY=${DOMINO_GITHUB_WORKFLOWS_REPOSITORY} diff --git a/frontend/package.json b/frontend/package.json index 4f5615e5..c5b5bda4 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -22,6 +22,7 @@ "@react-pdf/renderer": "^3.1.9", "@types/react-dom": "^18.0.9", "@types/uuid": "^9.0.0", + "@uiw/react-textarea-code-editor": "^2.1.1", "ag-grid-community": "^28.2.1", "ag-grid-react": "^28.2.1", "axios": "^1.2.1", diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item-array.component.tsx b/frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item-array.component.tsx index a83802e2..abfc4b4e 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item-array.component.tsx +++ b/frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item-array.component.tsx @@ -9,7 +9,9 @@ import { Input, Select, MenuItem, - SelectChangeEvent + SelectChangeEvent, + FormControl, + InputLabel, } from '@mui/material'; import TextField from '@mui/material/TextField'; import DeleteIcon from '@mui/icons-material/Delete'; @@ -53,22 +55,25 @@ const ArrayInputCard: React.FC = ({ title }) => { if (checkedFromUpstream) { const options = ['upstream 1', 'upstream 2', 'upstream 3', 'upstream 4']; inputElement = ( - + + {title} + + ); } else { inputElement = handleArrayItemChange(index, e.target.value)} /> @@ -77,15 +82,13 @@ const ArrayInputCard: React.FC = ({ title }) => { } return ( - - - - - } - /> + +
+ + + + {title} +
{arrayItems.map((item, index) => ( = ({ title }) => { alignItems="center" sx={{ mb: 1 }} > - {createInputElement(item, index)} - handleDeleteItem(index)} aria-label="Delete"> + {createInputElement(item, index)} + ))} diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item.component.tsx b/frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item.component.tsx index 23c8665e..6088e138 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item.component.tsx +++ b/frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item.component.tsx @@ -11,6 +11,7 @@ import { SelectChangeEvent, Card, CardContent, CardHeader, IconButton } from '@mui/material'; +import CodeEditor from '@uiw/react-textarea-code-editor'; import Delete from '@mui/icons-material'; import AddIcon from '@mui/icons-material/Add'; @@ -26,6 +27,9 @@ interface DominoFormItemProps { const DominoFormItem: React.FC = ({ schema, itemKey, value, onChange }) => { const [checkedFromUpstream, setCheckedFromUpstream] = useState(false); + const [codeValue, setCodeValue] = useState( + "def custom_function(input_args: list):\n print(input_args)\n return 'Hello world!'" + ); // console.log(itemKey); // console.log(value) @@ -60,17 +64,20 @@ const DominoFormItem: React.FC = ({ schema, itemKey, value, if (checkedFromUpstream) { const options = ['upstream 1', 'upstream 2', 'upstream 3', 'upstream 4']; inputElement = ( - + + {itemKey} + + ); } else if (itemSchema?.allOf && itemSchema.allOf.length > 0) { const typeClass = itemSchema.allOf[0]['$ref'].split("/").pop(); @@ -118,7 +125,30 @@ const DominoFormItem: React.FC = ({ schema, itemKey, value, onChange={handleInputChange} />; } else if (itemSchema.type === 'array') { - inputElement = + inputElement = + } else if (itemSchema.type === 'string' && itemSchema.format === 'date-time') { + inputElement = + } else if (itemSchema.type === 'string' && itemSchema?.widget === 'codeeditor') { + inputElement = ( + setCodeValue(evn.target.value)} + padding={15} + style={{ + fontSize: 12, + backgroundColor: "#f5f5f5", + fontFamily: 'ui-monospace,SFMono-Regular,SF Mono,Consolas,Liberation Mono,Menlo,monospace', + borderRadius: 4, + border: "1px solid #ddd", + width: "100%", + minHeight: "200px", + maxHeight: "400px", + overflowY: "scroll", + }} + /> + ) } else { inputElement = ( Date: Sun, 21 May 2023 12:20:11 +0200 Subject: [PATCH 007/328] datetime components --- docker-compose-dev.yaml | 2 +- frontend/package.json | 3 +- .../components/domino-form-item.component.tsx | 35 ++++++- .../piece-docs-popover.component.tsx | 2 +- frontend/yarn.lock | 92 ++++++++----------- 5 files changed, 73 insertions(+), 61 deletions(-) diff --git a/docker-compose-dev.yaml b/docker-compose-dev.yaml index e49bdf96..fc31b70d 100644 --- a/docker-compose-dev.yaml +++ b/docker-compose-dev.yaml @@ -314,7 +314,7 @@ services: - DOMINO_DB_HOST=domino_postgres - DOMINO_DB_PORT=5432 - DOMINO_DB_NAME=postgres - - DOMINO_DEFAULT_PIECES_REPOSITORY_VERSION=0.3.0 + - DOMINO_DEFAULT_PIECES_REPOSITORY_VERSION=0.3.1 - DOMINO_DEFAULT_PIECES_REPOSITORY_TOKEN=${DOMINO_DEFAULT_PIECES_REPOSITORY_TOKEN} - DOMINO_GITHUB_ACCESS_TOKEN_WORKFLOWS=${DOMINO_GITHUB_ACCESS_TOKEN_WORKFLOWS} - DOMINO_GITHUB_WORKFLOWS_REPOSITORY=${DOMINO_GITHUB_WORKFLOWS_REPOSITORY} diff --git a/frontend/package.json b/frontend/package.json index c5b5bda4..cff6a499 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -18,7 +18,7 @@ "@mui/material": "^5.11.1", "@mui/system": "^5.11.1", "@mui/x-data-grid": "^5.17.16", - "@mui/x-date-pickers": "^5.0.11", + "@mui/x-date-pickers": "^6.5.0", "@react-pdf/renderer": "^3.1.9", "@types/react-dom": "^18.0.9", "@types/uuid": "^9.0.0", @@ -28,6 +28,7 @@ "axios": "^1.2.1", "axios-mock-adapter": "^1.21.2", "cross-env": "^7.0.3", + "dayjs": "^1.11.7", "localforage": "^1.10.0", "material-ui-dropzone": "^3.5.0", "prop-types": "^15.8.1", diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item.component.tsx b/frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item.component.tsx index 6088e138..407db893 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item.component.tsx +++ b/frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item.component.tsx @@ -9,11 +9,14 @@ import { FormControl, InputLabel, SelectChangeEvent, - Card, CardContent, CardHeader, IconButton } from '@mui/material'; +import { DemoContainer } from '@mui/x-date-pickers/internals/demo'; +import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; +import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; +import { DatePicker } from '@mui/x-date-pickers/DatePicker'; +import { TimePicker } from '@mui/x-date-pickers/TimePicker'; +import { DateTimePicker } from '@mui/x-date-pickers/DateTimePicker'; import CodeEditor from '@uiw/react-textarea-code-editor'; -import Delete from '@mui/icons-material'; -import AddIcon from '@mui/icons-material/Add'; import ArrayInputCard from './domino-form-item-array.component'; @@ -126,8 +129,30 @@ const DominoFormItem: React.FC = ({ schema, itemKey, value, />; } else if (itemSchema.type === 'array') { inputElement = - } else if (itemSchema.type === 'string' && itemSchema.format === 'date-time') { - inputElement = + } else if (itemSchema.type === 'string' && itemSchema?.widget === 'date') { + inputElement = ( + + + + + + ); + } else if (itemSchema.type === 'string' && itemSchema?.widget === 'time') { + inputElement = ( + + + + + + ); + } else if (itemSchema.type === 'string' && itemSchema?.widget === 'datetime') { + inputElement = ( + + + + + + ); } else if (itemSchema.type === 'string' && itemSchema?.widget === 'codeeditor') { inputElement = ( - {key} [{typeName}] - {argument.description}. + {key} [{typeName}] - {argument.description} {argument.allOf && argument.allOf.length > 0 && ( <> {' Options: '} diff --git a/frontend/yarn.lock b/frontend/yarn.lock index 734fcb58..03500ebd 100644 --- a/frontend/yarn.lock +++ b/frontend/yarn.lock @@ -1035,7 +1035,7 @@ dependencies: regenerator-runtime "^0.13.11" -"@babel/runtime@^7.18.6", "@babel/runtime@^7.20.13": +"@babel/runtime@^7.18.6", "@babel/runtime@^7.20.13", "@babel/runtime@^7.21.0": version "7.21.5" resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.21.5.tgz#8492dddda9644ae3bda3b45eabe87382caee7200" integrity sha512-8jI69toZqqcsnqGGqwGS4Qb1VwLOEp4hz+CXPywcvjs60u3B4Pom/U/7rm4W8tMOYEB+E9wgD0mW1l3r8qlI9Q== @@ -1197,18 +1197,6 @@ resolved "https://registry.yarnpkg.com/@date-io/core/-/core-1.3.13.tgz#90c71da493f20204b7a972929cc5c482d078b3fa" integrity sha512-AlEKV7TxjeK+jxWVKcCFrfYAk8spX9aCyiToFIiLPtfQbsjmRGLIhb5VZgptQcJdHtLXo7+m0DuurwFgUToQuA== -"@date-io/core@^2.15.0", "@date-io/core@^2.16.0": - version "2.16.0" - resolved "https://registry.yarnpkg.com/@date-io/core/-/core-2.16.0.tgz#7871bfc1d9bca9aa35ad444a239505589d0f22f6" - integrity sha512-DYmSzkr+jToahwWrsiRA2/pzMEtz9Bq1euJwoOuYwuwIYXnZFtHajY2E6a1VNVDc9jP8YUXK1BvnZH9mmT19Zg== - -"@date-io/date-fns@^2.15.0": - version "2.16.0" - resolved "https://registry.yarnpkg.com/@date-io/date-fns/-/date-fns-2.16.0.tgz#bd5e09b6ecb47ee55e593fc3a87e7b2caaa3da40" - integrity sha512-bfm5FJjucqlrnQcXDVU5RD+nlGmL3iWgkHTq3uAZWVIuBu6dDmGa3m8a6zo2VQQpu8ambq9H22UyUpn7590joA== - dependencies: - "@date-io/core" "^2.16.0" - "@date-io/dayjs@1.3.13": version "1.3.13" resolved "https://registry.yarnpkg.com/@date-io/dayjs/-/dayjs-1.3.13.tgz#3a9edf5a7227b31b0f00a4f640f8715626833a61" @@ -1216,27 +1204,6 @@ dependencies: "@date-io/core" "^1.3.13" -"@date-io/dayjs@^2.15.0": - version "2.16.0" - resolved "https://registry.yarnpkg.com/@date-io/dayjs/-/dayjs-2.16.0.tgz#0d2c254ad8db1306fdc4b8eda197cb53c9af89dc" - integrity sha512-y5qKyX2j/HG3zMvIxTobYZRGnd1FUW2olZLS0vTj7bEkBQkjd2RO7/FEwDY03Z1geVGlXKnzIATEVBVaGzV4Iw== - dependencies: - "@date-io/core" "^2.16.0" - -"@date-io/luxon@^2.15.0": - version "2.16.1" - resolved "https://registry.yarnpkg.com/@date-io/luxon/-/luxon-2.16.1.tgz#b08786614cb58831c729a15807753011e4acb966" - integrity sha512-aeYp5K9PSHV28946pC+9UKUi/xMMYoaGelrpDibZSgHu2VWHXrr7zWLEr+pMPThSs5vt8Ei365PO+84pCm37WQ== - dependencies: - "@date-io/core" "^2.16.0" - -"@date-io/moment@^2.15.0": - version "2.16.1" - resolved "https://registry.yarnpkg.com/@date-io/moment/-/moment-2.16.1.tgz#ec6e0daa486871e0e6412036c6f806842a0eeed4" - integrity sha512-JkxldQxUqZBfZtsaCcCMkm/dmytdyq5pS1RxshCQ4fHhsvP5A7gSqPD22QbVXMcJydi3d3v1Y8BQdUKEuGACZQ== - dependencies: - "@date-io/core" "^2.16.0" - "@emotion/babel-plugin@^11.10.5": version "11.10.5" resolved "https://registry.yarnpkg.com/@emotion/babel-plugin/-/babel-plugin-11.10.5.tgz#65fa6e1790ddc9e23cc22658a4c5dea423c55c3c" @@ -1866,6 +1833,17 @@ prop-types "^15.8.1" react-is "^18.2.0" +"@mui/utils@^5.12.3": + version "5.13.1" + resolved "https://registry.yarnpkg.com/@mui/utils/-/utils-5.13.1.tgz#86199e46014215f95da046a5ec803f4a39c96eee" + integrity sha512-6lXdWwmlUbEU2jUI8blw38Kt+3ly7xkmV9ljzY4Q20WhsJMWiNry9CX8M+TaP/HbtuyR8XKsdMgQW7h7MM3n3A== + dependencies: + "@babel/runtime" "^7.21.0" + "@types/prop-types" "^15.7.5" + "@types/react-is" "^18.2.0" + prop-types "^15.8.1" + react-is "^18.2.0" + "@mui/x-data-grid@^5.17.16": version "5.17.16" resolved "https://registry.yarnpkg.com/@mui/x-data-grid/-/x-data-grid-5.17.16.tgz#4e05a014467bbee68385b5bee1e75004ba0178a3" @@ -1877,23 +1855,17 @@ prop-types "^15.8.1" reselect "^4.1.6" -"@mui/x-date-pickers@^5.0.11": - version "5.0.11" - resolved "https://registry.yarnpkg.com/@mui/x-date-pickers/-/x-date-pickers-5.0.11.tgz#f8b79222971b01bc94a6af30e97f30be7153efb0" - integrity sha512-YxUpyepbtzo6mu42KaaoJrfBHvlLobEdkP5EcEQ+OSaY5xxCEHqfSgi1NioXcxzZUi6ome5jcrjAopUHzFGk0g== +"@mui/x-date-pickers@^6.5.0": + version "6.5.0" + resolved "https://registry.yarnpkg.com/@mui/x-date-pickers/-/x-date-pickers-6.5.0.tgz#b71dbf9d8961fb34d9d829a4c6f9159ebb4e9206" + integrity sha512-dRCO1mzHjfOqsa4LdKxiXQnV0cuGiAkliyxSDCdRn6clK2WdF9Oj+1+4Mkx7fcJA61SV1eP4Yg29s0/VDsZKZw== dependencies: - "@babel/runtime" "^7.18.9" - "@date-io/core" "^2.15.0" - "@date-io/date-fns" "^2.15.0" - "@date-io/dayjs" "^2.15.0" - "@date-io/luxon" "^2.15.0" - "@date-io/moment" "^2.15.0" - "@mui/utils" "^5.10.3" - "@types/react-transition-group" "^4.4.5" + "@babel/runtime" "^7.21.0" + "@mui/utils" "^5.12.3" + "@types/react-transition-group" "^4.4.6" clsx "^1.2.1" - prop-types "^15.7.2" + prop-types "^15.8.1" react-transition-group "^4.4.5" - rifm "^0.12.1" "@nicolo-ribaudo/eslint-scope-5-internals@5.1.1-v1": version "5.1.1-v1" @@ -2801,6 +2773,13 @@ dependencies: "@types/react" "*" +"@types/react-is@^18.2.0": + version "18.2.0" + resolved "https://registry.yarnpkg.com/@types/react-is/-/react-is-18.2.0.tgz#2f5137853a46017b3d56447940fb3eb92bbf24a5" + integrity sha512-1vz2yObaQkLL7YFe/pme2cpvDsCwI1WXIfL+5eLz0MI9gFG24Re16RzUsI8t9XZn9ZWvgLNDrJBmrqXJO7GNQQ== + dependencies: + "@types/react" "*" + "@types/react-transition-group@^4.2.0", "@types/react-transition-group@^4.4.5": version "4.4.5" resolved "https://registry.yarnpkg.com/@types/react-transition-group/-/react-transition-group-4.4.5.tgz#aae20dcf773c5aa275d5b9f7cdbca638abc5e416" @@ -2808,6 +2787,13 @@ dependencies: "@types/react" "*" +"@types/react-transition-group@^4.4.6": + version "4.4.6" + resolved "https://registry.yarnpkg.com/@types/react-transition-group/-/react-transition-group-4.4.6.tgz#18187bcda5281f8e10dfc48f0943e2fdf4f75e2e" + integrity sha512-VnCdSxfcm08KjsJVQcfBmhEQAPnLB8G08hAxn39azX1qYBQ/5RVQuoHuKIcfKOdncuaUvEpFKFzEvbtIMsfVew== + dependencies: + "@types/react" "*" + "@types/react@*": version "18.0.26" resolved "https://registry.yarnpkg.com/@types/react/-/react-18.0.26.tgz#8ad59fc01fef8eaf5c74f4ea392621749f0b7917" @@ -4481,6 +4467,11 @@ dayjs@1.10.6: resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.10.6.tgz#288b2aa82f2d8418a6c9d4df5898c0737ad02a63" integrity sha512-AztC/IOW4L1Q41A86phW5Thhcrco3xuAA+YX/BLpLWWjRcTj5TOt/QImBLmCKlrF7u7k47arTnOyL6GnbG8Hvw== +dayjs@^1.11.7: + version "1.11.7" + resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.11.7.tgz#4b296922642f70999544d1144a2c25730fce63e2" + integrity sha512-+Yw9U6YO5TQohxLcIkrXBeY73WP3ejHWVvx8XCk3gxvQDCTEmS48ZrSZCKciI7Bhl/uCMyxYtE9UqRILmFphkQ== + debug@2.6.9, debug@^2.6.0, debug@^2.6.9: version "2.6.9" resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" @@ -9376,11 +9367,6 @@ reusify@^1.0.4: resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== -rifm@^0.12.1: - version "0.12.1" - resolved "https://registry.yarnpkg.com/rifm/-/rifm-0.12.1.tgz#8fa77f45b7f1cda2a0068787ac821f0593967ac4" - integrity sha512-OGA1Bitg/dSJtI/c4dh90svzaUPt228kzFsUkJbtA2c964IqEAwWXeL9ZJi86xWv3j5SMqRvGULl7bA6cK0Bvg== - rimraf@^3.0.0, rimraf@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" From 954f97a0857c367fce30aad8b11a167b5e149a5d Mon Sep 17 00:00:00 2001 From: luiz Date: Sun, 21 May 2023 12:44:16 +0200 Subject: [PATCH 008/328] fixes datetime --- .../components/domino-form-item.component.tsx | 27 ++++++++++++++----- 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item.component.tsx b/frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item.component.tsx index 407db893..87f6667b 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item.component.tsx +++ b/frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item.component.tsx @@ -132,24 +132,39 @@ const DominoFormItem: React.FC = ({ schema, itemKey, value, } else if (itemSchema.type === 'string' && itemSchema?.widget === 'date') { inputElement = ( - - + + ); } else if (itemSchema.type === 'string' && itemSchema?.widget === 'time') { inputElement = ( - - + + ); } else if (itemSchema.type === 'string' && itemSchema?.widget === 'datetime') { inputElement = ( - - + + ); From 386448128981a90baecbca3594071f1e28fea81c Mon Sep 17 00:00:00 2001 From: luiz Date: Sun, 21 May 2023 17:00:37 +0200 Subject: [PATCH 009/328] never and always conditions for from_upstream --- docker-compose-dev.yaml | 2 +- .../components/domino-form-item.component.tsx | 32 +++++++++++++++++-- 2 files changed, 30 insertions(+), 4 deletions(-) diff --git a/docker-compose-dev.yaml b/docker-compose-dev.yaml index fc31b70d..70ce2c85 100644 --- a/docker-compose-dev.yaml +++ b/docker-compose-dev.yaml @@ -314,7 +314,7 @@ services: - DOMINO_DB_HOST=domino_postgres - DOMINO_DB_PORT=5432 - DOMINO_DB_NAME=postgres - - DOMINO_DEFAULT_PIECES_REPOSITORY_VERSION=0.3.1 + - DOMINO_DEFAULT_PIECES_REPOSITORY_VERSION=0.3.2 - DOMINO_DEFAULT_PIECES_REPOSITORY_TOKEN=${DOMINO_DEFAULT_PIECES_REPOSITORY_TOKEN} - DOMINO_GITHUB_ACCESS_TOKEN_WORKFLOWS=${DOMINO_GITHUB_ACCESS_TOKEN_WORKFLOWS} - DOMINO_GITHUB_WORKFLOWS_REPOSITORY=${DOMINO_GITHUB_WORKFLOWS_REPOSITORY} diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item.component.tsx b/frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item.component.tsx index 87f6667b..44aff19c 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item.component.tsx +++ b/frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item.component.tsx @@ -29,9 +29,18 @@ interface DominoFormItemProps { } const DominoFormItem: React.FC = ({ schema, itemKey, value, onChange }) => { - const [checkedFromUpstream, setCheckedFromUpstream] = useState(false); + const [checkedFromUpstream, setCheckedFromUpstream] = useState(false); const [codeValue, setCodeValue] = useState( - "def custom_function(input_args: list):\n print(input_args)\n return 'Hello world!'" + `# Do not modify the function definition line +def custom_function(input_args: list): + # Write your code here + print(input_args) + + # Return the output of the function as an object + return { + "out_arg_1": "out_value_1", + "out_arg_2": "out_value_2" + }` ); // console.log(itemKey); @@ -44,6 +53,17 @@ const DominoFormItem: React.FC = ({ schema, itemKey, value, value = itemSchema.default; } + // from upstream condition, if "never" or "always" + let checkedFromUpstreamAllowed: boolean = true; + let checkedFromUpstreamEditable: boolean = true; + if (itemSchema?.from_upstream === "never") { + checkedFromUpstreamAllowed = false; + checkedFromUpstreamEditable = false; + } else if (itemSchema?.from_upstream === "always") { + checkedFromUpstreamAllowed = true; + checkedFromUpstreamEditable = false; + } + // Handle input change const handleInputChange = (event: React.ChangeEvent) => { onChange(event.target.value); @@ -210,7 +230,13 @@ const DominoFormItem: React.FC = ({ schema, itemKey, value, sx={{ paddingTop: "10px" }} > {inputElement} - + {checkedFromUpstreamAllowed ? ( + + ) : null}
); }; From 3398e146f0e79ceb5abef72eda50f39c5d62ddcc Mon Sep 17 00:00:00 2001 From: luiz Date: Sun, 21 May 2023 17:05:45 +0200 Subject: [PATCH 010/328] m --- .../components/domino-form-item.component.tsx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item.component.tsx b/frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item.component.tsx index 44aff19c..d6c1db1c 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item.component.tsx +++ b/frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item.component.tsx @@ -29,7 +29,9 @@ interface DominoFormItemProps { } const DominoFormItem: React.FC = ({ schema, itemKey, value, onChange }) => { - const [checkedFromUpstream, setCheckedFromUpstream] = useState(false); + const [checkedFromUpstream, setCheckedFromUpstream] = useState( + schema.properties[itemKey]?.from_upstream === "always" ? true : false + ); const [codeValue, setCodeValue] = useState( `# Do not modify the function definition line def custom_function(input_args: list): From 34a016fe8ccf219d7caa8b78075d2050f5c80f94 Mon Sep 17 00:00:00 2001 From: luiz Date: Sun, 21 May 2023 18:54:59 +0200 Subject: [PATCH 011/328] m --- .../domino-form-item-array.component.tsx | 36 ++++++++++++++++--- .../components/domino-form-item.component.tsx | 21 ++++++++--- 2 files changed, 48 insertions(+), 9 deletions(-) diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item-array.component.tsx b/frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item-array.component.tsx index abfc4b4e..869e7a91 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item-array.component.tsx +++ b/frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item-array.component.tsx @@ -17,20 +17,34 @@ import TextField from '@mui/material/TextField'; import DeleteIcon from '@mui/icons-material/Delete'; import AddIcon from '@mui/icons-material/Add'; + +// Arrays usually have their inner schema defined in the main schema definitions interface ArrayInputCardProps { - title: string; + itemSchema: any; + parentSchemaDefinitions: any; } -const ArrayInputCard: React.FC = ({ title }) => { +const ArrayInputCard: React.FC = ({ itemSchema, parentSchemaDefinitions }) => { const [arrayItems, setArrayItems] = useState(['']); const [checkedFromUpstream, setCheckedFromUpstream] = useState(false) + // Sub-items schema + let subItemSchema: any = itemSchema.items; + if (itemSchema.items?.$ref) { + const subItemSchemaName = itemSchema.items.$ref.split('/').pop(); + subItemSchema = parentSchemaDefinitions[subItemSchemaName]; + } + + console.log(itemSchema); + console.log(subItemSchema); + const handleArrayItemChange = (index: number, value: string) => { const updatedItems = [...arrayItems]; updatedItems[index] = value; setArrayItems(updatedItems); }; + // Add and delete items const handleAddItem = () => { setArrayItems([...arrayItems, '']); }; @@ -49,6 +63,18 @@ const ArrayInputCard: React.FC = ({ title }) => { console.log(event.target.value); }; + // TODO: create a function that returns the correct input element based on the schema + // TODO: it can be multiple types of input elements, like select, checkbox, etc. + { + if (subItemSchema?.properties) { + Object.keys(subItemSchema?.properties).map(key => ( + console.log(key) + )) + } + } + + + // create element const createInputElement = (item: string, index: number) => { let inputElement: JSX.Element; @@ -56,7 +82,7 @@ const ArrayInputCard: React.FC = ({ title }) => { const options = ['upstream 1', 'upstream 2', 'upstream 3', 'upstream 4']; inputElement = ( - {title} + {itemSchema.title} { + let inputElement: JSX.Element; + const subSubItemSchema = arrayOfProperties[itemKey]; + const value = arrayItems[index as number][itemKey as keyof typeof arrayItems[number]] + if (checkedFromUpstream) { + const options = ['upstream 1', 'upstream 2', 'upstream 3', 'upstream 4']; + inputElement = ( + + {`${itemKey} [${index}]`} + + + ); + } else if (subSubItemSchema?.allOf && subSubItemSchema.allOf.length > 0) { + const typeClass = subSubItemSchema.allOf[0]['$ref'].split("/").pop(); + const valuesOptions: Array = parentSchemaDefinitions?.[typeClass].enum; + inputElement = ( + + {`${itemKey} [${index}]`} + + + ); + } else { + inputElement = - {options.map(option => ( - - {option} - - ))} - - - ); - } else { - inputElement = handleArrayItemChange(index, e.target.value)} - /> + label={`${itemKey} [${index}]`} + value={value} + onChange={(e) => handleArrayItemChange(index, e.target.value)} + /> + } + itemElements.push(inputElement); + }); } - return inputElement; + return itemElements; } return ( @@ -139,7 +168,7 @@ const ArrayInputItem: React.FC = ({ itemSchema, parentSchem handleDeleteItem(index)} aria-label="Delete"> - {createInputElement(item, index)} + {createItemElements(item, index)} {fromUpstreamMode !== "never" ? ( = ({ schema, itemKey, value, return false; } }); - const [codeValue, setCodeValue] = useState( - `# Do not modify the function definition line + const [codeValue, setCodeValue] = useState(() => { + if (schema.properties[itemKey]?.default) { + return schema.properties[itemKey].default; + } else { + return `# Do not modify the function definition line def custom_function(input_args: list): # Write your code here print(input_args) @@ -49,8 +52,9 @@ def custom_function(input_args: list): return { "out_arg_1": "out_value_1", "out_arg_2": "out_value_2" - }` - ); + }`; + } + }); // console.log(itemKey); // console.log(value) diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component.tsx b/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component.tsx index 450101ca..8ba0edfe 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component.tsx +++ b/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component.tsx @@ -68,8 +68,6 @@ const SidebarForm = (props: ISidebarFormProps) => { const handleOnChange = useCallback(async ({ errors, data }: { errors?: any, data: any }) => { - console.log('formid', formId) - console.log('data', data) // On change update form data in forage try { var upstreamMap = await getForageUpstreamMap() From 54da3bed1ab252acfa3828986021f9ec29e2967a Mon Sep 17 00:00:00 2001 From: luiz Date: Wed, 24 May 2023 20:38:23 +0200 Subject: [PATCH 015/328] default values for simple arrays --- docker-compose-dev.yaml | 2 +- .../components/domino-form-item-array.component.tsx | 12 ++++++++---- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/docker-compose-dev.yaml b/docker-compose-dev.yaml index 0736422d..93a4f3fe 100644 --- a/docker-compose-dev.yaml +++ b/docker-compose-dev.yaml @@ -314,7 +314,7 @@ services: - DOMINO_DB_HOST=domino_postgres - DOMINO_DB_PORT=5432 - DOMINO_DB_NAME=postgres - - DOMINO_DEFAULT_PIECES_REPOSITORY_VERSION=0.3.4 + - DOMINO_DEFAULT_PIECES_REPOSITORY_VERSION=0.3.5 - DOMINO_DEFAULT_PIECES_REPOSITORY_TOKEN=${DOMINO_DEFAULT_PIECES_REPOSITORY_TOKEN} - DOMINO_GITHUB_ACCESS_TOKEN_WORKFLOWS=${DOMINO_GITHUB_ACCESS_TOKEN_WORKFLOWS} - DOMINO_GITHUB_WORKFLOWS_REPOSITORY=${DOMINO_GITHUB_WORKFLOWS_REPOSITORY} diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item-array.component.tsx b/frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item-array.component.tsx index 6a8c5794..aefc3181 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item-array.component.tsx +++ b/frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item-array.component.tsx @@ -34,7 +34,6 @@ interface ArrayInputItemProps { const ArrayInputItem: React.FC = ({ itemSchema, parentSchemaDefinitions, fromUpstreamMode }) => { const [arrayItems, setArrayItems] = useState(() => { if (itemSchema.default && itemSchema.default.length > 0) { - console.log("itemSchema.default", itemSchema.default); return itemSchema.default; } else { return [""]; @@ -99,7 +98,12 @@ const ArrayInputItem: React.FC = ({ itemSchema, parentSchem Object.keys(arrayOfProperties).map((itemKey, subIndex) => { let inputElement: JSX.Element; const subSubItemSchema = arrayOfProperties[itemKey]; - const value = arrayItems[index as number][itemKey as keyof typeof arrayItems[number]] + let initialValue: any = ''; + if (typeof arrayItems[index] === 'object') { + initialValue = arrayItems[index as number][itemKey as keyof typeof arrayItems[number]]; + } else { + initialValue = arrayItems[index as number]; + } if (checkedFromUpstream) { const options = ['upstream 1', 'upstream 2', 'upstream 3', 'upstream 4']; inputElement = ( @@ -124,7 +128,7 @@ const ArrayInputItem: React.FC = ({ itemSchema, parentSchem {`${itemKey} [${index}]`} ); - } else if (subSubItemSchema?.allOf && subSubItemSchema.allOf.length > 0) { - const typeClass = subSubItemSchema.allOf[0]['$ref'].split("/").pop(); + } else if (subItemPropSchema?.allOf && subItemPropSchema.allOf.length > 0) { + const typeClass = subItemPropSchema.allOf[0]['$ref'].split("/").pop(); const valuesOptions: Array = parentSchemaDefinitions?.[typeClass].enum; inputElement = ( @@ -155,7 +155,7 @@ const ArrayInputItem: React.FC = ({ itemSchema, parentSchem ) : null}
From 2df0aaa8a4504c5d6a386af9ca2000881134c9c9 Mon Sep 17 00:00:00 2001 From: luiz Date: Fri, 26 May 2023 10:07:57 +0200 Subject: [PATCH 021/328] no default widget if type is unkwon --- .../components/domino-form-item.component.tsx | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item.component.tsx b/frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item.component.tsx index 1de6c44b..dc180b63 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item.component.tsx +++ b/frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item.component.tsx @@ -234,7 +234,7 @@ def custom_function(input_args: list): }} /> ) - } else { + } else if (itemSchema.type === 'string') { inputElement = ( ); + } else { + inputElement =
+ Unknown widget type for {itemSchema.title} +
; } return ( From 3ffad2d14284b5b4090a95f2fcbe56aa7225cf51 Mon Sep 17 00:00:00 2001 From: luiz Date: Fri, 26 May 2023 12:16:46 +0200 Subject: [PATCH 022/328] checkbox array item props, not working 100% yet --- .../domino-form-item-array.component.tsx | 36 +++++++++++++------ 1 file changed, 25 insertions(+), 11 deletions(-) diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item-array.component.tsx b/frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item-array.component.tsx index 8edd8902..2f9d9ed6 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item-array.component.tsx +++ b/frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item-array.component.tsx @@ -39,13 +39,16 @@ const ArrayInputItem: React.FC = ({ itemSchema, parentSchem return [""]; } }); - const [checkedFromUpstream, setCheckedFromUpstream] = useState(() => { - if (fromUpstreamMode === "always") { - return true; + type ObjectWithBooleanValues = { [key: string]: boolean }; + const [checkedFromUpstreamItemProp, setCheckedFromUpstreamItemProp] = useState(() => { + if (itemSchema.default && itemSchema.default.length > 0) { + const newArray = new Array(itemSchema.default.length).fill({}); + return newArray; } else { - return false; + return []; } - }) + }); + // Sub-items schema let subItemSchema: any = itemSchema.items; @@ -67,17 +70,28 @@ const ArrayInputItem: React.FC = ({ itemSchema, parentSchem // Add and delete items const handleAddItem = () => { setArrayItems([...arrayItems, '']); + setCheckedFromUpstreamItemProp([...checkedFromUpstreamItemProp, {}]); }; const handleDeleteItem = (index: number) => { const updatedItems = [...arrayItems]; updatedItems.splice(index, 1); setArrayItems(updatedItems); + const updatedCheckedFromUpstreamItemProp = [...checkedFromUpstreamItemProp]; + updatedCheckedFromUpstreamItemProp.splice(index, 1); + setCheckedFromUpstreamItemProp(updatedCheckedFromUpstreamItemProp); }; - // FomrUpstream logic - const handleCheckboxFromUpstreamChange = (event: React.ChangeEvent) => { - setCheckedFromUpstream(event.target.checked); + // FromUpstream logic + const handleCheckboxFromUpstreamChange = (event: React.ChangeEvent, index: number, itemKey: string) => { + setCheckedFromUpstreamItemProp((prevArray) => { + const newArray = [...prevArray]; + const objectToUpdate = newArray[index] as { [key: string]: boolean }; + objectToUpdate[itemKey] = event.target.checked; + newArray[index] = objectToUpdate; + return newArray; + }); + console.log(checkedFromUpstreamItemProp); }; const handleSelectFromUpstreamChange = (event: SelectChangeEvent) => { console.log(event.target.value); @@ -105,7 +119,7 @@ const ArrayInputItem: React.FC = ({ itemSchema, parentSchem } else { initialValue = arrayItems[index as number]; } - if (checkedFromUpstream) { + if (checkedFromUpstreamItemProp[index]?.[itemKey]) { const options = ['upstream 1', 'upstream 2', 'upstream 3', 'upstream 4']; inputElement = ( @@ -153,8 +167,8 @@ const ArrayInputItem: React.FC = ({ itemSchema, parentSchem {inputElement} {fromUpstreamMode !== "never" ? ( handleCheckboxFromUpstreamChange(event, index, itemKey)} disabled={subItemPropSchema?.from_upstream === 'never' || subItemPropSchema?.from_upstream === 'always'} /> ) : null} From 1b38352f8263cb8bf1397dbd10360c2e29176a32 Mon Sep 17 00:00:00 2001 From: luiz Date: Fri, 26 May 2023 12:57:54 +0200 Subject: [PATCH 023/328] fix warnings --- .../domino-form-item-array.component.tsx | 134 +++++++++--------- 1 file changed, 65 insertions(+), 69 deletions(-) diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item-array.component.tsx b/frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item-array.component.tsx index 2f9d9ed6..f54929e9 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item-array.component.tsx +++ b/frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item-array.component.tsx @@ -1,12 +1,10 @@ import React, { useState } from 'react'; import { Card, - CardHeader, CardContent, IconButton, Box, Checkbox, - Input, Select, MenuItem, SelectChangeEvent, @@ -49,7 +47,6 @@ const ArrayInputItem: React.FC = ({ itemSchema, parentSchem } }); - // Sub-items schema let subItemSchema: any = itemSchema.items; if (itemSchema.items?.$ref) { @@ -109,73 +106,72 @@ const ArrayInputItem: React.FC = ({ itemSchema, parentSchem } const numProps = Object.keys(arrayOfProperties).length; // Loop through each of the item's properties and create the inputs for them - { - Object.keys(arrayOfProperties).map((itemKey, subIndex) => { - let inputElement: JSX.Element; - const subItemPropSchema = arrayOfProperties[itemKey]; - let initialValue: any = ''; - if (typeof arrayItems[index] === 'object') { - initialValue = arrayItems[index as number][itemKey as keyof typeof arrayItems[number]]; - } else { - initialValue = arrayItems[index as number]; - } - if (checkedFromUpstreamItemProp[index]?.[itemKey]) { - const options = ['upstream 1', 'upstream 2', 'upstream 3', 'upstream 4']; - inputElement = ( - - {`${itemKey} [${index}]`} - - - ); - } else if (subItemPropSchema?.allOf && subItemPropSchema.allOf.length > 0) { - const typeClass = subItemPropSchema.allOf[0]['$ref'].split("/").pop(); - const valuesOptions: Array = parentSchemaDefinitions?.[typeClass].enum; - inputElement = ( - - {`${itemKey} [${index}]`} - - - ); - } else { - inputElement = handleArrayItemChange(index, e.target.value)} - /> - } - itemElements.push( -
- {inputElement} - {fromUpstreamMode !== "never" ? ( - handleCheckboxFromUpstreamChange(event, index, itemKey)} - disabled={subItemPropSchema?.from_upstream === 'never' || subItemPropSchema?.from_upstream === 'always'} - /> - ) : null} -
+ Object.keys(arrayOfProperties).map((itemKey, subIndex) => { + let inputElement: JSX.Element; + const subItemPropSchema = arrayOfProperties[itemKey]; + let initialValue: any = ''; + if (typeof arrayItems[index] === 'object') { + initialValue = arrayItems[index as number][itemKey as keyof typeof arrayItems[number]]; + } else { + initialValue = arrayItems[index as number]; + } + if (checkedFromUpstreamItemProp[index]?.[itemKey]) { + const options = ['upstream 1', 'upstream 2', 'upstream 3', 'upstream 4']; + inputElement = ( + + {`${itemKey} [${index}]`} + + ); - }); - } + } else if (subItemPropSchema?.allOf && subItemPropSchema.allOf.length > 0) { + const typeClass = subItemPropSchema.allOf[0]['$ref'].split("/").pop(); + const valuesOptions: Array = parentSchemaDefinitions?.[typeClass].enum; + inputElement = ( + + {`${itemKey} [${index}]`} + + + ); + } else { + inputElement = handleArrayItemChange(index, e.target.value)} + /> + } + itemElements.push( +
+ {inputElement} + {fromUpstreamMode !== "never" ? ( + handleCheckboxFromUpstreamChange(event, index, itemKey)} + disabled={subItemPropSchema?.from_upstream === 'never' || subItemPropSchema?.from_upstream === 'always'} + /> + ) : null} +
+ ); + return null; + }); return
Date: Fri, 26 May 2023 13:04:01 +0200 Subject: [PATCH 024/328] fix initial state --- .../components/domino-form-item-array.component.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item-array.component.tsx b/frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item-array.component.tsx index f54929e9..f0eb6604 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item-array.component.tsx +++ b/frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item-array.component.tsx @@ -34,7 +34,7 @@ const ArrayInputItem: React.FC = ({ itemSchema, parentSchem if (itemSchema.default && itemSchema.default.length > 0) { return itemSchema.default; } else { - return [""]; + return []; } }); type ObjectWithBooleanValues = { [key: string]: boolean }; @@ -84,6 +84,7 @@ const ArrayInputItem: React.FC = ({ itemSchema, parentSchem setCheckedFromUpstreamItemProp((prevArray) => { const newArray = [...prevArray]; const objectToUpdate = newArray[index] as { [key: string]: boolean }; + console.log(objectToUpdate); objectToUpdate[itemKey] = event.target.checked; newArray[index] = objectToUpdate; return newArray; From 1fbdfb0e6578390b3bf06a5a5b14979bf6704e6a Mon Sep 17 00:00:00 2001 From: luiz Date: Fri, 26 May 2023 13:15:07 +0200 Subject: [PATCH 025/328] increase a bit handlers sizes to facilitate connection --- .../workflows-editor/components/custom-node.component.tsx | 4 ++-- .../components/domino-form-item-array.component.tsx | 7 ++++--- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/custom-node.component.tsx b/frontend/src/pages/private/workflows/workflows-editor/components/custom-node.component.tsx index 823e16cd..260f2155 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/components/custom-node.component.tsx +++ b/frontend/src/pages/private/workflows/workflows-editor/components/custom-node.component.tsx @@ -93,7 +93,7 @@ const CustomNode = memo((data: any) => { type='source' id={`$handle-source-${data['id']}`} position={sourceHandlePosition} - style={{ width: "8px", height: "8px", border: '1px solid black', backgroundColor: 'white' }} + style={{ width: "10px", height: "10px", border: '1px solid black', backgroundColor: 'white' }} /> ) : "" } @@ -119,7 +119,7 @@ const CustomNode = memo((data: any) => { type='target' id={`$handle-target-${data['id']}`} position={targetHandlePosition} - style={{ width: "8px", height: "8px", borderRadius: '0px', border: '1px solid black', backgroundColor: 'white' }} + style={{ width: "8px", height: "16px", borderRadius: '0px', border: '1px solid black', backgroundColor: 'white' }} /> ) : "" } diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item-array.component.tsx b/frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item-array.component.tsx index f0eb6604..a3488f81 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item-array.component.tsx +++ b/frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item-array.component.tsx @@ -32,7 +32,8 @@ interface ArrayInputItemProps { const ArrayInputItem: React.FC = ({ itemSchema, parentSchemaDefinitions, fromUpstreamMode }) => { const [arrayItems, setArrayItems] = useState(() => { if (itemSchema.default && itemSchema.default.length > 0) { - return itemSchema.default; + const initArray = [...itemSchema.default]; + return initArray; } else { return []; } @@ -40,8 +41,8 @@ const ArrayInputItem: React.FC = ({ itemSchema, parentSchem type ObjectWithBooleanValues = { [key: string]: boolean }; const [checkedFromUpstreamItemProp, setCheckedFromUpstreamItemProp] = useState(() => { if (itemSchema.default && itemSchema.default.length > 0) { - const newArray = new Array(itemSchema.default.length).fill({}); - return newArray; + const initArray = new Array(itemSchema.default.length).fill({}); + return initArray; } else { return []; } From ce6d990c217b6912c50acfafb94ad48bbe7336a5 Mon Sep 17 00:00:00 2001 From: luiz Date: Fri, 26 May 2023 15:33:11 +0200 Subject: [PATCH 026/328] fromupstream checkboxes for default arrays --- docker-compose-dev.yaml | 2 +- .../domino-form-item-array.component.tsx | 57 ++++++++++++------- 2 files changed, 37 insertions(+), 22 deletions(-) diff --git a/docker-compose-dev.yaml b/docker-compose-dev.yaml index ea5187a0..012fa474 100644 --- a/docker-compose-dev.yaml +++ b/docker-compose-dev.yaml @@ -314,7 +314,7 @@ services: - DOMINO_DB_HOST=domino_postgres - DOMINO_DB_PORT=5432 - DOMINO_DB_NAME=postgres - - DOMINO_DEFAULT_PIECES_REPOSITORY_VERSION=0.3.6 + - DOMINO_DEFAULT_PIECES_REPOSITORY_VERSION=0.3.7 - DOMINO_DEFAULT_PIECES_REPOSITORY_TOKEN=${DOMINO_DEFAULT_PIECES_REPOSITORY_TOKEN} - DOMINO_GITHUB_ACCESS_TOKEN_WORKFLOWS=${DOMINO_GITHUB_ACCESS_TOKEN_WORKFLOWS} - DOMINO_GITHUB_WORKFLOWS_REPOSITORY=${DOMINO_GITHUB_WORKFLOWS_REPOSITORY} diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item-array.component.tsx b/frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item-array.component.tsx index a3488f81..a907b112 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item-array.component.tsx +++ b/frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item-array.component.tsx @@ -38,15 +38,6 @@ const ArrayInputItem: React.FC = ({ itemSchema, parentSchem return []; } }); - type ObjectWithBooleanValues = { [key: string]: boolean }; - const [checkedFromUpstreamItemProp, setCheckedFromUpstreamItemProp] = useState(() => { - if (itemSchema.default && itemSchema.default.length > 0) { - const initArray = new Array(itemSchema.default.length).fill({}); - return initArray; - } else { - return []; - } - }); // Sub-items schema let subItemSchema: any = itemSchema.items; @@ -54,11 +45,42 @@ const ArrayInputItem: React.FC = ({ itemSchema, parentSchem const subItemSchemaName = itemSchema.items.$ref.split('/').pop(); subItemSchema = parentSchemaDefinitions[subItemSchemaName]; } + let arrayOfProperties: { [key: string]: any } = {}; + // If array subtypes were not defined in the schema, we create a default one + if (subItemSchema?.properties) { + arrayOfProperties = subItemSchema?.properties; + } else { + arrayOfProperties[itemSchema.title] = { "": "" }; + } + const numProps = Object.keys(arrayOfProperties).length; + // console.log("itemSchema", itemSchema); - // console.log("subItemSchema", subItemSchema); + console.log("subItemSchema", subItemSchema); // console.log("parentSchemaDefinitions", parentSchemaDefinitions); + type ObjectWithBooleanValues = { [key: string]: boolean }; + const [checkedFromUpstreamItemProp, setCheckedFromUpstreamItemProp] = useState(() => { + if (itemSchema.default && itemSchema.default.length > 0) { + const initArray = new Array(itemSchema.default.length).fill({}); + // set the default values from the schema in cases where from_upstream==="always" + initArray.map((obj, index) => { + Object.keys(arrayOfProperties).map((itemKey) => { + if (subItemSchema?.properties?.[itemKey]?.from_upstream === "always") { + initArray[index][itemKey] = true; + } else { + initArray[index][itemKey] = false; + } + return null; + }); + return null; + }); + return initArray; + } else { + return []; + } + }); + const handleArrayItemChange = (index: number, value: string) => { const updatedItems = [...arrayItems]; updatedItems[index] = value; @@ -82,12 +104,13 @@ const ArrayInputItem: React.FC = ({ itemSchema, parentSchem // FromUpstream logic const handleCheckboxFromUpstreamChange = (event: React.ChangeEvent, index: number, itemKey: string) => { + console.log(checkedFromUpstreamItemProp); setCheckedFromUpstreamItemProp((prevArray) => { const newArray = [...prevArray]; const objectToUpdate = newArray[index] as { [key: string]: boolean }; console.log(objectToUpdate); objectToUpdate[itemKey] = event.target.checked; - newArray[index] = objectToUpdate; + // newArray[index] = objectToUpdate; return newArray; }); console.log(checkedFromUpstreamItemProp); @@ -99,14 +122,6 @@ const ArrayInputItem: React.FC = ({ itemSchema, parentSchem // Each item in the array can be multiple inputs, with varied types like text, select, checkbox, etc. const createItemElements = (item: string, index: number) => { let itemElements: JSX.Element[] = []; - let arrayOfProperties: { [key: string]: any } = {}; - // If array subtypes were not defined in the schema, we create a default one - if (subItemSchema?.properties) { - arrayOfProperties = subItemSchema?.properties; - } else { - arrayOfProperties[itemSchema.title] = { "": "" }; - } - const numProps = Object.keys(arrayOfProperties).length; // Loop through each of the item's properties and create the inputs for them Object.keys(arrayOfProperties).map((itemKey, subIndex) => { let inputElement: JSX.Element; @@ -163,9 +178,9 @@ const ArrayInputItem: React.FC = ({ itemSchema, parentSchem itemElements.push(
{inputElement} - {fromUpstreamMode !== "never" ? ( + {subItemPropSchema?.from_upstream !== "never" ? ( handleCheckboxFromUpstreamChange(event, index, itemKey)} disabled={subItemPropSchema?.from_upstream === 'never' || subItemPropSchema?.from_upstream === 'always'} /> From 674a07ca21dd0151261fa9ce2f05a9cbe08a1b37 Mon Sep 17 00:00:00 2001 From: luiz Date: Fri, 26 May 2023 15:33:32 +0200 Subject: [PATCH 027/328] remove print --- .../components/domino-form-item-array.component.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item-array.component.tsx b/frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item-array.component.tsx index a907b112..83b775d5 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item-array.component.tsx +++ b/frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item-array.component.tsx @@ -56,7 +56,7 @@ const ArrayInputItem: React.FC = ({ itemSchema, parentSchem // console.log("itemSchema", itemSchema); - console.log("subItemSchema", subItemSchema); + // console.log("subItemSchema", subItemSchema); // console.log("parentSchemaDefinitions", parentSchemaDefinitions); type ObjectWithBooleanValues = { [key: string]: boolean }; From 823a5c51d5b00f7fe560c305954720f72b5ec892 Mon Sep 17 00:00:00 2001 From: luiz Date: Fri, 26 May 2023 16:55:29 +0200 Subject: [PATCH 028/328] logging trying to figure out whats going wrong --- .../components/domino-form-item-array.component.tsx | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item-array.component.tsx b/frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item-array.component.tsx index 83b775d5..2851a92e 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item-array.component.tsx +++ b/frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item-array.component.tsx @@ -102,19 +102,26 @@ const ArrayInputItem: React.FC = ({ itemSchema, parentSchem setCheckedFromUpstreamItemProp(updatedCheckedFromUpstreamItemProp); }; - // FromUpstream logic + // FromUpstream checkboxes logic + // TODO - this is not working for multiple default items, they're changing together const handleCheckboxFromUpstreamChange = (event: React.ChangeEvent, index: number, itemKey: string) => { console.log(checkedFromUpstreamItemProp); + console.log("event", event.target.checked); + console.log("index", index); + console.log("itemkey", itemKey); setCheckedFromUpstreamItemProp((prevArray) => { const newArray = [...prevArray]; + console.log(newArray); const objectToUpdate = newArray[index] as { [key: string]: boolean }; console.log(objectToUpdate); objectToUpdate[itemKey] = event.target.checked; - // newArray[index] = objectToUpdate; + newArray[index] = objectToUpdate; return newArray; }); console.log(checkedFromUpstreamItemProp); }; + + // FromUpstream select logic const handleSelectFromUpstreamChange = (event: SelectChangeEvent) => { console.log(event.target.value); }; @@ -231,4 +238,4 @@ const ArrayInputItem: React.FC = ({ itemSchema, parentSchem ); }; -export default ArrayInputItem; +export default ArrayInputItem; \ No newline at end of file From 06f69b11bbd9a9e0bad7bdccaca2f535f22536f6 Mon Sep 17 00:00:00 2001 From: luiz Date: Tue, 30 May 2023 14:43:27 +0200 Subject: [PATCH 029/328] fix adding new items when from_upstream==="always" --- .../components/domino-form-item-array.component.tsx | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item-array.component.tsx b/frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item-array.component.tsx index 2851a92e..592bf500 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item-array.component.tsx +++ b/frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item-array.component.tsx @@ -90,9 +90,19 @@ const ArrayInputItem: React.FC = ({ itemSchema, parentSchem // Add and delete items const handleAddItem = () => { setArrayItems([...arrayItems, '']); - setCheckedFromUpstreamItemProp([...checkedFromUpstreamItemProp, {}]); + let newItemPropChecked: { [key: string]: boolean } = {}; + Object.keys(arrayOfProperties).map((itemKey) => { + if (subItemSchema?.properties?.[itemKey]?.from_upstream === "always") { + newItemPropChecked[itemKey] = true; + } else { + newItemPropChecked[itemKey] = false; + } + return null; + }); + setCheckedFromUpstreamItemProp([...checkedFromUpstreamItemProp, newItemPropChecked]); }; + // TODO - this is not working when deleting items with fromUpstrem checked const handleDeleteItem = (index: number) => { const updatedItems = [...arrayItems]; updatedItems.splice(index, 1); From 5b046f866c8ec3bde003f202223e034c19e356de Mon Sep 17 00:00:00 2001 From: luiz Date: Tue, 30 May 2023 15:23:58 +0200 Subject: [PATCH 030/328] fix change fromUpstream select --- .../domino-form-item-array.component.tsx | 35 +++++++++++-------- 1 file changed, 21 insertions(+), 14 deletions(-) diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item-array.component.tsx b/frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item-array.component.tsx index 592bf500..10c20c10 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item-array.component.tsx +++ b/frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item-array.component.tsx @@ -30,7 +30,7 @@ interface ArrayInputItemProps { } const ArrayInputItem: React.FC = ({ itemSchema, parentSchemaDefinitions, fromUpstreamMode }) => { - const [arrayItems, setArrayItems] = useState(() => { + const [arrayItems, setArrayItems] = useState(() => { if (itemSchema.default && itemSchema.default.length > 0) { const initArray = [...itemSchema.default]; return initArray; @@ -81,25 +81,29 @@ const ArrayInputItem: React.FC = ({ itemSchema, parentSchem } }); - const handleArrayItemChange = (index: number, value: string) => { + const handleArrayItemChange = (index: number, itemKey: string, value: string) => { const updatedItems = [...arrayItems]; - updatedItems[index] = value; + updatedItems[index][itemKey] = value; setArrayItems(updatedItems); }; // Add and delete items + // TODO - fix setArrayItems to fill the props with correct values types, right now just guessing an empty string, but this will most likely fail e.g. boolen types const handleAddItem = () => { - setArrayItems([...arrayItems, '']); - let newItemPropChecked: { [key: string]: boolean } = {}; + let newItemPropsValues: { [key: string]: any } = {}; + let newItemPropsChecked: { [key: string]: boolean } = {}; Object.keys(arrayOfProperties).map((itemKey) => { if (subItemSchema?.properties?.[itemKey]?.from_upstream === "always") { - newItemPropChecked[itemKey] = true; + newItemPropsChecked[itemKey] = true; + newItemPropsValues[itemKey] = ''; } else { - newItemPropChecked[itemKey] = false; + newItemPropsChecked[itemKey] = false; + newItemPropsValues[itemKey] = ''; } return null; }); - setCheckedFromUpstreamItemProp([...checkedFromUpstreamItemProp, newItemPropChecked]); + setCheckedFromUpstreamItemProp([...checkedFromUpstreamItemProp, newItemPropsChecked]); + setArrayItems([...arrayItems, newItemPropsValues]); }; // TODO - this is not working when deleting items with fromUpstrem checked @@ -132,8 +136,10 @@ const ArrayInputItem: React.FC = ({ itemSchema, parentSchem }; // FromUpstream select logic - const handleSelectFromUpstreamChange = (event: SelectChangeEvent) => { - console.log(event.target.value); + const handleSelectFromUpstreamChange = (index: number, itemKey: string, value: string) => { + const updatedItems = [...arrayItems]; + updatedItems[index][itemKey] = value; + setArrayItems(updatedItems); }; // Each item in the array can be multiple inputs, with varied types like text, select, checkbox, etc. @@ -150,13 +156,14 @@ const ArrayInputItem: React.FC = ({ itemSchema, parentSchem initialValue = arrayItems[index as number]; } if (checkedFromUpstreamItemProp[index]?.[itemKey]) { - const options = ['upstream 1', 'upstream 2', 'upstream 3', 'upstream 4']; + const options: Array = ['upstream 1', 'upstream 2', 'upstream 3', 'upstream 4']; inputElement = ( {`${itemKey} [${index}]`} handleArrayItemChange(index, itemKey, e.target.value)} > {valuesOptions.map((option: string) => ( @@ -189,7 +196,7 @@ const ArrayInputItem: React.FC = ({ itemSchema, parentSchem fullWidth label={`${itemKey} [${index}]`} value={initialValue} - onChange={(e) => handleArrayItemChange(index, e.target.value)} + onChange={(e) => handleArrayItemChange(index, itemKey, e.target.value)} /> } itemElements.push( From cdee79e921a652006594396e79097fa2d48867cb Mon Sep 17 00:00:00 2001 From: luiz Date: Tue, 30 May 2023 15:41:06 +0200 Subject: [PATCH 031/328] mini fix --- .../components/domino-form-item-array.component.tsx | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item-array.component.tsx b/frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item-array.component.tsx index 10c20c10..419cc57a 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item-array.component.tsx +++ b/frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item-array.component.tsx @@ -138,7 +138,11 @@ const ArrayInputItem: React.FC = ({ itemSchema, parentSchem // FromUpstream select logic const handleSelectFromUpstreamChange = (index: number, itemKey: string, value: string) => { const updatedItems = [...arrayItems]; - updatedItems[index][itemKey] = value; + if (typeof updatedItems[index] === 'object') { + updatedItems[index][itemKey] = value; + } else { + updatedItems[index] = value; + } setArrayItems(updatedItems); }; From 39ed2144a78c9fc9012702d66f90fe1bcdf82f4c Mon Sep 17 00:00:00 2001 From: Vinicius Date: Tue, 30 May 2023 14:48:21 -0300 Subject: [PATCH 032/328] upstream dropdown --- .../components/domino-form-item.component.tsx | 113 ++++++++++++++++-- .../components/domino-form.component.tsx | 4 +- .../components/sidebar-form.component.tsx | 2 +- 3 files changed, 110 insertions(+), 9 deletions(-) diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item.component.tsx b/frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item.component.tsx index 465e5774..68863b41 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item.component.tsx +++ b/frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item.component.tsx @@ -1,4 +1,4 @@ -import React, { useState } from 'react'; +import React, { useState, useCallback } from 'react'; import { TextField, Select, @@ -17,18 +17,34 @@ import { DatePicker } from '@mui/x-date-pickers/DatePicker'; import { TimePicker } from '@mui/x-date-pickers/TimePicker'; import { DateTimePicker } from '@mui/x-date-pickers/DateTimePicker'; import CodeEditor from '@uiw/react-textarea-code-editor'; - +import { useWorkflowsEditor } from 'context/workflows/workflows-editor.context' import ArrayInputItem from './domino-form-item-array.component'; interface DominoFormItemProps { + formId: string; schema: any; itemKey: any; value: any; onChange: (val: any) => void; } -const DominoFormItem: React.FC = ({ schema, itemKey, value, onChange }) => { +const DominoFormItem: React.FC = ({ formId, schema, itemKey, value, onChange }) => { + const { + setFormsForageData, + fetchForageDataById, + fetchForageWorkflowEdges, + getForageUpstreamMap, + setForageUpstreamMap, + fetchForagePieceById, + getForageCheckboxStates, + setForageCheckboxStates, + setNameKeyUpstreamArgsMap, + getNameKeyUpstreamArgsMap, + } = useWorkflowsEditor() + + const formFieldType = schema.properties[itemKey].type; + const [upstreamOptions, setUpstreamOptions] = useState([]); const [checkedFromUpstream, setCheckedFromUpstream] = useState(() => { if (schema.properties[itemKey]?.from_upstream === "always") { if (schema.properties[itemKey].type === 'array') { @@ -87,26 +103,109 @@ def custom_function(input_args: list): // Handle input change const handleInputChange = (event: React.ChangeEvent) => { + console.log('handleInputChange') onChange(event.target.value); }; const handleSelectChange = (event: SelectChangeEvent) => { + console.log('handleSelectChange') onChange(event.target.value as string); }; // FomrUpstream logic - const handleCheckboxFromUpstreamChange = (event: React.ChangeEvent) => { + const handleCheckboxFromUpstreamChange = useCallback(async(event: React.ChangeEvent) => { + // itemKey = form key to be updated (input_arg for example) + // formId has the nodeId to update the possible upstreams enums from edges connections setCheckedFromUpstream(event.target.checked); - }; + + var auxSchema = JSON.parse(JSON.stringify(schema)) + var formKeys = Object.keys(schema.properties) + const edges = await fetchForageWorkflowEdges() + + var auxCheckboxState: any = await getForageCheckboxStates() + if (!auxCheckboxState) { + auxCheckboxState = {} + } + if (formId in auxCheckboxState) { + auxCheckboxState[formId][itemKey] = event.target.checked + } else { + auxCheckboxState[formId] = { + [itemKey]: event.target.checked + } + } + await setForageCheckboxStates(auxCheckboxState) + + // We can improve the logic using a forage key using following structure: + // nodeId: { + // upstreams: [], + // downstreams: [], + // } + // It will avoid to iterate over all edges + var upstreamsIds = [] + for (var ed of edges) { + if (ed.target === formId) { + upstreamsIds.push(ed.source) + } + } + if (!upstreamsIds.length) { + return + } + + var upstreamMap = await getForageUpstreamMap() + if (!(formId in upstreamMap)) { + upstreamMap[formId] = {} + } + + const auxNameKeyUpstreamArgsMap: any = {} + const upstreamOptions: string[] = [] + for (var upstreamId of upstreamsIds){parseInt(upstreamId.split('_')[0]) + const upstreamOperatorId = parseInt(upstreamId.split('_')[0]) + if (event.target.checked) { + const upstreamOperator = await fetchForagePieceById(upstreamOperatorId) + const upstreamOutputSchema = upstreamOperator?.output_schema + Object.keys(upstreamOutputSchema?.properties).forEach((key, index) => { + const obj = upstreamOutputSchema?.properties[key] + console.log(obj.type) + if (obj.type === formFieldType){ + // todo add to possible dropdown options + var upstreamOptionName = `${upstreamOperator?.name} - ${obj['title']}` + const counter = 1; + while (upstreamOptions.includes(upstreamOptionName)) { + upstreamOptionName = `${upstreamOptionName} (${counter})` + } + upstreamOptions.push(upstreamOptionName) + auxNameKeyUpstreamArgsMap[upstreamOptionName] = key + } + }) + } + } + console.log('upstreamOptions', upstreamOptions) + console.log('auxNameKeyUpstreamArgsMap', auxNameKeyUpstreamArgsMap) + setUpstreamOptions(upstreamOptions) + + + + },[ + formId, + schema, + itemKey, + fetchForageWorkflowEdges, + getForageCheckboxStates, + setForageCheckboxStates, + getForageUpstreamMap, + formFieldType, + fetchForagePieceById, + + ]); const handleSelectFromUpstreamChange = (event: SelectChangeEvent) => { + console.log('handleSelectFromUpstreamChange') console.log(event.target.value); }; let inputElement: JSX.Element; if (checkedFromUpstream) { - const options = ['upstream 1', 'upstream 2', 'upstream 3', 'upstream 4']; inputElement = ( {itemKey} @@ -115,7 +214,7 @@ def custom_function(input_args: list): value={value} onChange={handleSelectFromUpstreamChange} > - {options.map(option => ( + {upstreamOptions.map(option => ( {option} diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/domino-form.component.tsx b/frontend/src/pages/private/workflows/workflows-editor/components/domino-form.component.tsx index e33881c8..861cf981 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/components/domino-form.component.tsx +++ b/frontend/src/pages/private/workflows/workflows-editor/components/domino-form.component.tsx @@ -5,12 +5,13 @@ import DominoFormItem from './domino-form-item.component'; type initialDataType = Record; interface DominoFormProps { + formId: string; schema: any; initialData: initialDataType; onChange: ({ errors, data }: { errors?: any, data: any }) => void; } -const DominoForm: React.FC = ({ schema, initialData, onChange }) => { +const DominoForm: React.FC = ({ formId, schema, initialData, onChange }) => { const [formData, setFormData] = useState(initialData); const handleChange = (key: string) => (value: any) => { @@ -30,6 +31,7 @@ const DominoForm: React.FC = ({ schema, initialData, onChange } {Object.keys(schema.properties).map(key => (
{ const handleOnChange = useCallback(async ({ errors, data }: { errors?: any, data: any }) => { // On change update form data in forage try { - console.log('handleOnChange') var upstreamMap = await getForageUpstreamMap() const nameKeyUpstreamArgsMap = await getNameKeyUpstreamArgsMap() var upstreamMapFormInfo = (formId in upstreamMap) ? upstreamMap[formId] : {} @@ -339,6 +338,7 @@ const SidebarForm = (props: ISidebarFormProps) => { Date: Tue, 30 May 2023 18:15:06 -0300 Subject: [PATCH 033/328] keeping dropdown states --- .../components/domino-form-item.component.tsx | 121 +++++++++++++----- .../components/domino-form.component.tsx | 2 +- 2 files changed, 92 insertions(+), 31 deletions(-) diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item.component.tsx b/frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item.component.tsx index a2f7b73e..11fe13d5 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item.component.tsx +++ b/frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item.component.tsx @@ -1,4 +1,4 @@ -import React, { useState, useCallback } from 'react'; +import React, { useState, useCallback, useEffect } from 'react'; import { TextField, Select, @@ -19,7 +19,8 @@ import { DateTimePicker } from '@mui/x-date-pickers/DateTimePicker'; import CodeEditor from '@uiw/react-textarea-code-editor'; import { useWorkflowsEditor } from 'context/workflows/workflows-editor.context' import ArrayInputItem from './domino-form-item-array.component'; - +import { toast } from 'react-toastify'; +import { setSchema } from '@jsonforms/core'; interface DominoFormItemProps { formId: string; @@ -44,7 +45,10 @@ const DominoFormItem: React.FC = ({ formId, schema, itemKey } = useWorkflowsEditor() const formFieldType = schema.properties[itemKey].type; + const [upstreamOptions, setUpstreamOptions] = useState([]); + const [upstreamSelectValue, setUpstreamSelectValue] = useState(''); + const [checkedFromUpstream, setCheckedFromUpstream] = useState(() => { if (schema.properties[itemKey]?.from_upstream === "always") { if (schema.properties[itemKey].type === 'array') { @@ -102,24 +106,20 @@ def custom_function(input_args: list): } // Handle input change - const handleInputChange = (event: React.ChangeEvent) => { - console.log('handleInputChange') + const handleInputChange = useCallback((event: React.ChangeEvent) => { onChange(event.target.value); - }; + }, [onChange]); - const handleSelectChange = (event: SelectChangeEvent) => { - console.log('handleSelectChange') + const handleSelectChange = useCallback((event: SelectChangeEvent) => { onChange(event.target.value as string); - }; + }, [onChange]); // FomrUpstream logic - const handleCheckboxFromUpstreamChange = useCallback(async(event: React.ChangeEvent) => { + const handleCheckboxFromUpstreamChange = useCallback(async(checked: boolean) => { // itemKey = form key to be updated (input_arg for example) // formId has the nodeId to update the possible upstreams enums from edges connections - setCheckedFromUpstream(event.target.checked); + setCheckedFromUpstream(checked); - var auxSchema = JSON.parse(JSON.stringify(schema)) - var formKeys = Object.keys(schema.properties) const edges = await fetchForageWorkflowEdges() var auxCheckboxState: any = await getForageCheckboxStates() @@ -127,10 +127,10 @@ def custom_function(input_args: list): auxCheckboxState = {} } if (formId in auxCheckboxState) { - auxCheckboxState[formId][itemKey] = event.target.checked + auxCheckboxState[formId][itemKey] = checked } else { auxCheckboxState[formId] = { - [itemKey]: event.target.checked + [itemKey]: checked } } await setForageCheckboxStates(auxCheckboxState) @@ -160,12 +160,11 @@ def custom_function(input_args: list): const upstreamOptions: string[] = [] for (var upstreamId of upstreamsIds){parseInt(upstreamId.split('_')[0]) const upstreamOperatorId = parseInt(upstreamId.split('_')[0]) - if (event.target.checked) { + if (checked) { const upstreamOperator = await fetchForagePieceById(upstreamOperatorId) const upstreamOutputSchema = upstreamOperator?.output_schema Object.keys(upstreamOutputSchema?.properties).forEach((key, index) => { const obj = upstreamOutputSchema?.properties[key] - console.log(obj.type) if (obj.type === formFieldType){ // todo add to possible dropdown options var upstreamOptionName = `${upstreamOperator?.name} - ${obj['title']}` @@ -177,17 +176,35 @@ def custom_function(input_args: list): auxNameKeyUpstreamArgsMap[upstreamOptionName] = key } }) + upstreamMap[formId][itemKey] = { + ...upstreamMap[formId][itemKey], + fromUpstream: true, + upstreamId: upstreamId, + upstreamArgument: null + } + }else{ + upstreamMap[formId][itemKey] = { + ...upstreamMap[formId][itemKey], + fromUpstream: false, + upstreamId: upstreamId, + upstreamArgument: null + } } } - console.log('upstreamOptions', upstreamOptions) - console.log('auxNameKeyUpstreamArgsMap', auxNameKeyUpstreamArgsMap) + if (checked && !upstreamOptions.length) { + auxCheckboxState[formId][itemKey] = false + setCheckedFromUpstream(false); + await setForageCheckboxStates(auxCheckboxState) + toast.error('There are no upstream outputs with the same type as the selected field') + return + } + const currentNameKeyUpstreamArgsMap = await getNameKeyUpstreamArgsMap() + setNameKeyUpstreamArgsMap({ ...auxNameKeyUpstreamArgsMap, ...currentNameKeyUpstreamArgsMap }) + setForageUpstreamMap(upstreamMap) setUpstreamOptions(upstreamOptions) - - - + setUpstreamSelectValue(upstreamMap[formId][itemKey].value) },[ formId, - schema, itemKey, fetchForageWorkflowEdges, getForageCheckboxStates, @@ -195,23 +212,67 @@ def custom_function(input_args: list): getForageUpstreamMap, formFieldType, fetchForagePieceById, - + setForageUpstreamMap, + getNameKeyUpstreamArgsMap, + setNameKeyUpstreamArgsMap ]); - const handleSelectFromUpstreamChange = (event: SelectChangeEvent) => { - console.log('handleSelectFromUpstreamChange') - console.log(event.target.value); - }; + + useEffect(() => { + // Load checkboxes states from forage + (async () => { + + var auxCheckboxState: any = await getForageCheckboxStates() + if (!(formId in auxCheckboxState)) { + return + } + const formCheckboxStates = auxCheckboxState[formId] + if (itemKey in formCheckboxStates) { + await handleCheckboxFromUpstreamChange(formCheckboxStates[itemKey]) + }else{ + handleCheckboxFromUpstreamChange(false) + } + + + })() + }, [getForageCheckboxStates, formId, itemKey, getForageUpstreamMap, handleCheckboxFromUpstreamChange]) + + + const handleSelectFromUpstreamChange = useCallback(async(event: SelectChangeEvent) => { + setUpstreamSelectValue(event.target.value as string); + var upstreamMap = await getForageUpstreamMap() + const nameKeyUpstreamArgsMap = await getNameKeyUpstreamArgsMap() + var upstreamMapFormInfo = (formId in upstreamMap) ? upstreamMap[formId] : {} + const fromUpstream = upstreamMapFormInfo[itemKey] ? upstreamMapFormInfo[itemKey].fromUpstream : false + const upstreamId = fromUpstream && upstreamMapFormInfo[itemKey] ? upstreamMapFormInfo[itemKey].upstreamId : null + upstreamMapFormInfo[itemKey] = { + fromUpstream: fromUpstream, + upstreamId: upstreamId, + upstreamArgument: fromUpstream && nameKeyUpstreamArgsMap[event.target.value] ? nameKeyUpstreamArgsMap[event.target.value] : null, + value: (event.target.value === null || event.target.value === undefined) ? null : event.target.value + } + upstreamMap[formId] = upstreamMapFormInfo + await setForageUpstreamMap(upstreamMap) + onChange(event.target.value); + }, [ + itemKey, + getForageUpstreamMap, + getNameKeyUpstreamArgsMap, + formId, + setForageUpstreamMap, + onChange + + ]); let inputElement: JSX.Element; if (checkedFromUpstream) { inputElement = ( - {itemKey} + {itemSchema?.title} + None + Once + Hourly + Daily + Weekly + Monthly + Yearly + + + + + + + + + } + label="Generate Report" + /> + + + + + + + Storage + +
+ + + + Schedule Interval + + + + { + storageFormData.storageSource === 'AWS S3' ? ( + <> + + + + + + + + + ) : null + } + +
+
+ + + ) +} +export default SidebarSettingsForm diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/workflows-editor.component.tsx b/frontend/src/pages/private/workflows/workflows-editor/components/workflows-editor.component.tsx index 157218b5..5b8fbd07 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/components/workflows-editor.component.tsx +++ b/frontend/src/pages/private/workflows/workflows-editor/components/workflows-editor.component.tsx @@ -9,7 +9,7 @@ import { useCallback, useEffect, useState } from 'react' import WorkflowEditorPanelComponent from './workflow-editor-panel.component' import { PermanentDrawerRightWorkflows } from './drawer-menu-component' -import SidebarForm from './sidebar-form.component' +import SidebarSettingsForm from './sidebar-settings-form.component' import { workflowFormSchema, workflowFormUISchema } from 'common/schemas/workflowFormSchema' import { useWorkflowsEditor } from "context/workflows/workflows-editor.context" import { workflowFormName } from "../../../../../constants" @@ -247,7 +247,11 @@ export const WorkflowsEditorComponent = withContext(WorkflowsEditorProvider, () handleClose={() => setMenuOpen(!menuOpen)} /> - + {/* */} +
) From 62fe9ac29da563a58e963de6764b565a45d25772 Mon Sep 17 00:00:00 2001 From: Vinicius Date: Wed, 31 May 2023 15:34:22 -0300 Subject: [PATCH 040/328] storage form --- .../sidebar-settings-form.component.tsx | 113 +++++++++--------- 1 file changed, 57 insertions(+), 56 deletions(-) diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-settings-form.component.tsx b/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-settings-form.component.tsx index 48c80202..87434ee4 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-settings-form.component.tsx +++ b/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-settings-form.component.tsx @@ -18,12 +18,26 @@ import { import { useCallback, useEffect, useState } from 'react' import { useWorkflowsEditor } from 'context/workflows/workflows-editor.context' - interface ISidebarSettingsFormProps { open: boolean, onClose: (event: any) => void } +const defaultConfigData = { + name: '', + scheduleInterval: 'none', + startDate: '', + generateReport: false, +} + +const defaultStorageData = { + storageSource: 'None', + baseFolder: '', + bucket: '' +} +const formId = 'workflowForm' + + const SidebarSettingsForm = (props: ISidebarSettingsFormProps) => { const { open, @@ -35,42 +49,15 @@ const SidebarSettingsForm = (props: ISidebarSettingsFormProps) => { ] : [ "None", "AWS S3" ] - - const formId = 'workflowForm' - - //const [checkboxState, setCheckboxState] = useState({}) - const [formData, setFormData] = useState({ - name: '', - scheduleInterval: 'none', - startDate: '', - generateReport: false, - }); - const [storageFormData, setStorageFormData] = useState({ - storageSource: 'None', - baseFolder: '', - bucket: '' - }); + const [configFormData, setConfigFormData] = useState(defaultConfigData); + const [storageFormData, setStorageFormData] = useState(defaultStorageData); - const [containerResourcesFormData, setContainerResourcesFormData] = useState({}) - const { setFormsForageData, fetchForageDataById, } = useWorkflowsEditor() - // const handleOnChangeStorage = useCallback(async ({ errors, data }: { errors?: any, data: any }) => { const handleOnChangeStorage = useCallback(async (event: any) => { - /* - - // On change update node form data in forage - // The storage access mode key is inside the node form data in the `storage` key - { - ...nodeData, - storage: { - storageAccessMode: 'Enum(Read, Write, ReadWrite)' - } - } - */ const { name, value, type, checked } = event.target; const fieldValue = type === 'checkbox' ? checked : value; @@ -79,6 +66,8 @@ const SidebarSettingsForm = (props: ISidebarSettingsFormProps) => { [name]: fieldValue, } + console.log('storageFormData', storageFormData) + const currentData = await fetchForageDataById(formId) const outputData = { ...currentData, @@ -87,34 +76,46 @@ const SidebarSettingsForm = (props: ISidebarSettingsFormProps) => { await setFormsForageData(formId, outputData) setStorageFormData(newStorageFormData); - }, [fetchForageDataById, setFormsForageData, formId, storageFormData]) - - const handleOnChangeContainerResources = useCallback(async ({ errors, data }: { errors?: any, data: any }) => { - const currentData = await fetchForageDataById(formId) - const outputData = { - ...currentData, - containerResources: data - } - await setFormsForageData(formId, outputData) - setContainerResourcesFormData(data) - }, [formId, fetchForageDataById, setFormsForageData]) + }, [fetchForageDataById, setFormsForageData, storageFormData]) const handleChangeConfig = useCallback(async (event: any) => { const { name, value, type, checked } = event.target; const fieldValue = type === 'checkbox' ? checked : value; - setFormData((prevFormData) => ({ - ...prevFormData, + const newFormData = { + ...configFormData, [name]: fieldValue, - })); - - }, []) + } - // useEffect(()=> { - // console.log('formData', formData) - // }, [formData]) + console.log('newFormData', newFormData) - //console.log('storageFormData', storageFormData) + const currentData = await fetchForageDataById(formId) + const outputData = { + ...currentData, + config: newFormData + } + await setFormsForageData(formId, outputData) + setConfigFormData(newFormData); + + }, [configFormData, fetchForageDataById, setFormsForageData]) + + // On load fetch data from forage and set it to the form data + // If data is not present then set default data to the forage + useEffect(() => { + const fetchData = async () => { + const data = await fetchForageDataById(formId) + if (data) { + setConfigFormData(data.config) + setStorageFormData(data.storage) + }else{ + await setFormsForageData(formId, { + config: defaultConfigData, + storage: defaultStorageData, + }) + } + } + fetchData() + }) return ( { { Schedule Interval From b80b6e7e17383fa8403df6e08cb17c404e94a419 Mon Sep 17 00:00:00 2001 From: Vinicius Date: Wed, 31 May 2023 16:23:09 -0300 Subject: [PATCH 041/328] validate workflow --- .../sidebar-settings-form.component.tsx | 5 ----- .../components/workflows-editor.component.tsx | 20 ++++++++++--------- 2 files changed, 11 insertions(+), 14 deletions(-) diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-settings-form.component.tsx b/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-settings-form.component.tsx index 87434ee4..64f47659 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-settings-form.component.tsx +++ b/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-settings-form.component.tsx @@ -1,4 +1,3 @@ -import { createAjv } from '@jsonforms/core' import { Drawer, Grid, @@ -10,8 +9,6 @@ import { Select, MenuItem, Checkbox, - Button, - } from '@mui/material' //import { materialCells, materialRenderers } from '@jsonforms/material-renderers' //import { JsonForms } from '@jsonforms/react' @@ -87,8 +84,6 @@ const SidebarSettingsForm = (props: ISidebarSettingsFormProps) => { [name]: fieldValue, } - console.log('newFormData', newFormData) - const currentData = await fetchForageDataById(formId) const outputData = { ...currentData, diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/workflows-editor.component.tsx b/frontend/src/pages/private/workflows/workflows-editor/components/workflows-editor.component.tsx index 5b8fbd07..cdc8bd7b 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/components/workflows-editor.component.tsx +++ b/frontend/src/pages/private/workflows/workflows-editor/components/workflows-editor.component.tsx @@ -44,18 +44,20 @@ export const WorkflowsEditorComponent = withContext(WorkflowsEditorProvider, () const validateWorkflowForms = useCallback(async (payload: any) => { const workflowData = payload.workflow - const workflowSchema: any = workflowFormSchema.properties.config - const workflowSchemaRequireds = workflowSchema.required + const workflowRequiredFields: any = { + "name": "Name", + "scheduleInterval": "Schedule Interval", + "startDate": "Start Date", + } if (!workflowData || workflowData === undefined) { - throw new Error('Please fill in the workflow settings.') + throw new Error('Workflow settings are missing.') } - // iterate over config keys and validate workflow data - for (const key in workflowSchema.properties) { - if (workflowSchemaRequireds.includes(key)) { - if (!(key in workflowData) || !workflowData[key]) { - const title = workflowSchema.properties[key].title - throw new Error(`Please the ${title} field in Settings.`) + + for (const fieldKey in workflowData) { + if (fieldKey in workflowRequiredFields) { + if (!(fieldKey in workflowData) || !workflowData[fieldKey]) { + throw new Error(`Please fill the ${workflowRequiredFields[fieldKey]} field in Settings.`) } } } From 5636464fad21ba888de6726174478d2ef5057ab0 Mon Sep 17 00:00:00 2001 From: Vinicius Date: Wed, 31 May 2023 16:27:53 -0300 Subject: [PATCH 042/328] alias --- rest/schemas/requests/workflow.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/rest/schemas/requests/workflow.py b/rest/schemas/requests/workflow.py index 1722f2a0..b8a5a4b2 100644 --- a/rest/schemas/requests/workflow.py +++ b/rest/schemas/requests/workflow.py @@ -37,11 +37,11 @@ class WorkflowBaseSettings(BaseModel): example="workflow_name", regex=r"^[\w]*$", ) - start_date: str - end_date: Optional[str] # TODO add end date to UI? - schedule_interval: ScheduleIntervalType + start_date: str = Field(alias="startDate") + end_date: Optional[str] = Field(alias='endDate')# TODO add end date to UI? + schedule_interval: ScheduleIntervalType = Field(alias="scheduleInterval") catchup: Optional[bool] = False # TODO add catchup to UI? - generate_report: Optional[bool] = False + generate_report: Optional[bool] = Field(alias="generateReport", default=False) # TODO add generate report to UI? description: Optional[str] # TODO add description to UI? From e70cf47ad3e4c3fe4b0d7bfd81862630e6fc7bca Mon Sep 17 00:00:00 2001 From: Vinicius Date: Wed, 31 May 2023 18:11:12 -0300 Subject: [PATCH 043/328] small fix --- .../components/sidebar-settings-form.component.tsx | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-settings-form.component.tsx b/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-settings-form.component.tsx index 64f47659..15327334 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-settings-form.component.tsx +++ b/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-settings-form.component.tsx @@ -63,8 +63,6 @@ const SidebarSettingsForm = (props: ISidebarSettingsFormProps) => { [name]: fieldValue, } - console.log('storageFormData', storageFormData) - const currentData = await fetchForageDataById(formId) const outputData = { ...currentData, @@ -99,7 +97,7 @@ const SidebarSettingsForm = (props: ISidebarSettingsFormProps) => { useEffect(() => { const fetchData = async () => { const data = await fetchForageDataById(formId) - if (data) { + if (Object.keys(data).length > 0) { setConfigFormData(data.config) setStorageFormData(data.storage) }else{ @@ -110,7 +108,7 @@ const SidebarSettingsForm = (props: ISidebarSettingsFormProps) => { } } fetchData() - }) + }, [fetchForageDataById, setFormsForageData]) return ( Date: Thu, 1 Jun 2023 14:40:58 +0200 Subject: [PATCH 044/328] start and end datetimes --- .../sidebar-settings-form.component.tsx | 98 ++++++++++++------- 1 file changed, 65 insertions(+), 33 deletions(-) diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-settings-form.component.tsx b/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-settings-form.component.tsx index 15327334..f6ffd357 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-settings-form.component.tsx +++ b/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-settings-form.component.tsx @@ -1,7 +1,7 @@ -import { - Drawer, - Grid, - Typography, +import { + Drawer, + Grid, + Typography, FormControl, TextField, InputLabel, @@ -9,11 +9,16 @@ import { Select, MenuItem, Checkbox, - } from '@mui/material' +} from '@mui/material' +import { DemoContainer } from '@mui/x-date-pickers/internals/demo'; +import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; +import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; +import { DateTimePicker } from '@mui/x-date-pickers/DateTimePicker'; //import { materialCells, materialRenderers } from '@jsonforms/material-renderers' //import { JsonForms } from '@jsonforms/react' import { useCallback, useEffect, useState } from 'react' import { useWorkflowsEditor } from 'context/workflows/workflows-editor.context' +import { set } from 'react-hook-form'; interface ISidebarSettingsFormProps { open: boolean, @@ -24,7 +29,8 @@ const defaultConfigData = { name: '', scheduleInterval: 'none', startDate: '', - generateReport: false, + selectEndDateTime: 'never', + endDate: '', } const defaultStorageData = { @@ -48,7 +54,7 @@ const SidebarSettingsForm = (props: ISidebarSettingsFormProps) => { ] const [configFormData, setConfigFormData] = useState(defaultConfigData); const [storageFormData, setStorageFormData] = useState(defaultStorageData); - + const [isEndDateTimeDisabled, setIsEndDateTimeDisabled] = useState(true); const { setFormsForageData, fetchForageDataById, @@ -68,9 +74,9 @@ const SidebarSettingsForm = (props: ISidebarSettingsFormProps) => { ...currentData, storage: newStorageFormData } - await setFormsForageData(formId, outputData) + await setFormsForageData(formId, outputData); setStorageFormData(newStorageFormData); - + }, [fetchForageDataById, setFormsForageData, storageFormData]) const handleChangeConfig = useCallback(async (event: any) => { @@ -82,6 +88,12 @@ const SidebarSettingsForm = (props: ISidebarSettingsFormProps) => { [name]: fieldValue, } + // changes the disable state of the selectEndDateTime + if (name === 'selectEndDateTime') { + setIsEndDateTimeDisabled(value === 'never') + newFormData.endDate = '' + } + const currentData = await fetchForageDataById(formId) const outputData = { ...currentData, @@ -100,7 +112,7 @@ const SidebarSettingsForm = (props: ISidebarSettingsFormProps) => { if (Object.keys(data).length > 0) { setConfigFormData(data.config) setStorageFormData(data.storage) - }else{ + } else { await setFormsForageData(formId, { config: defaultConfigData, storage: defaultStorageData, @@ -155,29 +167,49 @@ const SidebarSettingsForm = (props: ISidebarSettingsFormProps) => {
- - - - + + - } - label="Generate Report" - /> + + + + + + + End Date/Time + + + + + + + + + + @@ -186,7 +218,7 @@ const SidebarSettingsForm = (props: ISidebarSettingsFormProps) => { Storage -
+ @@ -199,7 +231,7 @@ const SidebarSettingsForm = (props: ISidebarSettingsFormProps) => { > { storageSourceOptions.map((option: string, index: number) => ( - {option} + {option} )) } From f5f42e4217c4652311d38fe47d42ae1dbf425369 Mon Sep 17 00:00:00 2001 From: luiz Date: Thu, 1 Jun 2023 15:28:31 +0200 Subject: [PATCH 045/328] start and end datetime --- .../sidebar-settings-form.component.tsx | 26 ++++++++++++------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-settings-form.component.tsx b/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-settings-form.component.tsx index f6ffd357..abfe57ab 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-settings-form.component.tsx +++ b/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-settings-form.component.tsx @@ -28,9 +28,9 @@ interface ISidebarSettingsFormProps { const defaultConfigData = { name: '', scheduleInterval: 'none', - startDate: '', + startDateTime: '', selectEndDateTime: 'never', - endDate: '', + endDateTime: '', } const defaultStorageData = { @@ -79,9 +79,18 @@ const SidebarSettingsForm = (props: ISidebarSettingsFormProps) => { }, [fetchForageDataById, setFormsForageData, storageFormData]) + // TODO - not working for datetime pickers const handleChangeConfig = useCallback(async (event: any) => { - const { name, value, type, checked } = event.target; - const fieldValue = type === 'checkbox' ? checked : value; + let name = event?.target?.name; + let fieldValue = event?.target?.value; + if (event.target) { + const { name, value, type, checked } = event.target; + fieldValue = type === 'checkbox' ? checked : value; + } else { + const newDate = event; + fieldValue = new Date(newDate).toISOString(); + name = 'startDateTime'; + } const newFormData = { ...configFormData, @@ -90,8 +99,8 @@ const SidebarSettingsForm = (props: ISidebarSettingsFormProps) => { // changes the disable state of the selectEndDateTime if (name === 'selectEndDateTime') { - setIsEndDateTimeDisabled(value === 'never') - newFormData.endDate = '' + setIsEndDateTimeDisabled(fieldValue === 'never') + newFormData.endDateTime = '' } const currentData = await fetchForageDataById(formId) @@ -171,7 +180,7 @@ const SidebarSettingsForm = (props: ISidebarSettingsFormProps) => { { handleChangeConfig(event, "scheduleInterval")} required > None @@ -194,7 +193,7 @@ const SidebarSettingsForm = (props: ISidebarSettingsFormProps) => { handleChangeConfig(event, "startDateTime")} ampm={false} format='DD/MM/YYYY HH:mm' sx={{ width: "100%" }} @@ -209,7 +208,7 @@ const SidebarSettingsForm = (props: ISidebarSettingsFormProps) => { + None + Read + Read/Write + + + + + : null } diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/workflow-editor-panel.component.tsx b/frontend/src/pages/private/workflows/workflows-editor/components/workflow-editor-panel.component.tsx index 4eb836c3..00173526 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/components/workflow-editor-panel.component.tsx +++ b/frontend/src/pages/private/workflows/workflows-editor/components/workflow-editor-panel.component.tsx @@ -149,7 +149,7 @@ const WorkflowEditorPanelComponent = () => { upstreamMap[newNode.id] = upstreamMapFormInfo await setForageUpstreamMap(upstreamMap) defaultData['storage'] = { - "storageAccessMode": 'Read/Write' + "storageAccessMode": 'None' } defaultData['containerResources'] = containerResourcesDefaultData // Set default data for the node form - used in json-forms From 51d92bfc70f92c39c04e71761f1ccace76ae0ae5 Mon Sep 17 00:00:00 2001 From: luiz Date: Fri, 2 Jun 2023 11:54:41 +0200 Subject: [PATCH 053/328] comments and formatting --- .../components/domino-form-item.component.tsx | 12 +++-- .../components/sidebar-form.component.tsx | 44 ++++++++----------- 2 files changed, 23 insertions(+), 33 deletions(-) diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item.component.tsx b/frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item.component.tsx index 793fa135..bfe64b0b 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item.component.tsx +++ b/frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item.component.tsx @@ -43,7 +43,6 @@ const DominoFormItem: React.FC = ({ formId, schema, itemKey setNameKeyUpstreamArgsMap, getNameKeyUpstreamArgsMap, } = useWorkflowsEditor(); - const formFieldType = schema.properties[itemKey].type; const [formLabelUpstreamIdMap, setFormLabelUpstreamIdMap] = useState>({}); const [upstreamOptions, setUpstreamOptions] = useState([]); @@ -59,9 +58,8 @@ const DominoFormItem: React.FC = ({ formId, schema, itemKey } }); - + // The schema for this item let itemSchema: any = schema.properties[itemKey]; - if (value === undefined) { value = itemSchema.default; } @@ -85,6 +83,7 @@ const DominoFormItem: React.FC = ({ formId, schema, itemKey } } + // Handle input change const handleInputChange = useCallback((event: React.ChangeEvent) => { onChange(event.target.value); }, [onChange]); @@ -93,7 +92,7 @@ const DominoFormItem: React.FC = ({ formId, schema, itemKey onChange(event.target.value as string); }, [onChange]); - + // From upstream checkbox callback const handleCheckboxFromUpstreamChange = useCallback(async (checked: boolean) => { setCheckedFromUpstream(checked); @@ -229,7 +228,7 @@ const DominoFormItem: React.FC = ({ formId, schema, itemKey })() }, [getForageCheckboxStates, formId, itemKey, getForageUpstreamMap, handleCheckboxFromUpstreamChange]) - + // Select fromUpstream source const handleSelectFromUpstreamChange = useCallback(async (event: SelectChangeEvent) => { setUpstreamSelectValue(event.target.value as string); var upstreamMap = await getForageUpstreamMap() @@ -258,9 +257,8 @@ const DominoFormItem: React.FC = ({ formId, schema, itemKey ]); + // Set input element based on type let inputElement: JSX.Element; - - if (checkedFromUpstream) { inputElement = ( diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component.tsx b/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component.tsx index 3d01b457..ff4f5679 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component.tsx +++ b/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component.tsx @@ -1,27 +1,25 @@ -import { createAjv } from '@jsonforms/core' -import { +import { useCallback, useEffect, useState } from 'react' +// import { createAjv } from '@jsonforms/core' +import { Divider, Drawer, - Grid, + Grid, Typography, MenuItem, Select, FormControl, InputLabel - } from '@mui/material' -//import { materialCells, materialRenderers } from '@jsonforms/material-renderers' -//import { JsonForms } from '@jsonforms/react' -import { useCallback, useEffect, useState } from 'react' +} from '@mui/material' + import { useWorkflowsEditor } from 'context/workflows/workflows-editor.context' import { extractDefaultValues } from 'utils' import { operatorStorageSchema } from 'common/schemas/storageSchemas' -import { containerResourcesSchema } from 'common/schemas/containerResourcesSchemas' import { workflowFormSchema } from 'common/schemas/workflowFormSchema' - +import { containerResourcesSchema } from 'common/schemas/containerResourcesSchemas' import DominoForm from './domino-form.component' -const handleDefaultsAjv = createAjv({ useDefaults: true }) +// const handleDefaultsAjv = createAjv({ useDefaults: true }) interface ISidebarFormProps { formSchema: any, @@ -42,14 +40,12 @@ const SidebarForm = (props: ISidebarFormProps) => { title, isPieceForm = true } = props - //const [checkboxState, setCheckboxState] = useState({}) const [formData, setFormData] = useState({}) const [storageFormData, setStorageFormData] = useState('None') const [containerResourcesFormData, setContainerResourcesFormData] = useState({}) const [formWidthSpace, setFormWidthSpace] = useState(12) const [formJsonSchema, setFormJsonSchema] = useState({ ...formSchema }) - const { setFormsForageData, fetchForageDataById, @@ -66,14 +62,12 @@ const SidebarForm = (props: ISidebarFormProps) => { setFormWidthSpace(isPieceForm ? 12 : 12) }, [isPieceForm]) - + // On change update form data in forage const handleOnChange = useCallback(async ({ errors, data }: { errors?: any, data: any }) => { - // On change update form data in forage try { var upstreamMap = await getForageUpstreamMap() const nameKeyUpstreamArgsMap = await getNameKeyUpstreamArgsMap() var upstreamMapFormInfo = (formId in upstreamMap) ? upstreamMap[formId] : {} - for (const key in data) { const fromUpstream = upstreamMapFormInfo[key] ? upstreamMapFormInfo[key].fromUpstream : false const upstreamId = fromUpstream && upstreamMapFormInfo[key] ? upstreamMapFormInfo[key].upstreamId : null @@ -87,7 +81,6 @@ const SidebarForm = (props: ISidebarFormProps) => { } } upstreamMap[formId] = upstreamMapFormInfo - await setFormsForageData(formId, data) await setForageUpstreamMap(upstreamMap) } catch (err) { @@ -133,13 +126,11 @@ const SidebarForm = (props: ISidebarFormProps) => { // setContainerResourcesFormData(data) }, [formId, fetchForageDataById, setFormsForageData]) - - + // When opened fetch forage data and update forms data useEffect(() => { - // When opened fetch forage data and update forms data const fetchForage = async () => { const forageData = await fetchForageDataById(formId) - + if (!forageData) { const defaultData = extractDefaultValues(formJsonSchema) handleOnChange({ data: defaultData }) @@ -168,7 +159,7 @@ const SidebarForm = (props: ISidebarFormProps) => { if (open) { fetchForage() } }, [formId, formJsonSchema, open, fetchForageDataById, setFormsForageData, handleOnChange, handleOnChangeStorage, isPieceForm, handleOnChangeContainerResources]) - + return ( { - + + - - : null + : null }
) -} -export default SidebarForm +}; + +export default SidebarForm; \ No newline at end of file From 95c7e07b7f3a3c504812b5fda3a7645adb87a0c5 Mon Sep 17 00:00:00 2001 From: Vinicius Date: Fri, 2 Jun 2023 06:56:32 -0300 Subject: [PATCH 054/328] starting storage forms --- .../components/sidebar-form.component.tsx | 129 ++++++++++++++++-- 1 file changed, 118 insertions(+), 11 deletions(-) diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component.tsx b/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component.tsx index 3d01b457..96024bb8 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component.tsx +++ b/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component.tsx @@ -7,7 +7,11 @@ import { MenuItem, Select, FormControl, - InputLabel + InputLabel, + TextField, + FormControlLabel, + Checkbox + } from '@mui/material' //import { materialCells, materialRenderers } from '@jsonforms/material-renderers' //import { JsonForms } from '@jsonforms/react' @@ -33,6 +37,18 @@ interface ISidebarFormProps { isPieceForm?: boolean, } +const defaultContainerResources = { + "useGpu": false, + "memory": { + "min": 128, + "max": 128 + }, + "cpu": { + "min": 100, + "max": 100 + } +} + const SidebarForm = (props: ISidebarFormProps) => { const { formSchema, @@ -46,7 +62,7 @@ const SidebarForm = (props: ISidebarFormProps) => { //const [checkboxState, setCheckboxState] = useState({}) const [formData, setFormData] = useState({}) const [storageFormData, setStorageFormData] = useState('None') - const [containerResourcesFormData, setContainerResourcesFormData] = useState({}) + const [containerResourcesFormData, setContainerResourcesFormData] = useState(defaultContainerResources) const [formWidthSpace, setFormWidthSpace] = useState(12) const [formJsonSchema, setFormJsonSchema] = useState({ ...formSchema }) @@ -123,12 +139,39 @@ const SidebarForm = (props: ISidebarFormProps) => { }, [fetchForageDataById, setFormsForageData, formId]) - const handleOnChangeContainerResources = useCallback(async ({ errors, data }: { errors?: any, data: any }) => { - // const currentData = await fetchForageDataById(formId) - // const outputData = { - // ...currentData, - // containerResources: data - // } + const handleOnChangeContainerResources = useCallback(async (event: any) => { + if (!event?.target) { + return + } + const { name, value, type, checked } = event.target; + console.log('value', value) + console.log('type', type) + console.log(typeof value) + var newContainerResourcesData = {} + if (name.includes('.')){ + const firstLevelKey = name.split('.')[0] + const secondLevelKey = name.split('.')[1] + newContainerResourcesData = { + ...containerResourcesFormData, + [firstLevelKey]: { + ...containerResourcesFormData[firstLevelKey], + [secondLevelKey]: type === 'checkbox' ? checked : value + } + } + }else{ + const firstLevelKey = name + newContainerResourcesData = { + ...containerResourcesFormData, + [firstLevelKey]: type === 'checkbox' ? checked : value + } + } + + const currentData = await fetchForageDataById(formId) + const outputData = { + ...currentData, + containerResources: newContainerResourcesData + } + console.log('outputData', outputData) // await setFormsForageData(formId, outputData) // setContainerResourcesFormData(data) }, [formId, fetchForageDataById, setFormsForageData]) @@ -209,7 +252,10 @@ const SidebarForm = (props: ISidebarFormProps) => { /> - + + + Container Resources + Storage Access Mode @@ -225,8 +271,69 @@ const SidebarForm = (props: ISidebarFormProps) => { - - + + + + + Container Resources + + + + + + + + + + + + + + + + } + label="Use GPU" + /> + + : null From 73e03b5582cbbf94a6b163e0f7c1c0eab4ab1769 Mon Sep 17 00:00:00 2001 From: luiz Date: Fri, 2 Jun 2023 12:14:18 +0200 Subject: [PATCH 055/328] fix time and datetime --- .../components/domino-form-item.component.tsx | 30 ++++++++++++++----- 1 file changed, 23 insertions(+), 7 deletions(-) diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item.component.tsx b/frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item.component.tsx index bfe64b0b..1e6bb3c3 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item.component.tsx +++ b/frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item.component.tsx @@ -17,7 +17,7 @@ import { DatePicker } from '@mui/x-date-pickers/DatePicker'; import { TimePicker } from '@mui/x-date-pickers/TimePicker'; import { DateTimePicker } from '@mui/x-date-pickers/DateTimePicker'; import { toast } from 'react-toastify'; - +import dayjs from 'dayjs'; import { useWorkflowsEditor } from 'context/workflows/workflows-editor.context' import ArrayInputItem from './domino-form-item-array.component'; @@ -60,6 +60,8 @@ const DominoFormItem: React.FC = ({ formId, schema, itemKey // The schema for this item let itemSchema: any = schema.properties[itemKey]; + + // The value for this item if (value === undefined) { value = itemSchema.default; } @@ -84,8 +86,16 @@ const DominoFormItem: React.FC = ({ formId, schema, itemKey } // Handle input change - const handleInputChange = useCallback((event: React.ChangeEvent) => { - onChange(event.target.value); + const handleInputChange = useCallback((event: any, source: string) => { + let fieldValue = event?.target?.value || ""; + if (source === 'datePicker' || source === 'timePicker' || source === 'dateTimePicker') { + const newDate = event; + fieldValue = new Date(newDate).toISOString(); + } else { + const { name, value, type, checked } = event.target; + fieldValue = type === 'checkbox' ? checked : value; + } + onChange(fieldValue); }, [onChange]); const handleSelectChange = useCallback((event: SelectChangeEvent) => { @@ -298,7 +308,7 @@ const DominoFormItem: React.FC = ({ formId, schema, itemKey inputElement = handleInputChange(event, "boolean")} />} labelPlacement="start" label={itemSchema.title} @@ -310,7 +320,7 @@ const DominoFormItem: React.FC = ({ formId, schema, itemKey type="number" label={itemSchema.title} value={value} - onChange={handleInputChange} + onChange={(event) => handleInputChange(event, "number")} />; } else if (itemSchema.type === 'integer') { inputElement = = ({ formId, schema, itemKey type="number" label={itemSchema.title} value={value} - onChange={handleInputChange} + onChange={(event) => handleInputChange(event, "integer")} />; } else if (itemSchema.type === 'array') { inputElement = = ({ formId, schema, itemKey views={['day', 'month', 'year']} format="DD/MM/YYYY" sx={{ width: "100%" }} + value={dayjs(value)} + onChange={(event) => handleInputChange(event, "datePicker")} /> @@ -349,6 +361,8 @@ const DominoFormItem: React.FC = ({ formId, schema, itemKey label={itemSchema.title} format='HH:mm' sx={{ width: "100%" }} + value={dayjs(value)} + onChange={(event) => handleInputChange(event, "timePicker")} /> @@ -362,6 +376,8 @@ const DominoFormItem: React.FC = ({ formId, schema, itemKey label={itemSchema.title} format='DD/MM/YYYY HH:mm' sx={{ width: "100%" }} + value={dayjs(value)} + onChange={(event) => handleInputChange(event, "dateTimePicker")} /> @@ -380,7 +396,7 @@ const DominoFormItem: React.FC = ({ formId, schema, itemKey variant="outlined" label={itemSchema.title} value={value} - onChange={handleInputChange} + onChange={(event) => handleInputChange(event, "string")} /> ); } else { From c36c32a029b60de013af0fe2d15a6a8d031ba956 Mon Sep 17 00:00:00 2001 From: Vinicius Date: Fri, 2 Jun 2023 07:19:01 -0300 Subject: [PATCH 056/328] partial changes --- .../components/sidebar-form.component.tsx | 57 +++++++++++++++++-- 1 file changed, 51 insertions(+), 6 deletions(-) diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component.tsx b/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component.tsx index 51f32220..45f79613 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component.tsx +++ b/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component.tsx @@ -19,6 +19,7 @@ import { operatorStorageSchema } from 'common/schemas/storageSchemas' import { workflowFormSchema } from 'common/schemas/workflowFormSchema' import { containerResourcesSchema } from 'common/schemas/containerResourcesSchemas' import DominoForm from './domino-form.component' +import { toast } from 'react-toastify' // const handleDefaultsAjv = createAjv({ useDefaults: true }) @@ -33,6 +34,23 @@ interface ISidebarFormProps { isPieceForm?: boolean, } +const minAcceptedMemory = 128 +const minAcceptedCpu = 100 +const maxAcceptedMemory = 128000 +const maxAcceptedCpu = 100000 + +const storageValidationValues: any = { + "memory": { + "min": minAcceptedMemory, + "max": maxAcceptedMemory + }, + "cpu": { + "min": minAcceptedCpu, + "max": maxAcceptedCpu + } +} + + const defaultContainerResources = { "useGpu": false, "memory": { @@ -45,6 +63,7 @@ const defaultContainerResources = { } } + const SidebarForm = (props: ISidebarFormProps) => { const { formSchema, @@ -58,6 +77,7 @@ const SidebarForm = (props: ISidebarFormProps) => { const [formData, setFormData] = useState({}) const [storageFormData, setStorageFormData] = useState('None') const [containerResourcesFormData, setContainerResourcesFormData] = useState(defaultContainerResources) + const [storageFieldErrors, setStorageFieldErrors] = useState({}); const [formWidthSpace, setFormWidthSpace] = useState(12) const [formJsonSchema, setFormJsonSchema] = useState({ ...formSchema }) const { @@ -135,18 +155,27 @@ const SidebarForm = (props: ISidebarFormProps) => { return } const { name, value, type, checked } = event.target; - console.log('value', value) - console.log('type', type) - console.log(typeof value) + + var parsedValue = value; + if (type === 'number') { + parsedValue = parseInt(value); // Convert the value to a float or use parseInt() for an integer + } var newContainerResourcesData = {} if (name.includes('.')){ const firstLevelKey = name.split('.')[0] const secondLevelKey = name.split('.')[1] + + const validationValue: any = storageValidationValues[firstLevelKey] + + if (parsedValue < validationValue.min || parsedValue > validationValue.max) { + toast.error(`The value must be between ${validationValue.min} and ${validationValue.max}`) + } + newContainerResourcesData = { ...containerResourcesFormData, [firstLevelKey]: { ...containerResourcesFormData[firstLevelKey], - [secondLevelKey]: type === 'checkbox' ? checked : value + [secondLevelKey]: type === 'checkbox' ? checked : parsedValue } } }else{ @@ -162,9 +191,9 @@ const SidebarForm = (props: ISidebarFormProps) => { ...currentData, containerResources: newContainerResourcesData } - console.log('outputData', outputData) + //console.log('outputData', outputData) // await setFormsForageData(formId, outputData) - // setContainerResourcesFormData(data) + setContainerResourcesFormData(newContainerResourcesData) }, [formId, fetchForageDataById, setFormsForageData]) // When opened fetch forage data and update forms data @@ -275,6 +304,10 @@ const SidebarForm = (props: ISidebarFormProps) => { onChange={handleOnChangeContainerResources} required fullWidth + inputProps={{ + min: minAcceptedCpu, + max: maxAcceptedCpu + }} /> @@ -286,6 +319,10 @@ const SidebarForm = (props: ISidebarFormProps) => { onChange={handleOnChangeContainerResources} required fullWidth + inputProps={{ + min: minAcceptedCpu, + max: maxAcceptedCpu + }} /> @@ -297,6 +334,10 @@ const SidebarForm = (props: ISidebarFormProps) => { onChange={handleOnChangeContainerResources} required fullWidth + inputProps={{ + min: minAcceptedMemory, + max: maxAcceptedMemory + }} /> @@ -308,6 +349,10 @@ const SidebarForm = (props: ISidebarFormProps) => { onChange={handleOnChangeContainerResources} required fullWidth + inputProps={{ + min: minAcceptedMemory, + max: maxAcceptedMemory + }} /> From 6ffe54c670e4a34a8a519b2ac90b7a86f02dd55e Mon Sep 17 00:00:00 2001 From: Vinicius Date: Fri, 2 Jun 2023 08:02:12 -0300 Subject: [PATCH 057/328] container resources forms --- .../components/sidebar-form.component.tsx | 103 +++++++++++++----- 1 file changed, 76 insertions(+), 27 deletions(-) diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component.tsx b/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component.tsx index 45f79613..d3b58ed8 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component.tsx +++ b/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component.tsx @@ -34,10 +34,11 @@ interface ISidebarFormProps { isPieceForm?: boolean, } +// TODO check if these values make sense const minAcceptedMemory = 128 const minAcceptedCpu = 100 -const maxAcceptedMemory = 128000 -const maxAcceptedCpu = 100000 +const maxAcceptedMemory = 12800 +const maxAcceptedCpu = 10000 const storageValidationValues: any = { "memory": { @@ -63,6 +64,17 @@ const defaultContainerResources = { } } +const defaultErrorState = { + "memory": { + "min": false, + "max": false + }, + "cpu": { + "min": false, + "max": false + } +} + const SidebarForm = (props: ISidebarFormProps) => { const { @@ -77,7 +89,7 @@ const SidebarForm = (props: ISidebarFormProps) => { const [formData, setFormData] = useState({}) const [storageFormData, setStorageFormData] = useState('None') const [containerResourcesFormData, setContainerResourcesFormData] = useState(defaultContainerResources) - const [storageFieldErrors, setStorageFieldErrors] = useState({}); + const [containerResourcesFieldsErrors, setContainerResourcesFieldsErrors] = useState(defaultErrorState); const [formWidthSpace, setFormWidthSpace] = useState(12) const [formJsonSchema, setFormJsonSchema] = useState({ ...formSchema }) const { @@ -161,6 +173,9 @@ const SidebarForm = (props: ISidebarFormProps) => { parsedValue = parseInt(value); // Convert the value to a float or use parseInt() for an integer } var newContainerResourcesData = {} + var newStorageErrors = { + ...containerResourcesFieldsErrors + } if (name.includes('.')){ const firstLevelKey = name.split('.')[0] const secondLevelKey = name.split('.')[1] @@ -168,7 +183,21 @@ const SidebarForm = (props: ISidebarFormProps) => { const validationValue: any = storageValidationValues[firstLevelKey] if (parsedValue < validationValue.min || parsedValue > validationValue.max) { - toast.error(`The value must be between ${validationValue.min} and ${validationValue.max}`) + newStorageErrors = { + ...containerResourcesFieldsErrors, + [firstLevelKey]: { + ...containerResourcesFieldsErrors[firstLevelKey], + [secondLevelKey]: true + } + } + }else{ + newStorageErrors = { + ...containerResourcesFieldsErrors, + [firstLevelKey]: { + ...containerResourcesFieldsErrors[firstLevelKey], + [secondLevelKey]: false + } + } } newContainerResourcesData = { @@ -185,16 +214,23 @@ const SidebarForm = (props: ISidebarFormProps) => { [firstLevelKey]: type === 'checkbox' ? checked : value } } - + const currentData = await fetchForageDataById(formId) const outputData = { ...currentData, containerResources: newContainerResourcesData } - //console.log('outputData', outputData) - // await setFormsForageData(formId, outputData) + await setFormsForageData(formId, outputData) setContainerResourcesFormData(newContainerResourcesData) - }, [formId, fetchForageDataById, setFormsForageData]) + setContainerResourcesFieldsErrors(newStorageErrors) + }, + [ + formId, + fetchForageDataById, + setFormsForageData, + containerResourcesFieldsErrors, + containerResourcesFormData + ]) // When opened fetch forage data and update forms data useEffect(() => { @@ -204,31 +240,36 @@ const SidebarForm = (props: ISidebarFormProps) => { if (!forageData) { const defaultData = extractDefaultValues(formJsonSchema) handleOnChange({ data: defaultData }) - isPieceForm && handleOnChangeStorage({ data: "None" }) setFormData(defaultData) + return + } + + handleOnChange({ data: forageData }) + // If the form has checkboxes, we need to update the storage data + if (!forageData.storage) { + setStorageFormData("None") + } else{ + setStorageFormData(forageData.storage.storageAccessMode) + } + + if (!forageData.containerResources) { + setContainerResourcesFormData(defaultContainerResources) } else { - handleOnChange({ data: forageData }) - // If the form has checkboxes, we need to update the storage data - if (isPieceForm && !forageData.storage) { - handleOnChangeStorage({ data: "None" }) - setStorageFormData("None") - } else if (isPieceForm) { - handleOnChangeStorage({ data: forageData.storage }) - setStorageFormData(forageData.storage.storageAccessMode) - } - - if (isPieceForm && !forageData.containerResources) { - const defaultContainerResourcesData = extractDefaultValues(containerResourcesSchema) - handleOnChangeContainerResources({ data: defaultContainerResourcesData }) - } else if (isPieceForm) { - handleOnChangeContainerResources({ data: forageData.containerResources }) - } - setFormData(forageData) + setContainerResourcesFormData(forageData.containerResources) } + setFormData(forageData) } if (open) { fetchForage() } - }, [formId, formJsonSchema, open, fetchForageDataById, setFormsForageData, handleOnChange, handleOnChangeStorage, isPieceForm, handleOnChangeContainerResources]) + }, [ + formId, + formJsonSchema, + open, + fetchForageDataById, + setFormsForageData, + handleOnChange, + isPieceForm, + ]) return ( { min: minAcceptedCpu, max: maxAcceptedCpu }} + error={containerResourcesFieldsErrors.cpu.min} + helperText={containerResourcesFieldsErrors.cpu.min ? 'Min CPU must be between ' + minAcceptedCpu + ' and ' + maxAcceptedCpu : ''} /> @@ -323,6 +366,8 @@ const SidebarForm = (props: ISidebarFormProps) => { min: minAcceptedCpu, max: maxAcceptedCpu }} + error={containerResourcesFieldsErrors.cpu.max} + helperText={containerResourcesFieldsErrors.cpu.max ? 'Max CPU must be between ' + minAcceptedCpu + ' and ' + maxAcceptedCpu: ''} /> @@ -338,6 +383,8 @@ const SidebarForm = (props: ISidebarFormProps) => { min: minAcceptedMemory, max: maxAcceptedMemory }} + error={containerResourcesFieldsErrors.memory.min} + helperText={containerResourcesFieldsErrors.memory.min ? 'Min Memory must be between ' + minAcceptedMemory + ' and ' + maxAcceptedMemory: ''} /> @@ -353,6 +400,8 @@ const SidebarForm = (props: ISidebarFormProps) => { min: minAcceptedMemory, max: maxAcceptedMemory }} + error={containerResourcesFieldsErrors.memory.max} + helperText={containerResourcesFieldsErrors.memory.max ? 'Max Memory must be between ' + minAcceptedMemory + ' and ' + maxAcceptedMemory: ''} /> From bb9c4bcc4169d8ce883eafc4adda58af509a2857 Mon Sep 17 00:00:00 2001 From: luiz Date: Fri, 2 Jun 2023 14:01:16 +0200 Subject: [PATCH 058/328] change default storage to read/write --- .../components/sidebar-form.component.tsx | 59 ++++++++++--------- .../workflow-editor-panel.component.tsx | 2 +- 2 files changed, 31 insertions(+), 30 deletions(-) diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component.tsx b/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component.tsx index d3b58ed8..063da958 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component.tsx +++ b/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component.tsx @@ -1,5 +1,4 @@ import { useCallback, useEffect, useState } from 'react' -// import { createAjv } from '@jsonforms/core' import { Divider, Drawer, @@ -12,14 +11,16 @@ import { TextField, FormControlLabel, Checkbox - } from '@mui/material' +} from '@mui/material' + import { useWorkflowsEditor } from 'context/workflows/workflows-editor.context' import { extractDefaultValues } from 'utils' -import { operatorStorageSchema } from 'common/schemas/storageSchemas' -import { workflowFormSchema } from 'common/schemas/workflowFormSchema' -import { containerResourcesSchema } from 'common/schemas/containerResourcesSchemas' import DominoForm from './domino-form.component' -import { toast } from 'react-toastify' +// import { createAjv } from '@jsonforms/core' +// import { operatorStorageSchema } from 'common/schemas/storageSchemas' +// import { workflowFormSchema } from 'common/schemas/workflowFormSchema' +// import { containerResourcesSchema } from 'common/schemas/containerResourcesSchemas' +// import { toast } from 'react-toastify' // const handleDefaultsAjv = createAjv({ useDefaults: true }) @@ -87,7 +88,7 @@ const SidebarForm = (props: ISidebarFormProps) => { } = props //const [checkboxState, setCheckboxState] = useState({}) const [formData, setFormData] = useState({}) - const [storageFormData, setStorageFormData] = useState('None') + const [storageFormData, setStorageFormData] = useState('Read/Write') const [containerResourcesFormData, setContainerResourcesFormData] = useState(defaultContainerResources) const [containerResourcesFieldsErrors, setContainerResourcesFieldsErrors] = useState(defaultErrorState); const [formWidthSpace, setFormWidthSpace] = useState(12) @@ -108,7 +109,7 @@ const SidebarForm = (props: ISidebarFormProps) => { setFormWidthSpace(isPieceForm ? 12 : 12) }, [isPieceForm]) - // On change update form data in forage + // Update form data in forage const handleOnChange = useCallback(async ({ errors, data }: { errors?: any, data: any }) => { try { var upstreamMap = await getForageUpstreamMap() @@ -134,9 +135,9 @@ const SidebarForm = (props: ISidebarFormProps) => { } }, [formId, setFormsForageData, getForageUpstreamMap, setForageUpstreamMap, getNameKeyUpstreamArgsMap]) + // On Change of storage access mode option const handleOnChangeStorage = useCallback(async (event: any) => { /* - // On change update node form data in forage // The storage access mode key is inside the node form data in the `storage` key { @@ -159,9 +160,9 @@ const SidebarForm = (props: ISidebarFormProps) => { } await setFormsForageData(formId, outputData) setStorageFormData(data) - }, [fetchForageDataById, setFormsForageData, formId]) + // On Change of container resources options const handleOnChangeContainerResources = useCallback(async (event: any) => { if (!event?.target) { return @@ -176,12 +177,12 @@ const SidebarForm = (props: ISidebarFormProps) => { var newStorageErrors = { ...containerResourcesFieldsErrors } - if (name.includes('.')){ + if (name.includes('.')) { const firstLevelKey = name.split('.')[0] const secondLevelKey = name.split('.')[1] - + const validationValue: any = storageValidationValues[firstLevelKey] - + if (parsedValue < validationValue.min || parsedValue > validationValue.max) { newStorageErrors = { ...containerResourcesFieldsErrors, @@ -190,7 +191,7 @@ const SidebarForm = (props: ISidebarFormProps) => { [secondLevelKey]: true } } - }else{ + } else { newStorageErrors = { ...containerResourcesFieldsErrors, [firstLevelKey]: { @@ -207,7 +208,7 @@ const SidebarForm = (props: ISidebarFormProps) => { [secondLevelKey]: type === 'checkbox' ? checked : parsedValue } } - }else{ + } else { const firstLevelKey = name newContainerResourcesData = { ...containerResourcesFormData, @@ -223,7 +224,7 @@ const SidebarForm = (props: ISidebarFormProps) => { await setFormsForageData(formId, outputData) setContainerResourcesFormData(newContainerResourcesData) setContainerResourcesFieldsErrors(newStorageErrors) - }, + }, [ formId, fetchForageDataById, @@ -242,16 +243,16 @@ const SidebarForm = (props: ISidebarFormProps) => { handleOnChange({ data: defaultData }) setFormData(defaultData) return - } - + } + handleOnChange({ data: forageData }) // If the form has checkboxes, we need to update the storage data if (!forageData.storage) { - setStorageFormData("None") - } else{ + setStorageFormData("Read/Write") + } else { setStorageFormData(forageData.storage.storageAccessMode) } - + if (!forageData.containerResources) { setContainerResourcesFormData(defaultContainerResources) } else { @@ -268,7 +269,7 @@ const SidebarForm = (props: ISidebarFormProps) => { fetchForageDataById, setFormsForageData, handleOnChange, - isPieceForm, + isPieceForm, ]) return ( @@ -313,7 +314,7 @@ const SidebarForm = (props: ISidebarFormProps) => { - Container Resources + Storage @@ -367,7 +368,7 @@ const SidebarForm = (props: ISidebarFormProps) => { max: maxAcceptedCpu }} error={containerResourcesFieldsErrors.cpu.max} - helperText={containerResourcesFieldsErrors.cpu.max ? 'Max CPU must be between ' + minAcceptedCpu + ' and ' + maxAcceptedCpu: ''} + helperText={containerResourcesFieldsErrors.cpu.max ? 'Max CPU must be between ' + minAcceptedCpu + ' and ' + maxAcceptedCpu : ''} /> @@ -384,7 +385,7 @@ const SidebarForm = (props: ISidebarFormProps) => { max: maxAcceptedMemory }} error={containerResourcesFieldsErrors.memory.min} - helperText={containerResourcesFieldsErrors.memory.min ? 'Min Memory must be between ' + minAcceptedMemory + ' and ' + maxAcceptedMemory: ''} + helperText={containerResourcesFieldsErrors.memory.min ? 'Min Memory must be between ' + minAcceptedMemory + ' and ' + maxAcceptedMemory : ''} /> @@ -397,11 +398,11 @@ const SidebarForm = (props: ISidebarFormProps) => { required fullWidth inputProps={{ - min: minAcceptedMemory, + min: minAcceptedMemory, max: maxAcceptedMemory }} error={containerResourcesFieldsErrors.memory.max} - helperText={containerResourcesFieldsErrors.memory.max ? 'Max Memory must be between ' + minAcceptedMemory + ' and ' + maxAcceptedMemory: ''} + helperText={containerResourcesFieldsErrors.memory.max ? 'Max Memory must be between ' + minAcceptedMemory + ' and ' + maxAcceptedMemory : ''} /> @@ -415,11 +416,11 @@ const SidebarForm = (props: ISidebarFormProps) => { } label="Use GPU" /> - + - + : null } diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/workflow-editor-panel.component.tsx b/frontend/src/pages/private/workflows/workflows-editor/components/workflow-editor-panel.component.tsx index 00173526..106dcc85 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/components/workflow-editor-panel.component.tsx +++ b/frontend/src/pages/private/workflows/workflows-editor/components/workflow-editor-panel.component.tsx @@ -149,7 +149,7 @@ const WorkflowEditorPanelComponent = () => { upstreamMap[newNode.id] = upstreamMapFormInfo await setForageUpstreamMap(upstreamMap) defaultData['storage'] = { - "storageAccessMode": 'None' + "storageAccessMode": 'Read/Write', } defaultData['containerResources'] = containerResourcesDefaultData // Set default data for the node form - used in json-forms From 1b1d05ddd981ded3d39cca5f363dfa7293546a49 Mon Sep 17 00:00:00 2001 From: luiz Date: Fri, 2 Jun 2023 14:25:23 +0200 Subject: [PATCH 059/328] advanced options collapsible --- .../components/domino-form-item.component.tsx | 17 +- .../components/sidebar-form.component.tsx | 269 ++++++++++-------- 2 files changed, 154 insertions(+), 132 deletions(-) diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item.component.tsx b/frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item.component.tsx index 1e6bb3c3..82ec100c 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item.component.tsx +++ b/frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item.component.tsx @@ -9,6 +9,7 @@ import { FormControl, InputLabel, SelectChangeEvent, + Grid } from '@mui/material'; import { DemoContainer } from '@mui/x-date-pickers/internals/demo'; import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; @@ -412,13 +413,17 @@ const DominoFormItem: React.FC = ({ formId, schema, itemKey alignItems="flex-start" sx={{ paddingTop: "10px" }} > - {inputElement} + + {inputElement} + {checkedFromUpstreamAllowed ? ( - handleCheckboxFromUpstreamChange(event.target.checked)} - disabled={!checkedFromUpstreamEditable} - /> + + handleCheckboxFromUpstreamChange(event.target.checked)} + disabled={!checkedFromUpstreamEditable} + /> + ) : null} ); diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component.tsx b/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component.tsx index 063da958..53552285 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component.tsx +++ b/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component.tsx @@ -10,8 +10,12 @@ import { InputLabel, TextField, FormControlLabel, - Checkbox + Checkbox, + Accordion, + AccordionSummary, + AccordionDetails } from '@mui/material' +import ExpandMoreIcon from '@mui/icons-material/ExpandMore'; import { useWorkflowsEditor } from 'context/workflows/workflows-editor.context' import { extractDefaultValues } from 'utils' @@ -289,138 +293,151 @@ const SidebarForm = (props: ISidebarFormProps) => { { isPieceForm ? - - - Input Argument - - - Upstream - - - : null - } - { - isPieceForm ? - - - - +
+ + + Input Arguments - - - - Storage - - - - Storage Access Mode - - - + + Upstream - - - - Container Resources - - - - - - - - - - - - - + + + + - - } - label="Use GPU" + - +
+ + + }> + + Advanced Options + + + + + + Storage + + + + Storage Access Mode + + + + + +
+ + + + Container Resources + + + + + + + + + + + + + + + + } + label="Use GPU" + /> + + + + + - + +
+
: null } From a3056fd4b0212fa3f10153a3282be33a9326f515 Mon Sep 17 00:00:00 2001 From: luiz Date: Fri, 2 Jun 2023 14:32:47 +0200 Subject: [PATCH 060/328] improve styles --- .../components/sidebar-form.component.tsx | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component.tsx b/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component.tsx index 53552285..3f7e942b 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component.tsx +++ b/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component.tsx @@ -316,9 +316,14 @@ const SidebarForm = (props: ISidebarFormProps) => {
- + }> - + Advanced Options @@ -435,12 +440,11 @@ const SidebarForm = (props: ISidebarFormProps) => { - -
: null } +
) From 588492b3bc710ea0cd33da5ac46ebe2f027f5a83 Mon Sep 17 00:00:00 2001 From: Vinicius Date: Fri, 2 Jun 2023 10:30:13 -0300 Subject: [PATCH 061/328] fix schemas and dagfile --- rest/schemas/requests/workflow.py | 19 +++++++++++++++---- rest/services/workflow_service.py | 1 + 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/rest/schemas/requests/workflow.py b/rest/schemas/requests/workflow.py index b8a5a4b2..e3a705e9 100644 --- a/rest/schemas/requests/workflow.py +++ b/rest/schemas/requests/workflow.py @@ -30,6 +30,10 @@ class WorkflowStorage(BaseModel): storage_source: Optional[str] # TODO use enum ? base_folder: Optional[str] +class SelectEndDate(str, Enum): + never = "never" + user_defined = "User defined" + class WorkflowBaseSettings(BaseModel): # TODO remove regex ? name: str = Field( @@ -37,8 +41,9 @@ class WorkflowBaseSettings(BaseModel): example="workflow_name", regex=r"^[\w]*$", ) - start_date: str = Field(alias="startDate") - end_date: Optional[str] = Field(alias='endDate')# TODO add end date to UI? + start_date: str = Field(alias="startDateTime") + select_end_date: Optional[SelectEndDate] = Field(alias="selectEndDate", default=SelectEndDate.never) + end_date: Optional[str] = Field(alias='endDateTime') schedule_interval: ScheduleIntervalType = Field(alias="scheduleInterval") catchup: Optional[bool] = False # TODO add catchup to UI? generate_report: Optional[bool] = Field(alias="generateReport", default=False) # TODO add generate report to UI? @@ -48,7 +53,7 @@ class WorkflowBaseSettings(BaseModel): @validator('start_date') def start_date_validator(cls, v): try: - converted_date = datetime.fromisoformat(v).date() + converted_date = datetime.strptime(v, "%Y-%m-%dT%H:%M:%S.%fZ").date() if converted_date < datetime.now().date(): raise ValueError("Start date must be in the future") return converted_date.isoformat() @@ -62,7 +67,13 @@ def end_date_validator(cls, v, values): if 'start_date' not in values: raise ValueError("Start date must be provided") converted_start_date = datetime.fromisoformat(values['start_date']) - converted_end_date = datetime.fromisoformat(v) + if 'select_end_date' not in values: + raise ValueError("Select end date must be provided") + + if values['select_end_date'] == SelectEndDate.never.value: + return None + + converted_end_date = datetime.strptime(v, "%Y-%m-%dT%H:%M:%S.%fZ").date() if converted_end_date <= converted_start_date: raise ValueError("End date must greater than start date") return converted_end_date.isoformat() diff --git a/rest/services/workflow_service.py b/rest/services/workflow_service.py index 876f172c..d0850b75 100644 --- a/rest/services/workflow_service.py +++ b/rest/services/workflow_service.py @@ -397,6 +397,7 @@ def _create_dag_code_from_raw_json(self, data: dict, workspace_id: int): - end_date (not none) """ workflow_kwargs['dag_id'] = workflow_kwargs.pop('id') + select_end_date = workflow_kwargs.pop('select_end_date') # TODO define how to use select end date workflow_kwargs['schedule_interval'] = None if workflow_kwargs['schedule_interval'] == 'none' else f"@{workflow_kwargs['schedule_interval']}" workflow_processed_schema = { From 5b7336297e4b3342a8a45dc00720e632ad3076c0 Mon Sep 17 00:00:00 2001 From: Vinicius Date: Fri, 2 Jun 2023 10:30:22 -0300 Subject: [PATCH 062/328] fix payload --- frontend/src/context/workflows/workflows-editor.context.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/frontend/src/context/workflows/workflows-editor.context.tsx b/frontend/src/context/workflows/workflows-editor.context.tsx index 670b7ecd..becbe28d 100644 --- a/frontend/src/context/workflows/workflows-editor.context.tsx +++ b/frontend/src/context/workflows/workflows-editor.context.tsx @@ -376,9 +376,9 @@ export const WorkflowsEditorProvider: FC = ({ chi ui_schema['nodes'][taskName] = element const taskDict: any = {} - const { source, baseFolder, ...providerOptions } = storageWorkflowData || {} + const { storageSource, baseFolder, ...providerOptions } = storageWorkflowData || {} const storageDict: any = { - "source": source || null, + "source": storageSource || null, "base_folder": baseFolder || null, "mode": elementData?.storage?.storageAccessMode, "provider_options": providerOptions || null From b6321cee702434cbec3e15d98abaa936573ec347 Mon Sep 17 00:00:00 2001 From: Vinicius Date: Fri, 2 Jun 2023 10:33:55 -0300 Subject: [PATCH 063/328] fix get workflows service response --- rest/services/workflow_service.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/rest/services/workflow_service.py b/rest/services/workflow_service.py index d0850b75..9e1a72d6 100644 --- a/rest/services/workflow_service.py +++ b/rest/services/workflow_service.py @@ -193,14 +193,14 @@ async def list_workflows( is_dag_broken = dag_uuid in import_errors_uuids schedule_interval = 'none' - is_active = 'creating' - is_paused = 'creating' + is_active = False + is_paused = False status = WorkflowStatus.creating.value if is_dag_broken: status = WorkflowStatus.failed.value schedule_interval = 'failed' - is_active = 'failed' - is_paused = 'failed' + is_active = False + is_paused = False if response and not is_dag_broken: schedule_interval = response.get("schedule_interval") From 8c2a2ec777ca5e5775e7b631b871277268e0dd1b Mon Sep 17 00:00:00 2001 From: luiz Date: Fri, 2 Jun 2023 17:15:00 +0200 Subject: [PATCH 064/328] need to treat timepicker separate, not working yet --- .../components/domino-form-item.component.tsx | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item.component.tsx b/frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item.component.tsx index 82ec100c..a6c60eef 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item.component.tsx +++ b/frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item.component.tsx @@ -89,9 +89,14 @@ const DominoFormItem: React.FC = ({ formId, schema, itemKey // Handle input change const handleInputChange = useCallback((event: any, source: string) => { let fieldValue = event?.target?.value || ""; - if (source === 'datePicker' || source === 'timePicker' || source === 'dateTimePicker') { + if (source === 'datePicker' || source === 'dateTimePicker') { const newDate = event; fieldValue = new Date(newDate).toISOString(); + } else if (source === 'timePicker') { + const newTime = event; + // const newDate = dayjs().set('hour', newTime.getHours()).set('minute', newTime.getMinutes()).set('second', newTime.getSeconds()); + console.log("newDate", newTime); + // fieldValue = new Date(newDate).toISOString(); } else { const { name, value, type, checked } = event.target; fieldValue = type === 'checkbox' ? checked : value; @@ -362,6 +367,7 @@ const DominoFormItem: React.FC = ({ formId, schema, itemKey label={itemSchema.title} format='HH:mm' sx={{ width: "100%" }} + // value={new Date(`1970-01-01T${value}:00`)} // this trick is necessary to properly parse only time value={dayjs(value)} onChange={(event) => handleInputChange(event, "timePicker")} /> From e1ef2cc9f9ed23b34f5b4d83dbae4d6a473095d8 Mon Sep 17 00:00:00 2001 From: luiz Date: Fri, 2 Jun 2023 17:54:19 +0200 Subject: [PATCH 065/328] comment mounts --- domino/custom_operators/docker_operator.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/domino/custom_operators/docker_operator.py b/domino/custom_operators/docker_operator.py index 30711eef..0bd0b4a3 100644 --- a/domino/custom_operators/docker_operator.py +++ b/domino/custom_operators/docker_operator.py @@ -40,8 +40,8 @@ def __init__( # # TODO remove mounts=[ # TODO remove - Mount(source='/media/luiz/storage2/Github/domino/domino', target='/home/domino/domino_py/domino', type='bind', read_only=True), - Mount(source='/media/luiz/storage2/Github/default_domino_pieces', target='/home/domino/pieces_repository/', type='bind', read_only=True), + # Mount(source='/media/luiz/storage2/Github/domino/domino', target='/home/domino/domino_py/domino', type='bind', read_only=True), + # Mount(source='/media/luiz/storage2/Github/default_domino_pieces', target='/home/domino/pieces_repository/', type='bind', read_only=True), ] if self.workflow_shared_storage and str(self.workflow_shared_storage.source.value).lower() == str(getattr(StorageSource, 'local').value).lower(): mounts.append( From e8bceca4f54cf9add0eb2667c594c05ce30c63dd Mon Sep 17 00:00:00 2001 From: Vinicius Date: Fri, 2 Jun 2023 17:31:48 -0300 Subject: [PATCH 066/328] adding format, update default repo version --- docker-compose-dev.yaml | 2 +- .../components/domino-form-item.component.tsx | 25 +++++++++++++------ rest/core/settings.py | 2 +- 3 files changed, 20 insertions(+), 9 deletions(-) diff --git a/docker-compose-dev.yaml b/docker-compose-dev.yaml index 012fa474..9067fb27 100644 --- a/docker-compose-dev.yaml +++ b/docker-compose-dev.yaml @@ -314,7 +314,7 @@ services: - DOMINO_DB_HOST=domino_postgres - DOMINO_DB_PORT=5432 - DOMINO_DB_NAME=postgres - - DOMINO_DEFAULT_PIECES_REPOSITORY_VERSION=0.3.7 + - DOMINO_DEFAULT_PIECES_REPOSITORY_VERSION=0.3.8 - DOMINO_DEFAULT_PIECES_REPOSITORY_TOKEN=${DOMINO_DEFAULT_PIECES_REPOSITORY_TOKEN} - DOMINO_GITHUB_ACCESS_TOKEN_WORKFLOWS=${DOMINO_GITHUB_ACCESS_TOKEN_WORKFLOWS} - DOMINO_GITHUB_WORKFLOWS_REPOSITORY=${DOMINO_GITHUB_WORKFLOWS_REPOSITORY} diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item.component.tsx b/frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item.component.tsx index a6c60eef..526f44da 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item.component.tsx +++ b/frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item.component.tsx @@ -44,7 +44,14 @@ const DominoFormItem: React.FC = ({ formId, schema, itemKey setNameKeyUpstreamArgsMap, getNameKeyUpstreamArgsMap, } = useWorkflowsEditor(); - const formFieldType = schema.properties[itemKey].type; + var formFieldType = schema.properties[itemKey].type; + const formFieldFormat = schema.properties[itemKey].format; + if (formFieldFormat !== undefined && formFieldFormat !== null) { + formFieldType = formFieldFormat; + } + if ('allOf' in schema.properties[itemKey] || "oneOf" in schema.properties[itemKey] || "anyOf" in schema.properties[itemKey]) { + formFieldType = 'enum' + } const [formLabelUpstreamIdMap, setFormLabelUpstreamIdMap] = useState>({}); const [upstreamOptions, setUpstreamOptions] = useState([]); const [upstreamSelectValue, setUpstreamSelectValue] = useState(''); @@ -95,7 +102,6 @@ const DominoFormItem: React.FC = ({ formId, schema, itemKey } else if (source === 'timePicker') { const newTime = event; // const newDate = dayjs().set('hour', newTime.getHours()).set('minute', newTime.getMinutes()).set('second', newTime.getSeconds()); - console.log("newDate", newTime); // fieldValue = new Date(newDate).toISOString(); } else { const { name, value, type, checked } = event.target; @@ -163,7 +169,12 @@ const DominoFormItem: React.FC = ({ formId, schema, itemKey const upstreamOutputSchema = upstreamOperator?.output_schema Object.keys(upstreamOutputSchema?.properties).forEach((key, index) => { const obj = upstreamOutputSchema?.properties[key] - if (obj.type === formFieldType) { + var objType = obj.format ? obj.format : obj.type + if ('allOf' in obj || "oneOf" in obj || "anyOf" in obj) { + objType = 'enum' + } + + if (objType === formFieldType) { var upstreamOptionName = `${upstreamOperator?.name} - ${obj['title']}` const counter = 1; while (upstreamOptions.includes(upstreamOptionName)) { @@ -343,7 +354,7 @@ const DominoFormItem: React.FC = ({ formId, schema, itemKey parentSchemaDefinitions={schema.definitions} fromUpstreamMode={arrayItemsFromUpstreamOption} /> - } else if (itemSchema.type === 'string' && itemSchema?.widget === 'date') { + } else if (itemSchema.type === 'string' && itemSchema?.format === 'date') { inputElement = ( @@ -358,7 +369,7 @@ const DominoFormItem: React.FC = ({ formId, schema, itemKey ); - } else if (itemSchema.type === 'string' && itemSchema?.widget === 'time') { + } else if (itemSchema.type === 'string' && itemSchema?.format === 'time') { inputElement = ( @@ -368,13 +379,13 @@ const DominoFormItem: React.FC = ({ formId, schema, itemKey format='HH:mm' sx={{ width: "100%" }} // value={new Date(`1970-01-01T${value}:00`)} // this trick is necessary to properly parse only time - value={dayjs(value)} + value={dayjs(value, "HH:mm")} onChange={(event) => handleInputChange(event, "timePicker")} /> ); - } else if (itemSchema.type === 'string' && itemSchema?.widget === 'datetime') { + } else if (itemSchema.type === 'string' && itemSchema?.format === 'datetime') { inputElement = ( diff --git a/rest/core/settings.py b/rest/core/settings.py index 7f3c6ccb..79649380 100644 --- a/rest/core/settings.py +++ b/rest/core/settings.py @@ -48,7 +48,7 @@ class Settings(BaseSettings): # Default domino pieces repository DOMINO_DEFAULT_PIECES_REPOSITORY = os.environ.get('DOMINO_DEFAULT_PIECES_REPOSITORY', "Tauffer-Consulting/default_domino_pieces") - DOMINO_DEFAULT_PIECES_REPOSITORY_VERSION = os.environ.get('DOMINO_DEFAULT_PIECES_REPOSITORY_VERSION', "0.2.2") + DOMINO_DEFAULT_PIECES_REPOSITORY_VERSION = os.environ.get('DOMINO_DEFAULT_PIECES_REPOSITORY_VERSION', "0.3.8") DOMINO_DEFAULT_PIECES_REPOSITORY_SOURCE = os.environ.get('DOMINO_DEFAULT_PIECES_REPOSITORY_SOURCE', "github") DOMINO_DEFAULT_PIECES_REPOSITORY_TOKEN: EmptyStrToNone = os.environ.get('DOMINO_DEFAULT_PIECES_REPOSITORY_TOKEN', "") From db71e1dc595b3f45da0d6124e5d683fd53b298fc Mon Sep 17 00:00:00 2001 From: luiz Date: Sat, 3 Jun 2023 11:41:07 +0200 Subject: [PATCH 067/328] fix timepicker --- .../workflows-editor/components/domino-form-item.component.tsx | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item.component.tsx b/frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item.component.tsx index 526f44da..6ce34e88 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item.component.tsx +++ b/frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item.component.tsx @@ -101,8 +101,7 @@ const DominoFormItem: React.FC = ({ formId, schema, itemKey fieldValue = new Date(newDate).toISOString(); } else if (source === 'timePicker') { const newTime = event; - // const newDate = dayjs().set('hour', newTime.getHours()).set('minute', newTime.getMinutes()).set('second', newTime.getSeconds()); - // fieldValue = new Date(newDate).toISOString(); + fieldValue = dayjs(newTime).format('HH:mm'); } else { const { name, value, type, checked } = event.target; fieldValue = type === 'checkbox' ? checked : value; From 5f8f57ce327fbfabd22d0e8e18495affe49d913b Mon Sep 17 00:00:00 2001 From: luiz Date: Sat, 3 Jun 2023 18:30:10 +0200 Subject: [PATCH 068/328] fix codeeditor --- .../domino-form-item-textcode.component.tsx | 23 ++++--------------- .../components/domino-form-item.component.tsx | 10 ++++---- 2 files changed, 8 insertions(+), 25 deletions(-) diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item-textcode.component.tsx b/frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item-textcode.component.tsx index b30956c1..77deb0c6 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item-textcode.component.tsx +++ b/frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item-textcode.component.tsx @@ -4,33 +4,18 @@ import CodeEditor from '@uiw/react-textarea-code-editor'; interface TextCodeItemProps { itemSchema: any; + codeValue: string; + onChange: (value: any) => void; } -const TextCodeItem: React.FC = ({ itemSchema }) => { - - const [codeValue, setCodeValue] = useState(() => { - if (itemSchema.properties?.default) { - return itemSchema.properties.default; - } else { - return `# Do not modify the function definition line -def custom_function(input_args: list): - # Write your code here - print(input_args) - - # Return the output of the function as an object - return { - "out_arg_1": "out_value_1", - "out_arg_2": "out_value_2" - }`; - } - }); +const TextCodeItem: React.FC = ({ itemSchema, codeValue, onChange }) => { return ( setCodeValue(evn.target.value)} + onChange={(event: any) => onChange(event.target.value)} padding={15} style={{ fontSize: 12, diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item.component.tsx b/frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item.component.tsx index 6ce34e88..c17c1c27 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item.component.tsx +++ b/frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item.component.tsx @@ -102,6 +102,8 @@ const DominoFormItem: React.FC = ({ formId, schema, itemKey } else if (source === 'timePicker') { const newTime = event; fieldValue = dayjs(newTime).format('HH:mm'); + } else if (source === 'codeeditor') { + fieldValue = event; } else { const { name, value, type, checked } = event.target; fieldValue = type === 'checkbox' ? checked : value; @@ -132,12 +134,6 @@ const DominoFormItem: React.FC = ({ formId, schema, itemKey } await setForageCheckboxStates(auxCheckboxState) - // We can improve the logic using a forage key with the following structure: - // nodeId: { - // upstreams: [], - // downstreams: [], - // } - // It will avoid to iterate over all edges var upstreamsIds = [] for (var ed of edges) { if (ed.target === formId) { @@ -403,6 +399,8 @@ const DominoFormItem: React.FC = ({ formId, schema, itemKey inputElement = ( handleInputChange(event, "codeeditor")} + codeValue={value} /> ) } else if (itemSchema.type === 'string') { From 7ec0b973da1dc79bbe1bf286e48378287eaa3a22 Mon Sep 17 00:00:00 2001 From: luiz Date: Sat, 3 Jun 2023 18:33:08 +0200 Subject: [PATCH 069/328] codeeditor component --- ...ponent.tsx => domino-form-item-codeeditor.component.tsx} | 6 +++--- .../components/domino-form-item.component.tsx | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) rename frontend/src/pages/private/workflows/workflows-editor/components/{domino-form-item-textcode.component.tsx => domino-form-item-codeeditor.component.tsx} (83%) diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item-textcode.component.tsx b/frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item-codeeditor.component.tsx similarity index 83% rename from frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item-textcode.component.tsx rename to frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item-codeeditor.component.tsx index 77deb0c6..069f2dc9 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item-textcode.component.tsx +++ b/frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item-codeeditor.component.tsx @@ -2,13 +2,13 @@ import React, { useState } from 'react'; import CodeEditor from '@uiw/react-textarea-code-editor'; -interface TextCodeItemProps { +interface CodeEditorItemProps { itemSchema: any; codeValue: string; onChange: (value: any) => void; } -const TextCodeItem: React.FC = ({ itemSchema, codeValue, onChange }) => { +const CodeEditorItem: React.FC = ({ itemSchema, codeValue, onChange }) => { return ( = ({ itemSchema, codeValue, onCh ); }; -export default React.memo(TextCodeItem); \ No newline at end of file +export default React.memo(CodeEditorItem); \ No newline at end of file diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item.component.tsx b/frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item.component.tsx index c17c1c27..4f0154c5 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item.component.tsx +++ b/frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item.component.tsx @@ -22,7 +22,7 @@ import dayjs from 'dayjs'; import { useWorkflowsEditor } from 'context/workflows/workflows-editor.context' import ArrayInputItem from './domino-form-item-array.component'; -import TextCodeItem from './domino-form-item-textcode.component'; +import CodeEditorItem from './domino-form-item-codeeditor.component'; interface DominoFormItemProps { @@ -397,7 +397,7 @@ const DominoFormItem: React.FC = ({ formId, schema, itemKey ); } else if (itemSchema.type === 'string' && itemSchema?.widget === 'codeeditor') { inputElement = ( - handleInputChange(event, "codeeditor")} codeValue={value} From 3a6503fc3c8caab4347bfc9235a4a449d641ee6b Mon Sep 17 00:00:00 2001 From: luiz Date: Sat, 3 Jun 2023 18:54:38 +0200 Subject: [PATCH 070/328] arrays values --- .../domino-form-item-array.component.tsx | 35 +++++++++++-------- .../components/domino-form-item.component.tsx | 4 +++ 2 files changed, 24 insertions(+), 15 deletions(-) diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item-array.component.tsx b/frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item-array.component.tsx index 79deb7f8..1eaf0d6d 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item-array.component.tsx +++ b/frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item-array.component.tsx @@ -26,17 +26,21 @@ interface ArrayInputItemProps { itemSchema: any; parentSchemaDefinitions: any; fromUpstreamMode?: FromUpstreamOptions | string; + arrayItems: Array | { [key: string]: any }[]; + onChange: (value: any) => void; } -const ArrayInputItem: React.FC = ({ itemSchema, parentSchemaDefinitions, fromUpstreamMode }) => { - const [arrayItems, setArrayItems] = useState(() => { - if (itemSchema.default && itemSchema.default.length > 0) { - const initArray = [...itemSchema.default]; - return initArray; - } else { - return []; - } - }); +const ArrayInputItem: React.FC = ({ itemSchema, parentSchemaDefinitions, fromUpstreamMode, arrayItems, onChange }) => { + // const [arrayItems, setArrayItems] = useState(() => { + // if (itemSchema.default && itemSchema.default.length > 0) { + // const initArray = [...itemSchema.default]; + // return initArray; + // } else { + // return []; + // } + // }); + + console.log(arrayItems) // Sub-items schema let subItemSchema: any = itemSchema.items; @@ -83,11 +87,12 @@ const ArrayInputItem: React.FC = ({ itemSchema, parentSchem const handleArrayItemChange = (index: number, itemKey: string, value: string) => { const updatedItems = [...arrayItems]; updatedItems[index][itemKey] = value; - setArrayItems(updatedItems); + onChange(updatedItems); }; // Add and delete items - // TODO - fix setArrayItems to fill the props with correct values types, right now just guessing an empty string, but this will most likely fail e.g. boolen types + // TODO - fix setArrayItems to fill the props with correct values types, + // right now just guessing an empty string, but this will most likely fail e.g. boolen types const handleAddItem = () => { let newItemPropsValues: { [key: string]: any } = {}; let newItemPropsChecked: { [key: string]: boolean } = {}; @@ -102,14 +107,14 @@ const ArrayInputItem: React.FC = ({ itemSchema, parentSchem return null; }); setCheckedFromUpstreamItemProp([...checkedFromUpstreamItemProp, newItemPropsChecked]); - setArrayItems([...arrayItems, newItemPropsValues]); + onChange([...arrayItems, newItemPropsValues]); }; // TODO - this is not working when deleting items with fromUpstrem checked const handleDeleteItem = (index: number) => { const updatedItems = [...arrayItems]; updatedItems.splice(index, 1); - setArrayItems(updatedItems); + onChange(updatedItems); const updatedCheckedFromUpstreamItemProp = [...checkedFromUpstreamItemProp]; updatedCheckedFromUpstreamItemProp.splice(index, 1); setCheckedFromUpstreamItemProp(updatedCheckedFromUpstreamItemProp); @@ -141,7 +146,7 @@ const ArrayInputItem: React.FC = ({ itemSchema, parentSchem } else { updatedItems[index] = value; } - setArrayItems(updatedItems); + // setArrayItems(updatedItems); }; // Each item in the array can be multiple inputs, with varied types like text, select, checkbox, etc. @@ -257,4 +262,4 @@ const ArrayInputItem: React.FC = ({ itemSchema, parentSchem ); }; -export default ArrayInputItem; \ No newline at end of file +export default React.memo(ArrayInputItem); \ No newline at end of file diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item.component.tsx b/frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item.component.tsx index 4f0154c5..6f504e26 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item.component.tsx +++ b/frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item.component.tsx @@ -104,6 +104,8 @@ const DominoFormItem: React.FC = ({ formId, schema, itemKey fieldValue = dayjs(newTime).format('HH:mm'); } else if (source === 'codeeditor') { fieldValue = event; + } else if (source === 'array') { + fieldValue = event; } else { const { name, value, type, checked } = event.target; fieldValue = type === 'checkbox' ? checked : value; @@ -348,6 +350,8 @@ const DominoFormItem: React.FC = ({ formId, schema, itemKey itemSchema={itemSchema} parentSchemaDefinitions={schema.definitions} fromUpstreamMode={arrayItemsFromUpstreamOption} + arrayItems={value} + onChange={(event) => handleInputChange(event, "array")} /> } else if (itemSchema.type === 'string' && itemSchema?.format === 'date') { inputElement = ( From d4e78618df5c62e9a1d418d9caf01a7828c1fa63 Mon Sep 17 00:00:00 2001 From: Vinicius Date: Mon, 5 Jun 2023 14:26:53 -0300 Subject: [PATCH 071/328] fix shallow copy on multiple array items checkbox --- docker-compose-dev.yaml | 2 +- .../domino-form-item-array.component.tsx | 38 +++++++++---------- rest/core/settings.py | 2 +- 3 files changed, 21 insertions(+), 21 deletions(-) diff --git a/docker-compose-dev.yaml b/docker-compose-dev.yaml index 9067fb27..fa18357d 100644 --- a/docker-compose-dev.yaml +++ b/docker-compose-dev.yaml @@ -314,7 +314,7 @@ services: - DOMINO_DB_HOST=domino_postgres - DOMINO_DB_PORT=5432 - DOMINO_DB_NAME=postgres - - DOMINO_DEFAULT_PIECES_REPOSITORY_VERSION=0.3.8 + - DOMINO_DEFAULT_PIECES_REPOSITORY_VERSION=0.3.9 - DOMINO_DEFAULT_PIECES_REPOSITORY_TOKEN=${DOMINO_DEFAULT_PIECES_REPOSITORY_TOKEN} - DOMINO_GITHUB_ACCESS_TOKEN_WORKFLOWS=${DOMINO_GITHUB_ACCESS_TOKEN_WORKFLOWS} - DOMINO_GITHUB_WORKFLOWS_REPOSITORY=${DOMINO_GITHUB_WORKFLOWS_REPOSITORY} diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item-array.component.tsx b/frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item-array.component.tsx index 1eaf0d6d..2fcabd4c 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item-array.component.tsx +++ b/frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item-array.component.tsx @@ -1,4 +1,4 @@ -import React, { useState } from 'react'; +import React, { useState, useCallback } from 'react'; import { Card, CardContent, @@ -40,7 +40,7 @@ const ArrayInputItem: React.FC = ({ itemSchema, parentSchem // } // }); - console.log(arrayItems) + //console.log(arrayItems) // Sub-items schema let subItemSchema: any = itemSchema.items; @@ -79,12 +79,13 @@ const ArrayInputItem: React.FC = ({ itemSchema, parentSchem return null; }); return initArray; - } else { - return []; - } + } + return []; + }); const handleArrayItemChange = (index: number, itemKey: string, value: string) => { + console.log('handleArrayItemChange') const updatedItems = [...arrayItems]; updatedItems[index][itemKey] = value; onChange(updatedItems); @@ -120,26 +121,25 @@ const ArrayInputItem: React.FC = ({ itemSchema, parentSchem setCheckedFromUpstreamItemProp(updatedCheckedFromUpstreamItemProp); }; - // FromUpstream checkboxes logic - // TODO - this is not working for multiple default items, they're changing together - const handleCheckboxFromUpstreamChange = (event: React.ChangeEvent, index: number, itemKey: string) => { - console.log(checkedFromUpstreamItemProp); - console.log("event", event.target.checked); - console.log("index", index); - console.log("itemkey", itemKey); + const handleCheckboxFromUpstreamChange = useCallback( + (event: React.ChangeEvent, index: number, itemKey: string) => { setCheckedFromUpstreamItemProp((prevArray) => { - const newArray = [...prevArray]; - console.log(newArray); - const objectToUpdate = newArray[index] as { [key: string]: boolean }; - console.log(objectToUpdate); - objectToUpdate[itemKey] = event.target.checked; - newArray[index] = objectToUpdate; + const newArray = prevArray.map((item, i) => { + if (i !== index) { + return item; + } + return { + ...item, + [itemKey]: event.target.checked, + }; + }); return newArray; }); - }; + }, []); // FromUpstream select logic const handleSelectFromUpstreamChange = (index: number, itemKey: string, value: string) => { + console.log('handleSelectFromUpstreamChange', handleSelectFromUpstreamChange) const updatedItems = [...arrayItems]; if (typeof updatedItems[index] === 'object') { updatedItems[index][itemKey] = value; diff --git a/rest/core/settings.py b/rest/core/settings.py index 79649380..8efcfb3a 100644 --- a/rest/core/settings.py +++ b/rest/core/settings.py @@ -48,7 +48,7 @@ class Settings(BaseSettings): # Default domino pieces repository DOMINO_DEFAULT_PIECES_REPOSITORY = os.environ.get('DOMINO_DEFAULT_PIECES_REPOSITORY', "Tauffer-Consulting/default_domino_pieces") - DOMINO_DEFAULT_PIECES_REPOSITORY_VERSION = os.environ.get('DOMINO_DEFAULT_PIECES_REPOSITORY_VERSION', "0.3.8") + DOMINO_DEFAULT_PIECES_REPOSITORY_VERSION = os.environ.get('DOMINO_DEFAULT_PIECES_REPOSITORY_VERSION', "0.3.9") DOMINO_DEFAULT_PIECES_REPOSITORY_SOURCE = os.environ.get('DOMINO_DEFAULT_PIECES_REPOSITORY_SOURCE', "github") DOMINO_DEFAULT_PIECES_REPOSITORY_TOKEN: EmptyStrToNone = os.environ.get('DOMINO_DEFAULT_PIECES_REPOSITORY_TOKEN', "") From a11e2ae0fc3290f6fdd5c23f539fadbbfa1c2efc Mon Sep 17 00:00:00 2001 From: Vinicius Date: Mon, 5 Jun 2023 15:07:18 -0300 Subject: [PATCH 072/328] partial commit --- .../domino-form-item-array.component.tsx | 59 +++++++++++++------ .../components/domino-form-item.component.tsx | 4 +- 2 files changed, 43 insertions(+), 20 deletions(-) diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item-array.component.tsx b/frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item-array.component.tsx index 2fcabd4c..1d131888 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item-array.component.tsx +++ b/frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item-array.component.tsx @@ -13,7 +13,7 @@ import { import TextField from '@mui/material/TextField'; import DeleteIcon from '@mui/icons-material/Delete'; import AddIcon from '@mui/icons-material/Add'; - +import { useWorkflowsEditor } from 'context/workflows/workflows-editor.context' enum FromUpstreamOptions { always = "always", @@ -23,6 +23,8 @@ enum FromUpstreamOptions { // Arrays usually have their inner schema defined in the main schema definitions interface ArrayInputItemProps { + formId: string; + itemKey: string; itemSchema: any; parentSchemaDefinitions: any; fromUpstreamMode?: FromUpstreamOptions | string; @@ -30,17 +32,29 @@ interface ArrayInputItemProps { onChange: (value: any) => void; } -const ArrayInputItem: React.FC = ({ itemSchema, parentSchemaDefinitions, fromUpstreamMode, arrayItems, onChange }) => { - // const [arrayItems, setArrayItems] = useState(() => { - // if (itemSchema.default && itemSchema.default.length > 0) { - // const initArray = [...itemSchema.default]; - // return initArray; - // } else { - // return []; - // } - // }); +const ArrayInputItem: React.FC = ({ + formId, + itemKey, + itemSchema, + parentSchemaDefinitions, + fromUpstreamMode, + arrayItems, + onChange +}) => { + + console.log(formId, itemKey) + console.log('arrayItems', arrayItems) - //console.log(arrayItems) + const { + fetchForageWorkflowEdges, + getForageUpstreamMap, + setForageUpstreamMap, + fetchForagePieceById, + getForageCheckboxStates, + setForageCheckboxStates, + setNameKeyUpstreamArgsMap, + getNameKeyUpstreamArgsMap, + } = useWorkflowsEditor(); // Sub-items schema let subItemSchema: any = itemSchema.items; @@ -56,6 +70,7 @@ const ArrayInputItem: React.FC = ({ itemSchema, parentSchem arrayOfProperties[itemSchema.title] = { "": "" }; } const numProps = Object.keys(arrayOfProperties).length; + const [upstreamOptions, setUpstreamOptions] = useState([]); // console.log("itemSchema", itemSchema); @@ -79,9 +94,9 @@ const ArrayInputItem: React.FC = ({ itemSchema, parentSchem return null; }); return initArray; - } + } return []; - + }); const handleArrayItemChange = (index: number, itemKey: string, value: string) => { @@ -121,8 +136,15 @@ const ArrayInputItem: React.FC = ({ itemSchema, parentSchem setCheckedFromUpstreamItemProp(updatedCheckedFromUpstreamItemProp); }; - const handleCheckboxFromUpstreamChange = useCallback( - (event: React.ChangeEvent, index: number, itemKey: string) => { + const handleCheckboxFromUpstreamChange = useCallback(async (event: React.ChangeEvent, index: number, itemKey: string) => { + + const edges = await fetchForageWorkflowEdges() + var auxCheckboxState: any = await getForageCheckboxStates() + if (!auxCheckboxState) { + auxCheckboxState = {} + } + + setCheckedFromUpstreamItemProp((prevArray) => { const newArray = prevArray.map((item, i) => { if (i !== index) { @@ -130,7 +152,7 @@ const ArrayInputItem: React.FC = ({ itemSchema, parentSchem } return { ...item, - [itemKey]: event.target.checked, + [itemKey]: event.target.checked, }; }); return newArray; @@ -139,7 +161,7 @@ const ArrayInputItem: React.FC = ({ itemSchema, parentSchem // FromUpstream select logic const handleSelectFromUpstreamChange = (index: number, itemKey: string, value: string) => { - console.log('handleSelectFromUpstreamChange', handleSelectFromUpstreamChange) + console.log('handleSelectFromUpstreamChange') const updatedItems = [...arrayItems]; if (typeof updatedItems[index] === 'object') { updatedItems[index][itemKey] = value; @@ -163,7 +185,6 @@ const ArrayInputItem: React.FC = ({ itemSchema, parentSchem initialValue = arrayItems[index as number]; } if (checkedFromUpstreamItemProp[index]?.[itemKey]) { - const options: Array = ['upstream 1', 'upstream 2', 'upstream 3', 'upstream 4']; inputElement = ( {`${itemKey} [${index}]`} @@ -172,7 +193,7 @@ const ArrayInputItem: React.FC = ({ itemSchema, parentSchem value={initialValue} onChange={(e) => handleSelectFromUpstreamChange(index, itemKey, e.target.value)} > - {options.map(option => ( + {upstreamOptions.map(option => ( {option} diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item.component.tsx b/frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item.component.tsx index 6f504e26..fbaf5836 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item.component.tsx +++ b/frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item.component.tsx @@ -44,6 +44,7 @@ const DominoFormItem: React.FC = ({ formId, schema, itemKey setNameKeyUpstreamArgsMap, getNameKeyUpstreamArgsMap, } = useWorkflowsEditor(); + var formFieldType = schema.properties[itemKey].type; const formFieldFormat = schema.properties[itemKey].format; if (formFieldFormat !== undefined && formFieldFormat !== null) { @@ -117,7 +118,6 @@ const DominoFormItem: React.FC = ({ formId, schema, itemKey onChange(event.target.value as string); }, [onChange]); - // From upstream checkbox callback const handleCheckboxFromUpstreamChange = useCallback(async (checked: boolean) => { setCheckedFromUpstream(checked); @@ -347,6 +347,8 @@ const DominoFormItem: React.FC = ({ formId, schema, itemKey />; } else if (itemSchema.type === 'array') { inputElement = Date: Mon, 5 Jun 2023 15:09:16 -0300 Subject: [PATCH 073/328] move method --- .../domino-form-item-array.component.tsx | 21 +++++++++---------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item-array.component.tsx b/frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item-array.component.tsx index 1d131888..da8bbf15 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item-array.component.tsx +++ b/frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item-array.component.tsx @@ -42,9 +42,6 @@ const ArrayInputItem: React.FC = ({ onChange }) => { - console.log(formId, itemKey) - console.log('arrayItems', arrayItems) - const { fetchForageWorkflowEdges, getForageUpstreamMap, @@ -138,13 +135,6 @@ const ArrayInputItem: React.FC = ({ const handleCheckboxFromUpstreamChange = useCallback(async (event: React.ChangeEvent, index: number, itemKey: string) => { - const edges = await fetchForageWorkflowEdges() - var auxCheckboxState: any = await getForageCheckboxStates() - if (!auxCheckboxState) { - auxCheckboxState = {} - } - - setCheckedFromUpstreamItemProp((prevArray) => { const newArray = prevArray.map((item, i) => { if (i !== index) { @@ -157,7 +147,16 @@ const ArrayInputItem: React.FC = ({ }); return newArray; }); - }, []); + + + const edges = await fetchForageWorkflowEdges() + var auxCheckboxState: any = await getForageCheckboxStates() + if (!auxCheckboxState) { + auxCheckboxState = {} + } + + + }, [fetchForageWorkflowEdges, getForageCheckboxStates]); // FromUpstream select logic const handleSelectFromUpstreamChange = (index: number, itemKey: string, value: string) => { From c6b37d14299f0b124e2c519afd3a6bf6e23a53ac Mon Sep 17 00:00:00 2001 From: luiz Date: Mon, 5 Jun 2023 20:17:24 +0200 Subject: [PATCH 074/328] renames --- ...t.tsx => piece-form-arrayinput-item.component.tsx} | 0 ...t.tsx => piece-form-codeeditor-item.component.tsx} | 0 ...em.component.tsx => piece-form-item.component.tsx} | 10 +++++----- ...no-form.component.tsx => piece-form.component.tsx} | 11 ++++++----- .../components/sidebar-form.component.tsx | 5 ++--- 5 files changed, 13 insertions(+), 13 deletions(-) rename frontend/src/pages/private/workflows/workflows-editor/components/{domino-form-item-array.component.tsx => piece-form-arrayinput-item.component.tsx} (100%) rename frontend/src/pages/private/workflows/workflows-editor/components/{domino-form-item-codeeditor.component.tsx => piece-form-codeeditor-item.component.tsx} (100%) rename frontend/src/pages/private/workflows/workflows-editor/components/{domino-form-item.component.tsx => piece-form-item.component.tsx} (98%) rename frontend/src/pages/private/workflows/workflows-editor/components/{domino-form.component.tsx => piece-form.component.tsx} (79%) diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item-array.component.tsx b/frontend/src/pages/private/workflows/workflows-editor/components/piece-form-arrayinput-item.component.tsx similarity index 100% rename from frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item-array.component.tsx rename to frontend/src/pages/private/workflows/workflows-editor/components/piece-form-arrayinput-item.component.tsx diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item-codeeditor.component.tsx b/frontend/src/pages/private/workflows/workflows-editor/components/piece-form-codeeditor-item.component.tsx similarity index 100% rename from frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item-codeeditor.component.tsx rename to frontend/src/pages/private/workflows/workflows-editor/components/piece-form-codeeditor-item.component.tsx diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item.component.tsx b/frontend/src/pages/private/workflows/workflows-editor/components/piece-form-item.component.tsx similarity index 98% rename from frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item.component.tsx rename to frontend/src/pages/private/workflows/workflows-editor/components/piece-form-item.component.tsx index fbaf5836..5d726e93 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item.component.tsx +++ b/frontend/src/pages/private/workflows/workflows-editor/components/piece-form-item.component.tsx @@ -21,11 +21,11 @@ import { toast } from 'react-toastify'; import dayjs from 'dayjs'; import { useWorkflowsEditor } from 'context/workflows/workflows-editor.context' -import ArrayInputItem from './domino-form-item-array.component'; -import CodeEditorItem from './domino-form-item-codeeditor.component'; +import ArrayInputItem from './piece-form-arrayinput-item.component'; +import CodeEditorItem from './piece-form-codeeditor-item.component'; -interface DominoFormItemProps { +interface PieceFormItemProps { formId: string; schema: any; itemKey: any; @@ -33,7 +33,7 @@ interface DominoFormItemProps { onChange: (val: any) => void; } -const DominoFormItem: React.FC = ({ formId, schema, itemKey, value, onChange }) => { +const PieceFormItem: React.FC = ({ formId, schema, itemKey, value, onChange }) => { const { fetchForageWorkflowEdges, getForageUpstreamMap, @@ -449,4 +449,4 @@ const DominoFormItem: React.FC = ({ formId, schema, itemKey ); }; -export default DominoFormItem; +export default PieceFormItem; diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/domino-form.component.tsx b/frontend/src/pages/private/workflows/workflows-editor/components/piece-form.component.tsx similarity index 79% rename from frontend/src/pages/private/workflows/workflows-editor/components/domino-form.component.tsx rename to frontend/src/pages/private/workflows/workflows-editor/components/piece-form.component.tsx index b305305e..99701486 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/components/domino-form.component.tsx +++ b/frontend/src/pages/private/workflows/workflows-editor/components/piece-form.component.tsx @@ -1,21 +1,22 @@ import React, { useState, useEffect } from 'react'; -import DominoFormItem from './domino-form-item.component'; +import PieceFormItem from './piece-form-item.component'; type initialDataType = Record; -interface DominoFormProps { +interface PieceFormProps { formId: string; schema: any; initialData: initialDataType; onChange: ({ errors, data }: { errors?: any, data: any }) => void; } -const DominoForm: React.FC = ({ formId, schema, initialData, onChange }) => { +const PieceForm: React.FC = ({ formId, schema, initialData, onChange }) => { const [formData, setFormData] = useState(initialData); const handleChange = (key: string) => (value: any) => { setFormData(prevData => ({ ...prevData, [key]: value })); + // setNodePieceSchema() }; useEffect(() => { @@ -33,7 +34,7 @@ const DominoForm: React.FC = ({ formId, schema, initialData, on { Object.keys(schema.properties).map(key => (
- = ({ formId, schema, initialData, on ); }; -export default React.memo(DominoForm); +export default React.memo(PieceForm); diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component.tsx b/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component.tsx index 3f7e942b..c1559a78 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component.tsx +++ b/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component.tsx @@ -19,7 +19,7 @@ import ExpandMoreIcon from '@mui/icons-material/ExpandMore'; import { useWorkflowsEditor } from 'context/workflows/workflows-editor.context' import { extractDefaultValues } from 'utils' -import DominoForm from './domino-form.component' +import PieceForm from './piece-form.component' // import { createAjv } from '@jsonforms/core' // import { operatorStorageSchema } from 'common/schemas/storageSchemas' // import { workflowFormSchema } from 'common/schemas/workflowFormSchema' @@ -56,7 +56,6 @@ const storageValidationValues: any = { } } - const defaultContainerResources = { "useGpu": false, "memory": { @@ -306,7 +305,7 @@ const SidebarForm = (props: ISidebarFormProps) => { - Date: Mon, 5 Jun 2023 15:53:45 -0300 Subject: [PATCH 075/328] wip improving upstreams --- .../domino-form-item-array.component.tsx | 39 ++++++++++++++++--- 1 file changed, 34 insertions(+), 5 deletions(-) diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item-array.component.tsx b/frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item-array.component.tsx index da8bbf15..23018dee 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item-array.component.tsx +++ b/frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item-array.component.tsx @@ -80,7 +80,7 @@ const ArrayInputItem: React.FC = ({ const initArray = new Array(itemSchema.default.length).fill({}); // set the default values from the schema in cases where from_upstream==="always" initArray.map((obj, index) => { - Object.keys(arrayOfProperties).map((itemKey) => { + Object.keys(arrayOfProperties).map(() => { if (subItemSchema?.properties?.[itemKey]?.from_upstream === "always") { initArray[index][itemKey] = true; } else { @@ -133,8 +133,9 @@ const ArrayInputItem: React.FC = ({ setCheckedFromUpstreamItemProp(updatedCheckedFromUpstreamItemProp); }; - const handleCheckboxFromUpstreamChange = useCallback(async (event: React.ChangeEvent, index: number, itemKey: string) => { + const handleCheckboxFromUpstreamChange = useCallback(async (event: React.ChangeEvent, index: number, _itemKey: string) => { + const checked = event.target.checked; setCheckedFromUpstreamItemProp((prevArray) => { const newArray = prevArray.map((item, i) => { if (i !== index) { @@ -142,21 +143,49 @@ const ArrayInputItem: React.FC = ({ } return { ...item, - [itemKey]: event.target.checked, + [_itemKey]: checked }; }); return newArray; }); - const edges = await fetchForageWorkflowEdges() var auxCheckboxState: any = await getForageCheckboxStates() if (!auxCheckboxState) { auxCheckboxState = {} } + console.log(typeof auxCheckboxState[formId][itemKey] !== 'object') + + if ((!(formId in auxCheckboxState))){ + if (!(itemKey in auxCheckboxState[formId])){ + auxCheckboxState[formId] = { + [itemKey]: new Array(arrayItems.length).fill(false) + } + } + } else if (typeof auxCheckboxState[formId][itemKey] !== 'object') { + auxCheckboxState[formId][itemKey] = new Array(arrayItems.length).fill(false) + } + + for (var i=0; i { From 7065358e51631e98875068fb89c7ec75f9f813e4 Mon Sep 17 00:00:00 2001 From: Vinicius Date: Mon, 5 Jun 2023 17:34:51 -0300 Subject: [PATCH 076/328] validate not upstreams --- .../domino-form-item-array.component.tsx | 45 ++++++++++++++----- 1 file changed, 34 insertions(+), 11 deletions(-) diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item-array.component.tsx b/frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item-array.component.tsx index 23018dee..a7d94280 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item-array.component.tsx +++ b/frontend/src/pages/private/workflows/workflows-editor/components/domino-form-item-array.component.tsx @@ -133,7 +133,7 @@ const ArrayInputItem: React.FC = ({ setCheckedFromUpstreamItemProp(updatedCheckedFromUpstreamItemProp); }; - const handleCheckboxFromUpstreamChange = useCallback(async (event: React.ChangeEvent, index: number, _itemKey: string) => { + const handleCheckboxFromUpstreamChange = useCallback(async (event: React.ChangeEvent, index: number) => { const checked = event.target.checked; setCheckedFromUpstreamItemProp((prevArray) => { @@ -143,7 +143,7 @@ const ArrayInputItem: React.FC = ({ } return { ...item, - [_itemKey]: checked + [itemKey]: checked }; }); return newArray; @@ -154,19 +154,41 @@ const ArrayInputItem: React.FC = ({ if (!auxCheckboxState) { auxCheckboxState = {} } - - console.log(typeof auxCheckboxState[formId][itemKey] !== 'object') if ((!(formId in auxCheckboxState))){ - if (!(itemKey in auxCheckboxState[formId])){ - auxCheckboxState[formId] = { - [itemKey]: new Array(arrayItems.length).fill(false) - } + auxCheckboxState[formId] = { + [itemKey]: new Array(arrayItems.length).fill(false) } } else if (typeof auxCheckboxState[formId][itemKey] !== 'object') { auxCheckboxState[formId][itemKey] = new Array(arrayItems.length).fill(false) } + var upstreamsIds = [] + for (var ed of edges) { + if (ed.target === formId) { + upstreamsIds.push(ed.source) + } + } + if (!upstreamsIds.length) { + // set checkbox react states to false + setCheckedFromUpstreamItemProp((prevArray) => { + const newArray = prevArray.map((item, i) => { + if (i !== index) { + return item; + } + return { + ...item, + [itemKey]: false + }; + }); + return newArray; + }); + await setForageCheckboxStates(auxCheckboxState) + // todo add toast + return + } + + for (var i=0; i = ({ } } await setForageCheckboxStates(auxCheckboxState) + }, [ @@ -203,7 +226,7 @@ const ArrayInputItem: React.FC = ({ const createItemElements = (item: string, index: number) => { let itemElements: JSX.Element[] = []; // Loop through each of the item's properties and create the inputs for them - Object.keys(arrayOfProperties).map((itemKey, subIndex) => { + Object.keys(arrayOfProperties).map((_itemKey, subIndex) => { let inputElement: JSX.Element; const subItemPropSchema = arrayOfProperties[itemKey]; let initialValue: any = ''; @@ -215,7 +238,7 @@ const ArrayInputItem: React.FC = ({ if (checkedFromUpstreamItemProp[index]?.[itemKey]) { inputElement = ( - {`${itemKey} [${index}]`} + {`${_itemKey} [${index}]`} { + (async () => { + const newElements: any = {} + arrayItems.map((item, index) => { + let itemElements: JSX.Element[] = []; + // Loop through each of the item's properties and create the inputs for them + Object.keys(arrayOfProperties).map((_itemKey, subIndex) => { + let inputElement: JSX.Element; + const subItemPropSchema = arrayOfProperties[_itemKey]; + let initialValue: any = ''; + if (typeof arrayItems[index] === 'object') { + initialValue = arrayItems[index as number][_itemKey as keyof typeof arrayItems[number]]; + } else { + initialValue = arrayItems[index as number]; + } + if (checkedFromUpstreamItemProp[index]?.[itemKey]) { + + inputElement = ( + + {`${_itemKey} [${index}]`} + + + ); + } else if (subItemPropSchema?.allOf && subItemPropSchema.allOf.length > 0) { + const typeClass = subItemPropSchema.allOf[0]['$ref'].split("/").pop(); + const valuesOptions: Array = parentSchemaDefinitions?.[typeClass].enum; + inputElement = ( + + {`${itemKey} [${index}]`} + + + ); + } else { + inputElement = handleSelectFromUpstreamChange(index, itemKey, e.target.value)} - > - {upstreamOptions.map(option => ( - - {option} - - ))} - - - ); - } else if (subItemPropSchema?.allOf && subItemPropSchema.allOf.length > 0) { - const typeClass = subItemPropSchema.allOf[0]['$ref'].split("/").pop(); - const valuesOptions: Array = parentSchemaDefinitions?.[typeClass].enum; - inputElement = ( - - {`${itemKey} [${index}]`} - - - ); - } else { - inputElement = handleArrayItemChange(index, itemKey, e.target.value)} - /> - } - itemElements.push( -
- {inputElement} - {subItemPropSchema?.from_upstream !== "never" ? ( - handleCheckboxFromUpstreamChange(event, index)} - disabled={subItemPropSchema?.from_upstream === 'never' || subItemPropSchema?.from_upstream === 'always'} /> - ) : null} -
- ); - return null; - }); - return
- {itemElements} -
+ } + itemElements.push( +
+ {inputElement} + {subItemPropSchema?.from_upstream !== "never" ? ( + handleCheckboxFromUpstreamChange(event, index)} + disabled={subItemPropSchema?.from_upstream === 'never' || subItemPropSchema?.from_upstream === 'always'} + /> + ) : null} +
+ ); + return null; + }); + newElements[index] = (
+ {itemElements} +
) + }) + setRenderElements(newElements) + + })() }, [ arrayOfProperties, arrayItems, @@ -365,8 +368,8 @@ const ArrayInputItem: React.FC = ({ numProps, parentSchemaDefinitions, upstreamOptions, - handleSelectFromUpstreamChange - ]); + handleSelectFromUpstreamChange, + ]) return ( @@ -391,7 +394,7 @@ const ArrayInputItem: React.FC = ({ handleDeleteItem(index)} aria-label="Delete"> - {createItemElements(item, index)} + {renderElements ? renderElements[index] : ''} ))} From 0b5e06b22f6346596a8ddebfca0db84a771fe3cc Mon Sep 17 00:00:00 2001 From: Vinicius Date: Thu, 8 Jun 2023 11:14:54 -0300 Subject: [PATCH 088/328] wip - updating data structures --- .../piece-form-arrayinput-item.component.tsx | 149 ++++++++++++++---- 1 file changed, 121 insertions(+), 28 deletions(-) diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/piece-form-arrayinput-item.component.tsx b/frontend/src/pages/private/workflows/workflows-editor/components/piece-form-arrayinput-item.component.tsx index 74ea6366..f9f472d2 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/components/piece-form-arrayinput-item.component.tsx +++ b/frontend/src/pages/private/workflows/workflows-editor/components/piece-form-arrayinput-item.component.tsx @@ -15,6 +15,7 @@ import DeleteIcon from '@mui/icons-material/Delete'; import AddIcon from '@mui/icons-material/Add'; import { useWorkflowsEditor } from 'context/workflows/workflows-editor.context' import { toast } from 'react-toastify'; +import { arrayOf } from 'prop-types'; enum FromUpstreamOptions { always = "always", @@ -56,6 +57,7 @@ const ArrayInputItem: React.FC = ({ // Sub-items schema let subItemSchema: any = itemSchema.items; + const itemsType = subItemSchema?.type if (itemSchema.items?.$ref) { const subItemSchemaName = itemSchema.items.$ref.split('/').pop(); subItemSchema = parentSchemaDefinitions[subItemSchemaName]; @@ -65,12 +67,15 @@ const ArrayInputItem: React.FC = ({ if (subItemSchema?.properties) { arrayOfProperties = subItemSchema?.properties; } else { - arrayOfProperties[itemSchema.title] = { "": "" }; + arrayOfProperties[itemKey] = { + "title": itemSchema.title, + "type": itemsType, + "description": itemSchema.description, + }; } const numProps = Object.keys(arrayOfProperties).length; - const itemsType = subItemSchema?.type - const [upstreamOptions, setUpstreamOptions] = useState([]); + const [upstreamOptions, setUpstreamOptions] = useState([]); const [renderElements, setRenderElements] = useState(null) type ObjectWithBooleanValues = { [key: string]: boolean }; @@ -130,6 +135,7 @@ const ArrayInputItem: React.FC = ({ setCheckedFromUpstreamItemProp(updatedCheckedFromUpstreamItemProp); }; + const handleCheckboxFromUpstreamChange = useCallback(async (event: React.ChangeEvent, index: number) => { const checked = event.target.checked; @@ -153,11 +159,21 @@ const ArrayInputItem: React.FC = ({ } if ((!(formId in auxCheckboxState))){ - auxCheckboxState[formId] = { - [itemKey]: new Array(arrayItems.length).fill(false) + auxCheckboxState[formId] = {} + } + + if (!(itemKey in auxCheckboxState[formId])){ + if (itemsType === "object") { + for (let key of Object.keys(subItemSchema?.properties)) { + auxCheckboxState[formId][itemKey] = { + [key]: new Array(arrayItems.length).fill(false) + } + } + }else{ + auxCheckboxState[formId][itemKey] = { + [itemKey]: new Array(arrayItems.length).fill(false) + } } - } else if (typeof auxCheckboxState[formId][itemKey] !== 'object') { - auxCheckboxState[formId][itemKey] = new Array(arrayItems.length).fill(false) } var upstreamsIds = [] @@ -187,16 +203,19 @@ const ArrayInputItem: React.FC = ({ for (var i=0; i = ({ upstreamMap[formId] = {} } + const upstreamOptions: any = {} for (const upstreamId of upstreamsIds) { const upstreamOperatorId = parseInt(upstreamId.split('_')[0]) if (checked){ const upstreamOperator = await fetchForagePieceById(upstreamOperatorId) const upstreamOutputSchema = upstreamOperator?.output_schema - Object.keys(upstreamOutputSchema?.properties).forEach((key, index) => { + Object.keys(upstreamOutputSchema?.properties).forEach((key, _index) => { const obj = upstreamOutputSchema?.properties[key] var objType = obj.format ? obj.format : obj.type - if (objType === itemsType) { - var upstreamOptionName = `${upstreamOperator?.name} - ${obj['title']}` - const counter = 1; - while (upstreamOptions.includes(upstreamOptionName)) { + if (itemsType === 'object') { + for (const [subItemKey, subItemValuevalue] of Object.entries(subItemSchema.properties)) { + if (!(subItemKey in upstreamOptions)) { + upstreamOptions[subItemKey] = [] + } + let itemType = subItemValuevalue.format ? subItemValuevalue.format : subItemValuevalue.type + if (objType === itemType){ + let upstreamOptionName = `${upstreamOperator?.name} - ${obj['title']}` + let counter = 1; + while (upstreamOptions[subItemKey].includes(upstreamOptionName)) { + upstreamOptionName = `${upstreamOptionName} (${counter})` + } + upstreamOptions[subItemKey].push(upstreamOptionName) + auxNameKeyUpstreamArgsMap[upstreamOptionName] = key + auxLabelUpstreamIdMap[upstreamOptionName] = upstreamId + } + } + } + + if (objType === itemsType){ + let upstreamOptionName = `${upstreamOperator?.name} - ${obj['title']}` + let counter = 1; + if (!(itemKey in upstreamOptions)) { + upstreamOptions[itemKey] = [] + } + while (upstreamOptions[itemKey].includes(upstreamOptionName)) { upstreamOptionName = `${upstreamOptionName} (${counter})` } - upstreamOptions.push(upstreamOptionName) + upstreamOptions[itemKey].push(upstreamOptionName) auxNameKeyUpstreamArgsMap[upstreamOptionName] = key auxLabelUpstreamIdMap[upstreamOptionName] = upstreamId } }) } - const upstreamValue = upstreamOptions ? upstreamOptions[0] : null - const valueUpstreamId = upstreamValue && auxLabelUpstreamIdMap[upstreamValue] ? - auxLabelUpstreamIdMap[upstreamValue] : null - const upstreamArgument = upstreamValue && auxNameKeyUpstreamArgsMap[upstreamValue] - ? auxNameKeyUpstreamArgsMap[upstreamValue] : null - const auxUpstreamValue: any = {} - for (const [_key, _value] of Object.entries(upstreamMap[formId][itemKey].value[index])){ + for (let _key of Object.keys(upstreamMap[formId][itemKey].value[index])){ + const upstreamValue = upstreamOptions[_key] ? upstreamOptions[_key][0] : null + const valueUpstreamId = upstreamValue && auxLabelUpstreamIdMap[upstreamValue] ? auxLabelUpstreamIdMap[upstreamValue] : null + const upstreamArgument = upstreamValue && auxNameKeyUpstreamArgsMap[upstreamValue] ? auxNameKeyUpstreamArgsMap[upstreamValue] : null auxUpstreamValue[_key] = { fromUpstream: checked, value: upstreamValue, upstreamId: valueUpstreamId, upstreamArgument: upstreamArgument } - } + } upstreamMap[formId][itemKey].value[index] = auxUpstreamValue } setUpstreamOptions(upstreamOptions) setForageUpstreamMap(upstreamMap) }, [ + subItemSchema.properties, getForageUpstreamMap, setForageUpstreamMap, fetchForagePieceById, @@ -274,6 +314,57 @@ const ArrayInputItem: React.FC = ({ useEffect(() => { (async () => { const newElements: any = {} + const upstreamMap = await getForageUpstreamMap() + + if (!(formId in upstreamMap)) { + return + } + if (!(itemKey in upstreamMap[formId])) { + return + } + + const upstreamMapData = upstreamMap[formId][itemKey].value + + for (const i in upstreamMapData){ + const value = upstreamMapData[i] + var index = 0; + const entries: [any, any][] = Object.entries(value); + //for (let [key, _value] of Object.entries<{ value: string, upstreamId: string, upstreamArgument: string, fromUpstream: boolean }>(value)) { + for (let [key, _value] of entries) { + const formValue: string = _value.value + const upstreamId: string = _value.upstreamId + const upstreamArgument: string = _value.upstreamArgument + const fromUpstream: boolean = _value.fromUpstream + const title = arrayOfProperties[key].title + + const upstreamOptionsArray: any = upstreamOptions[key] + var inputElement = null + if (fromUpstream){ + inputElement = ( + + {`${title} [${index}]`} + + + ); + } + index = index + 1 + } + + } + + arrayItems.map((item, index) => { let itemElements: JSX.Element[] = []; // Loop through each of the item's properties and create the inputs for them @@ -287,7 +378,7 @@ const ArrayInputItem: React.FC = ({ initialValue = arrayItems[index as number]; } if (checkedFromUpstreamItemProp[index]?.[itemKey]) { - + //inputElement = (

hello

) inputElement = ( {`${_itemKey} [${index}]`} @@ -296,11 +387,11 @@ const ArrayInputItem: React.FC = ({ value={initialValue} onChange={(e) => handleSelectFromUpstreamChange(index, itemKey, e.target.value)} > - {upstreamOptions.map(option => ( + {/* {upstreamOptions[itemKey].map((option: string) => ( {option} - ))} + ))} */} ); @@ -353,11 +444,13 @@ const ArrayInputItem: React.FC = ({ > {itemElements}
) + return null; }) setRenderElements(newElements) - })() }, [ + formId, + getForageUpstreamMap, arrayOfProperties, arrayItems, checkedFromUpstreamItemProp, From 49468adcb86907a70fbf207303633da9c3b1bf89 Mon Sep 17 00:00:00 2001 From: Vinicius Date: Thu, 8 Jun 2023 15:46:56 -0300 Subject: [PATCH 089/328] wip - default value in simple forms --- .../piece-form-arrayinput-item.component.tsx | 74 +++++-------------- 1 file changed, 20 insertions(+), 54 deletions(-) diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/piece-form-arrayinput-item.component.tsx b/frontend/src/pages/private/workflows/workflows-editor/components/piece-form-arrayinput-item.component.tsx index f9f472d2..94bc7e27 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/components/piece-form-arrayinput-item.component.tsx +++ b/frontend/src/pages/private/workflows/workflows-editor/components/piece-form-arrayinput-item.component.tsx @@ -324,74 +324,39 @@ const ArrayInputItem: React.FC = ({ } const upstreamMapData = upstreamMap[formId][itemKey].value - - for (const i in upstreamMapData){ - const value = upstreamMapData[i] - var index = 0; - const entries: [any, any][] = Object.entries(value); - //for (let [key, _value] of Object.entries<{ value: string, upstreamId: string, upstreamArgument: string, fromUpstream: boolean }>(value)) { - for (let [key, _value] of entries) { - const formValue: string = _value.value - const upstreamId: string = _value.upstreamId - const upstreamArgument: string = _value.upstreamArgument - const fromUpstream: boolean = _value.fromUpstream - const title = arrayOfProperties[key].title - - const upstreamOptionsArray: any = upstreamOptions[key] - var inputElement = null - if (fromUpstream){ - inputElement = ( - - {`${title} [${index}]`} - - - ); - } - index = index + 1 - } - - } - - arrayItems.map((item, index) => { + const value = upstreamMapData[index] let itemElements: JSX.Element[] = []; // Loop through each of the item's properties and create the inputs for them - Object.keys(arrayOfProperties).map((_itemKey, subIndex) => { + Object.keys(arrayOfProperties).map((_itemKey: any, subIndex: any) => { let inputElement: JSX.Element; const subItemPropSchema = arrayOfProperties[_itemKey]; - let initialValue: any = ''; + const title = subItemPropSchema.title + + let initialValue: any = value[_itemKey].value || ''; if (typeof arrayItems[index] === 'object') { - initialValue = arrayItems[index as number][_itemKey as keyof typeof arrayItems[number]]; - } else { - initialValue = arrayItems[index as number]; + // console.log("value", _itemKey) + // console.log('entrou aq', _itemKey as keyof typeof arrayItems[number]) + // console.log('arrayItems', arrayItems[index as number]) + //initialValue = arrayItems[index as number][_itemKey as keyof typeof arrayItems[number]]; + //initialValue = value[_itemKey].value + console.log('aquii', upstreamOptions) } - if (checkedFromUpstreamItemProp[index]?.[itemKey]) { - //inputElement = (

hello

) + const upstreamOptionsArray: any = upstreamOptions[_itemKey] + if (upstreamOptionsArray && checkedFromUpstreamItemProp[index]?.[itemKey]) { inputElement = ( - {`${_itemKey} [${index}]`} + {`${title} [${index}]`} ); @@ -400,7 +365,7 @@ const ArrayInputItem: React.FC = ({ const valuesOptions: Array = parentSchemaDefinitions?.[typeClass].enum; inputElement = ( - {`${itemKey} [${index}]`} + {`${title} [${index}]`} handleSelectFromUpstreamChange(index, itemKey, e.target.value)} - > - {upstreamOptionsArray.map((option: string) => ( + Promise.all( + Object.keys(arrayOfProperties).map(async(_itemKey: any, subIndex: any) => { + let inputElement: JSX.Element; + const subItemPropSchema = arrayOfProperties[_itemKey]; + const title = subItemPropSchema.title + const checkboxValue = checkboxStates[formId][itemKey][index][_itemKey] + + // TODO this can be improved, it is slow but is working for now + // upstreamOptionsArray is undefined when user open the form for the first time + // it is generated only when user clicks on the checkbox + // it will cause a bug if the user close and open the form again since the checkbox will be checked + // but the upstreamOptionsArray will be undefined so the form will be rendered as textfield + // to solve this maybe we need to generate upstreamOptionsArray when the form is opened for the already checked checkboxes + if (upstreamOptions.length === 0 && checkboxValue) { + const results = await _handleCheckboxFromUpstreamChange(checkboxValue, index, _itemKey) + _upstreamOptions = results?.upstreamOptions + setUpstreamOptions(_upstreamOptions) + setForageUpstreamMap(results?.upstreamMap) + } + let initialValue: any = value[_itemKey].value || ''; + const upstreamOptionsArray: any = _upstreamOptions[_itemKey] + + if (upstreamOptionsArray && value[_itemKey].fromUpstream) { + inputElement = ( + + {`${title} [${index}]`} + + + ); + } else if (subItemPropSchema?.allOf && subItemPropSchema.allOf.length > 0) { + const typeClass = subItemPropSchema.allOf[0]['$ref'].split("/").pop(); + const valuesOptions: Array = parentSchemaDefinitions?.[typeClass].enum; + inputElement = ( + + {`${title} [${index}]`} + - - ); - } else if (subItemPropSchema?.allOf && subItemPropSchema.allOf.length > 0) { - const typeClass = subItemPropSchema.allOf[0]['$ref'].split("/").pop(); - const valuesOptions: Array = parentSchemaDefinitions?.[typeClass].enum; - inputElement = ( - - {`${title} [${index}]`} - - + {option} + + ))} + + + ); + } else { + inputElement = handleArrayItemChange(index, itemKey, e.target.value)} + /> + } + itemElements.push( +
+ {inputElement} + {subItemPropSchema?.from_upstream !== "never" ? ( + handleCheckboxFromUpstreamChange(event, index, _itemKey)} + disabled={subItemPropSchema?.from_upstream === 'never' || subItemPropSchema?.from_upstream === 'always'} + /> + ) : null} +
); - } else { - console.log('entrou text') - inputElement = handleArrayItemChange(index, itemKey, e.target.value)} - /> - } - itemElements.push( -
- {inputElement} - {subItemPropSchema?.from_upstream !== "never" ? ( - handleCheckboxFromUpstreamChange(event, index, _itemKey)} - disabled={subItemPropSchema?.from_upstream === 'never' || subItemPropSchema?.from_upstream === 'always'} - /> - ) : null} -
- ); - return null; - }); + return null; + })); newElements[index] = (
= ({ setRenderElements(newElements) })() }, [ + setForageUpstreamMap, + _handleCheckboxFromUpstreamChange, formId, setForageCheckboxStates, getForageCheckboxStates, From 7a5611911ea4897b4dc50d1d35167f0f95575830 Mon Sep 17 00:00:00 2001 From: Vinicius Date: Mon, 19 Jun 2023 14:01:48 -0300 Subject: [PATCH 096/328] add workflowPieces forage key to store workflow pieces schemas and metadata --- .../workflows/workflows-editor.context.tsx | 40 ++++++++++++++++++- .../workflow-editor-panel.component.tsx | 35 ++++++++++++---- 2 files changed, 67 insertions(+), 8 deletions(-) diff --git a/frontend/src/context/workflows/workflows-editor.context.tsx b/frontend/src/context/workflows/workflows-editor.context.tsx index f255ef85..52764253 100644 --- a/frontend/src/context/workflows/workflows-editor.context.tsx +++ b/frontend/src/context/workflows/workflows-editor.context.tsx @@ -70,6 +70,10 @@ interface IWorkflowsEditorContext { setForageCheckboxStates: (checkboxStatesMap: any) => Promise // TODO add type getForageCheckboxStates: () => Promise // TODO add type + setForageWorkflowPieces: (workflowPieces: any) => Promise // TODO add type + getForageWorkflowPieces: () => Promise // TODO add type + removeForageWorkflowPiecesById: (id: string) => Promise + setNameKeyUpstreamArgsMap: (nameKeyUpstreamArgsMap: any) => Promise // TODO add type getNameKeyUpstreamArgsMap: () => Promise // TODO add type clearNameKeyUpstreamArgsMap: () => Promise @@ -269,12 +273,18 @@ export const WorkflowsEditorProvider: FC = ({ chi localForage.setItem('formsData', currentData); }, []) + const clearForageWorkflowPieces = useCallback(async () => { + await localForage.setItem('workflowPieces', {}) + }, []) + + const clearForageData = useCallback(async () => { await localForage.setItem('formsData', {}) await clearForageUpstreamMap() await clearForageCheckboxStates() await clearNameKeyUpstreamArgsMap() - }, [clearForageUpstreamMap, clearForageCheckboxStates, clearNameKeyUpstreamArgsMap]) + await clearForageWorkflowPieces() + }, [clearForageUpstreamMap, clearForageCheckboxStates, clearNameKeyUpstreamArgsMap, clearForageWorkflowPieces]) const setForageWorkflowNodes = useCallback(async (nodes: IWorkflowElement[]) => { await localForage.setItem('workflowNodes', nodes) @@ -300,6 +310,28 @@ export const WorkflowsEditorProvider: FC = ({ chi return workflowEdges }, []) + const setForageWorkflowPieces = useCallback(async (workflowPieces: any) => { + await localForage.setItem('workflowPieces', workflowPieces) + }, []) + + const getForageWorkflowPieces = useCallback(async () => { + const workflowPieces = await localForage.getItem("workflowPieces") + if (!workflowPieces) { + return {} + } + return workflowPieces + }, []) + + const removeForageWorkflowPiecesById = useCallback(async (id: string) => { + const workflowPieces = await localForage.getItem("workflowPieces") + if (!workflowPieces) { + return + } + delete workflowPieces[id] + await localForage.setItem('workflowPieces', workflowPieces) + }, []) + + useEffect(() => { (async () => { const forageNodes = await fetchForageWorkflowNodes() @@ -495,6 +527,9 @@ export const WorkflowsEditorProvider: FC = ({ chi nodeDirection, setForageCheckboxStates, getForageCheckboxStates, + setForageWorkflowPieces, + getForageWorkflowPieces, + removeForageWorkflowPiecesById, setNameKeyUpstreamArgsMap, getNameKeyUpstreamArgsMap, clearNameKeyUpstreamArgsMap, @@ -531,6 +566,9 @@ export const WorkflowsEditorProvider: FC = ({ chi setNodes, setForageCheckboxStates, getForageCheckboxStates, + setForageWorkflowPieces, + getForageWorkflowPieces, + removeForageWorkflowPiecesById, setNameKeyUpstreamArgsMap, getNameKeyUpstreamArgsMap, clearNameKeyUpstreamArgsMap diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/workflow-editor-panel.component.tsx b/frontend/src/pages/private/workflows/workflows-editor/components/workflow-editor-panel.component.tsx index 3781e562..ade346d4 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/components/workflow-editor-panel.component.tsx +++ b/frontend/src/pages/private/workflows/workflows-editor/components/workflow-editor-panel.component.tsx @@ -59,6 +59,9 @@ const WorkflowEditorPanelComponent = () => { fetchForageWorkflowEdges, getForageUpstreamMap, setForageUpstreamMap, + setForageWorkflowPieces, + getForageWorkflowPieces, + removeForageWorkflowPiecesById, } = useWorkflowsEditor() // Removing flowchart elements @@ -66,17 +69,18 @@ const WorkflowEditorPanelComponent = () => { for (const node of nodes) { await removeFormsForageDataById(node.id) await removeForageUpstreamMapById(node.id) + await removeForageWorkflowPiecesById(node.id) } - }, [removeFormsForageDataById, removeForageUpstreamMapById]) + }, [removeFormsForageDataById, removeForageUpstreamMapById, removeForageWorkflowPiecesById]) // Node double click open drawer with forms const onNodeDoubleClick = useCallback(async (event: any, node: any) => { - const operatorNode = await fetchForagePieceById(node.id.split('_')[0]) + const pieceNode = await fetchForagePieceById(node.id.split('_')[0]) - setFormSchema(operatorNode?.input_schema) + setFormSchema(pieceNode?.input_schema) setFormId(node.id) - setFormTitle(() => { return operatorNode?.name ? operatorNode?.name : "" }) + setFormTitle(() => { return pieceNode?.name ? pieceNode?.name : "" }) setDrawerState(true) }, [fetchForagePieceById]) @@ -130,11 +134,18 @@ const WorkflowEditorPanelComponent = () => { } setNodes((ns: Node[]) => ns.concat(newNode)) - const operator = await fetchForagePieceById(data.id) - const inputSchema = operator?.input_schema + const piece = await fetchForagePieceById(data.id) + const inputSchema = piece?.input_schema const defaultData: any = extractDefaultValues(inputSchema) const containerResourcesDefaultData: unknown = extractDefaultValues(containerResourcesSchema) + const currentWorkflowPieces = await getForageWorkflowPieces() + const newWorkflowPieces = { + ...currentWorkflowPieces, + [newNode.id]: piece + } + await setForageWorkflowPieces(newWorkflowPieces) + // Set default data for upstream mapping - used in dags var upstreamMap = await getForageUpstreamMap() var upstreamMapFormInfo: any = {} @@ -186,7 +197,17 @@ const WorkflowEditorPanelComponent = () => { defaultData['containerResources'] = containerResourcesDefaultData // Set default data for the node form - used in json-forms await setFormsForageData(newNode.id, defaultData) - }, [fetchForagePieceById, nodeDirection, setFormsForageData, setForageUpstreamMap, getForageUpstreamMap, reactFlowInstance, setNodes]) + }, [ + fetchForagePieceById, + nodeDirection, + setFormsForageData, + setForageUpstreamMap, + getForageUpstreamMap, + reactFlowInstance, + setNodes, + setForageWorkflowPieces, + getForageWorkflowPieces + ]) // Left drawer controls // @ts-ignore: Unreachable code error From 2eec823021b28b2271a2fc90b06190e2f2f09b52 Mon Sep 17 00:00:00 2001 From: Vinicius Date: Mon, 19 Jun 2023 14:09:43 -0300 Subject: [PATCH 097/328] using new key schema when open forms --- .../src/context/workflows/workflows-editor.context.tsx | 10 ++++++++++ .../components/workflow-editor-panel.component.tsx | 7 ++++--- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/frontend/src/context/workflows/workflows-editor.context.tsx b/frontend/src/context/workflows/workflows-editor.context.tsx index 52764253..5f6ad43a 100644 --- a/frontend/src/context/workflows/workflows-editor.context.tsx +++ b/frontend/src/context/workflows/workflows-editor.context.tsx @@ -73,6 +73,7 @@ interface IWorkflowsEditorContext { setForageWorkflowPieces: (workflowPieces: any) => Promise // TODO add type getForageWorkflowPieces: () => Promise // TODO add type removeForageWorkflowPiecesById: (id: string) => Promise + fetchWorkflowPieceById: (id: string) => Promise // TODO add type setNameKeyUpstreamArgsMap: (nameKeyUpstreamArgsMap: any) => Promise // TODO add type getNameKeyUpstreamArgsMap: () => Promise // TODO add type @@ -331,6 +332,13 @@ export const WorkflowsEditorProvider: FC = ({ chi await localForage.setItem('workflowPieces', workflowPieces) }, []) + const fetchWorkflowPieceById = useCallback(async (id: string) => { + const workflowPieces = await localForage.getItem("workflowPieces") + if (workflowPieces !== null) { + return workflowPieces[id] + } + }, []) + useEffect(() => { (async () => { @@ -530,6 +538,7 @@ export const WorkflowsEditorProvider: FC = ({ chi setForageWorkflowPieces, getForageWorkflowPieces, removeForageWorkflowPiecesById, + fetchWorkflowPieceById, setNameKeyUpstreamArgsMap, getNameKeyUpstreamArgsMap, clearNameKeyUpstreamArgsMap, @@ -569,6 +578,7 @@ export const WorkflowsEditorProvider: FC = ({ chi setForageWorkflowPieces, getForageWorkflowPieces, removeForageWorkflowPiecesById, + fetchWorkflowPieceById, setNameKeyUpstreamArgsMap, getNameKeyUpstreamArgsMap, clearNameKeyUpstreamArgsMap diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/workflow-editor-panel.component.tsx b/frontend/src/pages/private/workflows/workflows-editor/components/workflow-editor-panel.component.tsx index ade346d4..3c61dd83 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/components/workflow-editor-panel.component.tsx +++ b/frontend/src/pages/private/workflows/workflows-editor/components/workflow-editor-panel.component.tsx @@ -62,6 +62,7 @@ const WorkflowEditorPanelComponent = () => { setForageWorkflowPieces, getForageWorkflowPieces, removeForageWorkflowPiecesById, + fetchWorkflowPieceById } = useWorkflowsEditor() // Removing flowchart elements @@ -76,13 +77,13 @@ const WorkflowEditorPanelComponent = () => { // Node double click open drawer with forms const onNodeDoubleClick = useCallback(async (event: any, node: any) => { - const pieceNode = await fetchForagePieceById(node.id.split('_')[0]) - + //const pieceNode = await fetchForagePieceById(node.id.split('_')[0]) + const pieceNode = await fetchWorkflowPieceById(node.id) setFormSchema(pieceNode?.input_schema) setFormId(node.id) setFormTitle(() => { return pieceNode?.name ? pieceNode?.name : "" }) setDrawerState(true) - }, [fetchForagePieceById]) + }, [fetchWorkflowPieceById]) const onLoad = useCallback(async (_reactFlowInstance: any) => { setReactFlowInstance(_reactFlowInstance) From 275eecf107eeb9de9474cf6c58a250634029090b Mon Sep 17 00:00:00 2001 From: Vinicius Date: Wed, 21 Jun 2023 07:39:33 -0300 Subject: [PATCH 098/328] fix forms parent upstream check --- .../piece-form-arrayinput-item.component.tsx | 35 +++++++++++++------ .../components/piece-form-item.component.tsx | 29 +++++++++++++++ 2 files changed, 54 insertions(+), 10 deletions(-) diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/piece-form-arrayinput-item.component.tsx b/frontend/src/pages/private/workflows/workflows-editor/components/piece-form-arrayinput-item.component.tsx index e97e7e9a..c8efbf64 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/components/piece-form-arrayinput-item.component.tsx +++ b/frontend/src/pages/private/workflows/workflows-editor/components/piece-form-arrayinput-item.component.tsx @@ -100,7 +100,6 @@ const ArrayInputItem: React.FC = ({ const handleArrayItemChange = useCallback((index: number, itemKey: string, value: string) => { - console.log('handleArrayItemChange') const updatedItems = [...arrayItems]; updatedItems[index][itemKey] = value; onChange(updatedItems); @@ -239,6 +238,7 @@ const ArrayInputItem: React.FC = ({ toast.error('This piece has no upstreams.') return } + for (var i=0; i = ({ // FromUpstream select logic const handleSelectFromUpstreamChange = useCallback((index: number, itemKey: string, value: string) => { - console.log('handleSelectFromUpstreamChange') const updatedItems = [...arrayItems]; if (typeof updatedItems[index] === 'object') { updatedItems[index][itemKey] = value; @@ -372,7 +371,7 @@ const ArrayInputItem: React.FC = ({ checkboxStates[formId] = {} } - if (!(itemKey in checkboxStates[formId])) { + if ((!(itemKey in checkboxStates[formId])) || typeof checkboxStates[formId][itemKey] !== 'object') { checkboxStates[formId][itemKey] = [] for (let i = 0; i < arrayItems.length; i++) { const newObj: any = {} @@ -383,7 +382,7 @@ const ArrayInputItem: React.FC = ({ } setForageCheckboxStates(checkboxStates) } - + if (!(formId in upstreamMap)) { return } @@ -392,8 +391,10 @@ const ArrayInputItem: React.FC = ({ } var _upstreamOptions = upstreamOptions - const upstreamMapData = upstreamMap[formId][itemKey].value + if (typeof upstreamMapData !== 'object') { + return + } arrayItems.map((item, index) => { const value = upstreamMapData[index] let itemElements: JSX.Element[] = []; @@ -401,9 +402,18 @@ const ArrayInputItem: React.FC = ({ Promise.all( Object.keys(arrayOfProperties).map(async(_itemKey: any, subIndex: any) => { let inputElement: JSX.Element; + const subItemPropSchema = arrayOfProperties[_itemKey]; const title = subItemPropSchema.title - const checkboxValue = checkboxStates[formId][itemKey][index][_itemKey] + const checkboxFormState = checkboxStates[formId][itemKey] + var checkboxValue = false; + var isParentChecked = false; + if (typeof checkboxFormState === 'boolean'){ + isParentChecked = true + } + if (!(typeof checkboxFormState === 'boolean')){ + checkboxValue = checkboxStates[formId][itemKey][index][_itemKey] + } // TODO this can be improved, it is slow but is working for now // upstreamOptionsArray is undefined when user open the form for the first time @@ -411,16 +421,20 @@ const ArrayInputItem: React.FC = ({ // it will cause a bug if the user close and open the form again since the checkbox will be checked // but the upstreamOptionsArray will be undefined so the form will be rendered as textfield // to solve this maybe we need to generate upstreamOptionsArray when the form is opened for the already checked checkboxes - if (upstreamOptions.length === 0 && checkboxValue) { + if (upstreamOptions.length === 0 && typeof checkboxFormState !== 'boolean' && checkboxValue) { const results = await _handleCheckboxFromUpstreamChange(checkboxValue, index, _itemKey) _upstreamOptions = results?.upstreamOptions setUpstreamOptions(_upstreamOptions) setForageUpstreamMap(results?.upstreamMap) } - let initialValue: any = value[_itemKey].value || ''; - const upstreamOptionsArray: any = _upstreamOptions[_itemKey] + var initialValue: any = '' + var upstreamOptionsArray: any = [] + if (!isParentChecked){ + initialValue = value[_itemKey].value || ''; + upstreamOptionsArray = _upstreamOptions[_itemKey] + } - if (upstreamOptionsArray && value[_itemKey].fromUpstream) { + if (!isParentChecked && (upstreamOptionsArray && value[_itemKey].fromUpstream)) { inputElement = ( {`${title} [${index}]`} @@ -488,6 +502,7 @@ const ArrayInputItem: React.FC = ({
) return null; }) + setRenderElements(newElements) })() }, [ diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/piece-form-item.component.tsx b/frontend/src/pages/private/workflows/workflows-editor/components/piece-form-item.component.tsx index 3325f5b8..c35fc04f 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/components/piece-form-item.component.tsx +++ b/frontend/src/pages/private/workflows/workflows-editor/components/piece-form-item.component.tsx @@ -208,6 +208,35 @@ const PieceFormItem: React.FC = ({ formId, schema, itemKey, auxLabelUpstreamIdMap[upstreamValue] : null const upstreamArgument = upstreamValue && auxNameKeyUpstreamArgsMap[upstreamValue] ? auxNameKeyUpstreamArgsMap[upstreamValue] : null + + if (Array.isArray(upstreamValue)) { + const auxValues = [] + for (const element of upstreamValue) { + const newValue: any = {} + if (typeof element === 'object') { + for (const [_key, _value] of Object.entries(element)) { + newValue[_key] = { + fromUpstream: upstreamMap[formId][itemKey].fromUpstream, + upstreamId: upstreamId, + upstreamArgument: null, + value: _value + } + } + auxValues.push(newValue) + } else { + newValue[itemKey] = { + fromUpstream: upstreamMap[formId][itemKey].fromUpstream, + upstreamId: upstreamId, + upstreamArgument: null, + value: element + } + auxValues.push(newValue) + } + } + upstreamValue = auxValues + } + + upstreamMap[formId][itemKey] = { ...upstreamMap[formId][itemKey], upstreamId: upstreamId, From 9ba0f454063bf627944c4a13f6c4157885aa4135 Mon Sep 17 00:00:00 2001 From: Vinicius Date: Wed, 21 Jun 2023 08:04:34 -0300 Subject: [PATCH 099/328] delete item for no checked --- .../piece-form-arrayinput-item.component.tsx | 28 +++++++++++++++++-- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/piece-form-arrayinput-item.component.tsx b/frontend/src/pages/private/workflows/workflows-editor/components/piece-form-arrayinput-item.component.tsx index c8efbf64..6423b45d 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/components/piece-form-arrayinput-item.component.tsx +++ b/frontend/src/pages/private/workflows/workflows-editor/components/piece-form-arrayinput-item.component.tsx @@ -165,14 +165,36 @@ const ArrayInputItem: React.FC = ({ ]); // TODO - this is not working when deleting items with fromUpstrem checked - const handleDeleteItem = (index: number) => { + const handleDeleteItem = useCallback(async(index: number) => { + const upstreamMap = await getForageUpstreamMap() + const currentValues = upstreamMap[formId][itemKey].value + currentValues.splice(index, 1) + await setForageUpstreamMap({ + ...upstreamMap, + [formId]: { + ...upstreamMap[formId], + [itemKey]: { + ...upstreamMap[formId][itemKey], + value: currentValues + } + } + }) const updatedItems = [...arrayItems]; updatedItems.splice(index, 1); - onChange(updatedItems); const updatedCheckedFromUpstreamItemProp = [...checkedFromUpstreamItemProp]; updatedCheckedFromUpstreamItemProp.splice(index, 1); setCheckedFromUpstreamItemProp(updatedCheckedFromUpstreamItemProp); - }; + onChange(updatedItems); + + }, [ + onChange, + arrayItems, + checkedFromUpstreamItemProp, + itemKey, + formId, + getForageUpstreamMap, + setForageUpstreamMap + ]); From d3159eeac6c7768f83f5c139fdd74a77b587520e Mon Sep 17 00:00:00 2001 From: Vinicius Date: Wed, 21 Jun 2023 08:07:38 -0300 Subject: [PATCH 100/328] delete checked item --- .../piece-form-arrayinput-item.component.tsx | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/piece-form-arrayinput-item.component.tsx b/frontend/src/pages/private/workflows/workflows-editor/components/piece-form-arrayinput-item.component.tsx index 6423b45d..985441de 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/components/piece-form-arrayinput-item.component.tsx +++ b/frontend/src/pages/private/workflows/workflows-editor/components/piece-form-arrayinput-item.component.tsx @@ -166,6 +166,18 @@ const ArrayInputItem: React.FC = ({ // TODO - this is not working when deleting items with fromUpstrem checked const handleDeleteItem = useCallback(async(index: number) => { + + const currentCheckboxStates = await getForageCheckboxStates() + const currentCheckboxStatesArray = currentCheckboxStates[formId][itemKey] + currentCheckboxStatesArray.splice(index, 1) + await setForageCheckboxStates({ + ...currentCheckboxStates, + [formId]: { + ...currentCheckboxStates[formId], + [itemKey]: currentCheckboxStatesArray + } + }) + const upstreamMap = await getForageUpstreamMap() const currentValues = upstreamMap[formId][itemKey].value currentValues.splice(index, 1) @@ -193,7 +205,9 @@ const ArrayInputItem: React.FC = ({ itemKey, formId, getForageUpstreamMap, - setForageUpstreamMap + setForageUpstreamMap, + getForageCheckboxStates, + setForageCheckboxStates ]); From 42a19400a8574af76ef1cd4227ff2e98f2c9a2eb Mon Sep 17 00:00:00 2001 From: Vinicius Date: Wed, 21 Jun 2023 11:48:20 -0300 Subject: [PATCH 101/328] checkbox states on delete and add --- .../piece-form-arrayinput-item.component.tsx | 22 ++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/piece-form-arrayinput-item.component.tsx b/frontend/src/pages/private/workflows/workflows-editor/components/piece-form-arrayinput-item.component.tsx index 985441de..fb0f095d 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/components/piece-form-arrayinput-item.component.tsx +++ b/frontend/src/pages/private/workflows/workflows-editor/components/piece-form-arrayinput-item.component.tsx @@ -149,6 +149,19 @@ const ArrayInputItem: React.FC = ({ } } } + + const checkboxStates = await getForageCheckboxStates() + const checkboxStatesArray = checkboxStates[formId][itemKey] + checkboxStatesArray.push(newItemPropsChecked[itemKey]) + await setForageCheckboxStates({ + ...checkboxStates, + [formId]: { + ...checkboxStates[formId], + [itemKey]: checkboxStatesArray + } + }) + + setForageUpstreamMap(updatedUpstreaMap) setCheckedFromUpstreamItemProp([...checkedFromUpstreamItemProp, newItemPropsChecked]); onChange([...arrayItems, newItemDefaultValue]); @@ -161,7 +174,9 @@ const ArrayInputItem: React.FC = ({ itemKey, formId, getForageUpstreamMap, - setForageUpstreamMap + setForageUpstreamMap, + getForageCheckboxStates, + setForageCheckboxStates ]); // TODO - this is not working when deleting items with fromUpstrem checked @@ -207,7 +222,7 @@ const ArrayInputItem: React.FC = ({ getForageUpstreamMap, setForageUpstreamMap, getForageCheckboxStates, - setForageCheckboxStates + setForageCheckboxStates, ]); @@ -428,9 +443,10 @@ const ArrayInputItem: React.FC = ({ var _upstreamOptions = upstreamOptions const upstreamMapData = upstreamMap[formId][itemKey].value - if (typeof upstreamMapData !== 'object') { + if ((typeof upstreamMapData !== 'object') || (checkboxStates[formId][itemKey].length === 0) || (checkboxStates[formId][itemKey].length !== arrayItems.length)) { return } + arrayItems.map((item, index) => { const value = upstreamMapData[index] let itemElements: JSX.Element[] = []; From 1b8fd8d016225e3dd34f7438a2a390b61a1174d5 Mon Sep 17 00:00:00 2001 From: Vinicius Date: Wed, 28 Jun 2023 08:59:00 -0300 Subject: [PATCH 102/328] fix keep parent checkbox --- .../workflows-editor/components/piece-form-item.component.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/piece-form-item.component.tsx b/frontend/src/pages/private/workflows/workflows-editor/components/piece-form-item.component.tsx index c35fc04f..8eef78d6 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/components/piece-form-item.component.tsx +++ b/frontend/src/pages/private/workflows/workflows-editor/components/piece-form-item.component.tsx @@ -271,10 +271,10 @@ const PieceFormItem: React.FC = ({ formId, schema, itemKey, if (!(formId in auxCheckboxState)) { return } - if (formFieldType === 'array'){ + const formCheckboxStates = auxCheckboxState[formId] + if (formFieldType === 'array' && typeof formCheckboxStates[itemKey] !== 'boolean'){ return } - const formCheckboxStates = auxCheckboxState[formId] if (itemKey in formCheckboxStates) { await handleCheckboxFromUpstreamChange(formCheckboxStates[itemKey], false) } else { From d4807247a4c2816b17be61187cdae795c935c2bf Mon Sep 17 00:00:00 2001 From: Nathan Vieira Marcelino Date: Thu, 29 Jun 2023 14:29:35 -0300 Subject: [PATCH 103/328] chore: add and update frontend dependencies - add yup for validation - update react-hook-form - remove root react dependencie --- frontend/package.json | 8 ++- frontend/yarn.lock | 70 ++++++++++++++++++++++---- package.json | 5 -- yarn.lock | 114 ------------------------------------------ 4 files changed, 65 insertions(+), 132 deletions(-) delete mode 100644 package.json delete mode 100644 yarn.lock diff --git a/frontend/package.json b/frontend/package.json index cff6a499..9a8468ff 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -2,6 +2,9 @@ "name": "domino", "version": "0.1.0", "private": true, + "engines": { + "node": ">=18 < 20" + }, "dependencies": { "@babel/core": "^7.20.5", "@babel/plugin-syntax-flow": "^7.18.6", @@ -36,7 +39,7 @@ "react-datepicker": "^4.8.0", "react-dom": "^18.2.0", "react-draggable": "^4.4.5", - "react-hook-form": "^7.41.0", + "react-hook-form": "^7.45.1", "react-markdown": "^8.0.7", "react-router-dom": "^6.6.0", "react-scripts": "^5.0.1", @@ -44,7 +47,8 @@ "reactflow": "^11.4.0", "swr": "^2.0.0", "typescript": "^4.9.4", - "uuid": "^9.0.0" + "uuid": "^9.0.0", + "yup": "^1.2.0" }, "scripts": { "start": "cross-env REACT_APP_API_ENV=dev react-scripts start", diff --git a/frontend/yarn.lock b/frontend/yarn.lock index 03500ebd..e1373e4a 100644 --- a/frontend/yarn.lock +++ b/frontend/yarn.lock @@ -1042,6 +1042,13 @@ dependencies: regenerator-runtime "^0.13.11" +"@babel/runtime@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.22.5.tgz#8564dd588182ce0047d55d7a75e93921107b57ec" + integrity sha512-ecjvYlnAaZ/KVneE/OdKYBYfgXV3Ptu6zQWmgEF7vwKhQnvVS6bjMD2XYgj+SNvQ1GfK/pjgokfPkC/2CO8CuA== + dependencies: + regenerator-runtime "^0.13.11" + "@babel/template@^7.18.10", "@babel/template@^7.3.3": version "7.18.10" resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.18.10.tgz#6f9134835970d1dbf0835c0d100c9f38de0c5e71" @@ -1822,7 +1829,18 @@ resolved "https://registry.yarnpkg.com/@mui/types/-/types-7.2.3.tgz#06faae1c0e2f3a31c86af6f28b3a4a42143670b9" integrity sha512-tZ+CQggbe9Ol7e/Fs5RcKwg/woU+o8DCtOnccX6KmbBc7YrfqMYEYuaIcXHuhpT880QwNkZZ3wQwvtlDFA2yOw== -"@mui/utils@^5.10.3", "@mui/utils@^5.11.1": +"@mui/utils@^5.10.3": + version "5.13.6" + resolved "https://registry.yarnpkg.com/@mui/utils/-/utils-5.13.6.tgz#aa29d75de59577585b9f23891b03592d40459ed7" + integrity sha512-ggNlxl5NPSbp+kNcQLmSig6WVB0Id+4gOxhx644987v4fsji+CSXc+MFYLocFB/x4oHtzCUlSzbVHlJfP/fXoQ== + dependencies: + "@babel/runtime" "^7.22.5" + "@types/prop-types" "^15.7.5" + "@types/react-is" "^18.2.0" + prop-types "^15.8.1" + react-is "^18.2.0" + +"@mui/utils@^5.11.1": version "5.11.1" resolved "https://registry.yarnpkg.com/@mui/utils/-/utils-5.11.1.tgz#8d12b3c2245efd9a1c0595658dcb4c86f6625206" integrity sha512-lMAPgIJoil8V9ZxsMbEflMsvZmWcHbRVMc4JDY9jPO9V4welpF43h/O267b1RqlcRnC5MEbVQV605GYkTZY29Q== @@ -1845,9 +1863,9 @@ react-is "^18.2.0" "@mui/x-data-grid@^5.17.16": - version "5.17.16" - resolved "https://registry.yarnpkg.com/@mui/x-data-grid/-/x-data-grid-5.17.16.tgz#4e05a014467bbee68385b5bee1e75004ba0178a3" - integrity sha512-tzgjvO0DgiYWqU9soM6ORurtOrNsqpmdRxIjqJguLHxs2nP5hyhGEDRaHQIfEPv9eXNl9QL3kBO3VfgaFS5NPg== + version "5.17.26" + resolved "https://registry.yarnpkg.com/@mui/x-data-grid/-/x-data-grid-5.17.26.tgz#1f7fa73dd3986cf052e2fd2cb56eb4678a7bd913" + integrity sha512-eGJq9J0g9cDGLFfMmugOadZx0mJeOd/yQpHwEa5gUXyONS6qF0OhXSWyDOhDdA3l2TOoQzotMN5dY/T4Wl1KYA== dependencies: "@babel/runtime" "^7.18.9" "@mui/utils" "^5.10.3" @@ -8741,6 +8759,11 @@ prop-types@^15.0.0, prop-types@^15.6.2, prop-types@^15.7.2, prop-types@^15.8.1: object-assign "^4.1.1" react-is "^16.13.1" +property-expr@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/property-expr/-/property-expr-2.0.5.tgz#278bdb15308ae16af3e3b9640024524f4dc02cb4" + integrity sha512-IJUkICM5dP5znhCckHSv30Q4b5/JA5enCtkRHYaOVOAocnH/1BQEYTC5NMfT3AVl/iXKdr3aqQbQn9DxyWknwA== + property-information@^6.0.0: version "6.2.0" resolved "https://registry.yarnpkg.com/property-information/-/property-information-6.2.0.tgz#b74f522c31c097b5149e3c3cb8d7f3defd986a1d" @@ -8921,10 +8944,10 @@ react-fast-compare@^3.0.1: resolved "https://registry.yarnpkg.com/react-fast-compare/-/react-fast-compare-3.2.0.tgz#641a9da81b6a6320f270e89724fb45a0b39e43bb" integrity sha512-rtGImPZ0YyLrscKI9xTpV8psd6I8VAtjKCzQDlzyDvqJA8XOW78TXYQwNRNd8g8JZnDu8q9Fu/1v4HPAVwVdHA== -react-hook-form@^7.41.0: - version "7.41.0" - resolved "https://registry.yarnpkg.com/react-hook-form/-/react-hook-form-7.41.0.tgz#cc0871f4784e7233ac8466300da557d622154414" - integrity sha512-u1cHOXujr+AsNBoeCtcCuRwPh87mXAgKtXqd3qTCBgNFYzVZLXjYgLcynORpAgqhe24r5scucR8+6gfWaXBtHQ== +react-hook-form@^7.45.1: + version "7.45.1" + resolved "https://registry.yarnpkg.com/react-hook-form/-/react-hook-form-7.45.1.tgz#e352c7f4dbc7540f0756abbb4dcfd1122fecc9bb" + integrity sha512-6dWoFJwycbuFfw/iKMcl+RdAOAOHDiF11KWYhNDRN/OkUt+Di5qsZHwA0OwsVnu9y135gkHpTw9DJA+WzCeR9w== react-is@^16.13.1, react-is@^16.7.0: version "16.13.1" @@ -9297,9 +9320,9 @@ requires-port@^1.0.0: integrity sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ== reselect@^4.1.6: - version "4.1.7" - resolved "https://registry.yarnpkg.com/reselect/-/reselect-4.1.7.tgz#56480d9ff3d3188970ee2b76527bd94a95567a42" - integrity sha512-Zu1xbUt3/OPwsXL46hvOOoQrap2azE7ZQbokq61BQfiXvhewsKDwhMeZjTX9sX0nvw1t/U5Audyn1I9P/m9z0A== + version "4.1.8" + resolved "https://registry.yarnpkg.com/reselect/-/reselect-4.1.8.tgz#3f5dc671ea168dccdeb3e141236f69f02eaec524" + integrity sha512-ab9EmR80F/zQTMNeneUr4cv+jSwPJgIlvEmVwLerwrWVbpLlBuls9XHzIeTFy4cegU2NHBp3va0LKOzU5qFEYQ== resolve-cwd@^3.0.0: version "3.0.0" @@ -10124,6 +10147,11 @@ thunky@^1.0.2: resolved "https://registry.yarnpkg.com/thunky/-/thunky-1.1.0.tgz#5abaf714a9405db0504732bbccd2cedd9ef9537d" integrity sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA== +tiny-case@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/tiny-case/-/tiny-case-1.0.3.tgz#d980d66bc72b5d5a9ca86fb7c9ffdb9c898ddd03" + integrity sha512-Eet/eeMhkO6TX8mnUteS9zgPbUMQa4I6Kkp5ORiBD5476/m+PIRiumP5tmh5ioJpH7k51Kehawy2UDfsnxxY8Q== + tiny-inflate@^1.0.0, tiny-inflate@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/tiny-inflate/-/tiny-inflate-1.0.3.tgz#122715494913a1805166aaf7c93467933eea26c4" @@ -10156,6 +10184,11 @@ toidentifier@1.0.1: resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.1.tgz#3be34321a88a820ed1bd80dfaa33e479fbb8dd35" integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA== +toposort@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/toposort/-/toposort-2.0.2.tgz#ae21768175d1559d48bef35420b2f4962f09c330" + integrity sha512-0a5EOkAUp8D4moMi2W8ZF8jcga7BgZd91O/yabJCFY8az+XSzeGyTKs0Aoo897iV1Nj6guFq8orWDS96z91oGg== + tough-cookie@^4.0.0: version "4.1.2" resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-4.1.2.tgz#e53e84b85f24e0b65dd526f46628db6c85f6b874" @@ -10266,6 +10299,11 @@ type-fest@^0.21.3: resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.21.3.tgz#d260a24b0198436e133fa26a524a6d65fa3b2e37" integrity sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w== +type-fest@^2.19.0: + version "2.19.0" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-2.19.0.tgz#88068015bb33036a598b952e55e9311a60fd3a9b" + integrity sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA== + type-is@~1.6.18: version "1.6.18" resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131" @@ -11070,6 +11108,16 @@ yocto-queue@^0.1.0: resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== +yup@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/yup/-/yup-1.2.0.tgz#9e51af0c63bdfc9be0fdc6c10aa0710899d8aff6" + integrity sha512-PPqYKSAXjpRCgLgLKVGPA33v5c/WgEx3wi6NFjIiegz90zSwyMpvTFp/uGcVnnbx6to28pgnzp/q8ih3QRjLMQ== + dependencies: + property-expr "^2.0.5" + tiny-case "^1.0.3" + toposort "^2.0.2" + type-fest "^2.19.0" + zustand@^4.1.1: version "4.1.5" resolved "https://registry.yarnpkg.com/zustand/-/zustand-4.1.5.tgz#7402b511f5b23ccb0f9ba6d20ae01ec817e16eb6" diff --git a/package.json b/package.json deleted file mode 100644 index c9d2ec99..00000000 --- a/package.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "dependencies": { - "@mui/x-data-grid": "^6.4.0" - } -} diff --git a/yarn.lock b/yarn.lock deleted file mode 100644 index 8c3d2881..00000000 --- a/yarn.lock +++ /dev/null @@ -1,114 +0,0 @@ -# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. -# yarn lockfile v1 - - -"@babel/runtime@^7.21.0": - version "7.21.5" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.21.5.tgz#8492dddda9644ae3bda3b45eabe87382caee7200" - integrity sha512-8jI69toZqqcsnqGGqwGS4Qb1VwLOEp4hz+CXPywcvjs60u3B4Pom/U/7rm4W8tMOYEB+E9wgD0mW1l3r8qlI9Q== - dependencies: - regenerator-runtime "^0.13.11" - -"@mui/utils@^5.12.3": - version "5.13.1" - resolved "https://registry.yarnpkg.com/@mui/utils/-/utils-5.13.1.tgz#86199e46014215f95da046a5ec803f4a39c96eee" - integrity sha512-6lXdWwmlUbEU2jUI8blw38Kt+3ly7xkmV9ljzY4Q20WhsJMWiNry9CX8M+TaP/HbtuyR8XKsdMgQW7h7MM3n3A== - dependencies: - "@babel/runtime" "^7.21.0" - "@types/prop-types" "^15.7.5" - "@types/react-is" "^18.2.0" - prop-types "^15.8.1" - react-is "^18.2.0" - -"@mui/x-data-grid@^6.4.0": - version "6.4.0" - resolved "https://registry.yarnpkg.com/@mui/x-data-grid/-/x-data-grid-6.4.0.tgz#1ce476c9a213e0e651288ff3384b2bf43f5d238f" - integrity sha512-rFpjJh4ZTJW3JnjmTsn5B32PMMJtjxTdRZyjn3Re5K/BA/iJQvN1qHO26qoqbo4Vt3b3dbRLThM/Q0N59PL2Fw== - dependencies: - "@babel/runtime" "^7.21.0" - "@mui/utils" "^5.12.3" - clsx "^1.2.1" - prop-types "^15.8.1" - reselect "^4.1.8" - -"@types/prop-types@*", "@types/prop-types@^15.7.5": - version "15.7.5" - resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.5.tgz#5f19d2b85a98e9558036f6a3cacc8819420f05cf" - integrity sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w== - -"@types/react-is@^18.2.0": - version "18.2.0" - resolved "https://registry.yarnpkg.com/@types/react-is/-/react-is-18.2.0.tgz#2f5137853a46017b3d56447940fb3eb92bbf24a5" - integrity sha512-1vz2yObaQkLL7YFe/pme2cpvDsCwI1WXIfL+5eLz0MI9gFG24Re16RzUsI8t9XZn9ZWvgLNDrJBmrqXJO7GNQQ== - dependencies: - "@types/react" "*" - -"@types/react@*": - version "18.2.6" - resolved "https://registry.yarnpkg.com/@types/react/-/react-18.2.6.tgz#5cd53ee0d30ffc193b159d3516c8c8ad2f19d571" - integrity sha512-wRZClXn//zxCFW+ye/D2qY65UsYP1Fpex2YXorHc8awoNamkMZSvBxwxdYVInsHOZZd2Ppq8isnSzJL5Mpf8OA== - dependencies: - "@types/prop-types" "*" - "@types/scheduler" "*" - csstype "^3.0.2" - -"@types/scheduler@*": - version "0.16.3" - resolved "https://registry.yarnpkg.com/@types/scheduler/-/scheduler-0.16.3.tgz#cef09e3ec9af1d63d2a6cc5b383a737e24e6dcf5" - integrity sha512-5cJ8CB4yAx7BH1oMvdU0Jh9lrEXyPkar6F9G/ERswkCuvP4KQZfZkSjcMbAICCpQTN4OuZn8tz0HiKv9TGZgrQ== - -clsx@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/clsx/-/clsx-1.2.1.tgz#0ddc4a20a549b59c93a4116bb26f5294ca17dc12" - integrity sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg== - -csstype@^3.0.2: - version "3.1.2" - resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.1.2.tgz#1d4bf9d572f11c14031f0436e1c10bc1f571f50b" - integrity sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ== - -"js-tokens@^3.0.0 || ^4.0.0": - version "4.0.0" - resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" - integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== - -loose-envify@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" - integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q== - dependencies: - js-tokens "^3.0.0 || ^4.0.0" - -object-assign@^4.1.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" - integrity sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg== - -prop-types@^15.8.1: - version "15.8.1" - resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.8.1.tgz#67d87bf1a694f48435cf332c24af10214a3140b5" - integrity sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg== - dependencies: - loose-envify "^1.4.0" - object-assign "^4.1.1" - react-is "^16.13.1" - -react-is@^16.13.1: - version "16.13.1" - resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4" - integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== - -react-is@^18.2.0: - version "18.2.0" - resolved "https://registry.yarnpkg.com/react-is/-/react-is-18.2.0.tgz#199431eeaaa2e09f86427efbb4f1473edb47609b" - integrity sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w== - -regenerator-runtime@^0.13.11: - version "0.13.11" - resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz#f6dca3e7ceec20590d07ada785636a90cdca17f9" - integrity sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg== - -reselect@^4.1.8: - version "4.1.8" - resolved "https://registry.yarnpkg.com/reselect/-/reselect-4.1.8.tgz#3f5dc671ea168dccdeb3e141236f69f02eaec524" - integrity sha512-ab9EmR80F/zQTMNeneUr4cv+jSwPJgIlvEmVwLerwrWVbpLlBuls9XHzIeTFy4cegU2NHBp3va0LKOzU5qFEYQ== From 0be1188c58e408d517759caf0bbed2c8ef21565a Mon Sep 17 00:00:00 2001 From: Nathan Vieira Marcelino Date: Thu, 29 Jun 2023 14:30:18 -0300 Subject: [PATCH 104/328] feat: create yup validation error resolver --- frontend/src/utils/validationResolver.ts | 40 ++++++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 frontend/src/utils/validationResolver.ts diff --git a/frontend/src/utils/validationResolver.ts b/frontend/src/utils/validationResolver.ts new file mode 100644 index 00000000..32126817 --- /dev/null +++ b/frontend/src/utils/validationResolver.ts @@ -0,0 +1,40 @@ +import { useCallback } from 'react'; +import { object, ValidationError } from 'yup'; + +const useYupValidationResolver = ( + validationSchema: ReturnType +) => + useCallback( + async (data: any) => { + try { + const values = await validationSchema.validate(data, { + abortEarly: false, + }); + + return { + values, + errors: {}, + }; + } catch (errors) { + if (errors instanceof ValidationError) + return { + values: {}, + errors: errors.inner.reduce( + (allErrors, currentError) => ({ + ...allErrors, + [currentError.path!]: { + type: currentError.type ?? 'validation', + message: currentError.message, + }, + }), + {} + ), + }; + + throw new Error('Error trying to validate form schema'); + } + }, + [validationSchema] + ); + +export default useYupValidationResolver; \ No newline at end of file From 13ac7a4633c3110eb8a27ea0c1dc78c3e1a4cf34 Mon Sep 17 00:00:00 2001 From: Nathan Vieira Marcelino Date: Thu, 29 Jun 2023 14:34:06 -0300 Subject: [PATCH 105/328] ref: move refactoring itens - move files to folders for better use of forms - refactor sidebar-form using react-hook-form --- .../index.tsx} | 0 .../index.tsx} | 4 +- .../index.tsx} | 2 +- .../container-resource-form.component.tsx | 140 ++++++++++++++++++ .../sidebar-form.component/index.tsx | 122 +++++++++++++++ .../old.tsx} | 2 +- .../storage-form.component.tsx | 58 ++++++++ .../workflow-editor-panel.component.tsx | 2 +- 8 files changed, 325 insertions(+), 5 deletions(-) rename frontend/src/pages/private/workflows/workflows-editor/components/{piece-form-arrayinput-item.component.tsx => piece-form-arrayinput-item.component/index.tsx} (100%) rename frontend/src/pages/private/workflows/workflows-editor/components/{piece-form-item.component.tsx => piece-form-item.component/index.tsx} (99%) rename frontend/src/pages/private/workflows/workflows-editor/components/{piece-form.component.tsx => piece-form.component/index.tsx} (95%) create mode 100644 frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component/container-resource-form.component.tsx create mode 100644 frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component/index.tsx rename frontend/src/pages/private/workflows/workflows-editor/components/{sidebar-form.component.tsx => sidebar-form.component/old.tsx} (99%) create mode 100644 frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component/storage-form.component.tsx diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/piece-form-arrayinput-item.component.tsx b/frontend/src/pages/private/workflows/workflows-editor/components/piece-form-arrayinput-item.component/index.tsx similarity index 100% rename from frontend/src/pages/private/workflows/workflows-editor/components/piece-form-arrayinput-item.component.tsx rename to frontend/src/pages/private/workflows/workflows-editor/components/piece-form-arrayinput-item.component/index.tsx diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/piece-form-item.component.tsx b/frontend/src/pages/private/workflows/workflows-editor/components/piece-form-item.component/index.tsx similarity index 99% rename from frontend/src/pages/private/workflows/workflows-editor/components/piece-form-item.component.tsx rename to frontend/src/pages/private/workflows/workflows-editor/components/piece-form-item.component/index.tsx index 8eef78d6..0799090e 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/components/piece-form-item.component.tsx +++ b/frontend/src/pages/private/workflows/workflows-editor/components/piece-form-item.component/index.tsx @@ -21,8 +21,8 @@ import { toast } from 'react-toastify'; import dayjs from 'dayjs'; import { useWorkflowsEditor } from 'context/workflows/workflows-editor.context' -import ArrayInputItem from './piece-form-arrayinput-item.component'; -import CodeEditorItem from './piece-form-codeeditor-item.component'; +import ArrayInputItem from '../piece-form-arrayinput-item.component'; +import CodeEditorItem from '../piece-form-codeeditor-item.component'; interface PieceFormItemProps { diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/piece-form.component.tsx b/frontend/src/pages/private/workflows/workflows-editor/components/piece-form.component/index.tsx similarity index 95% rename from frontend/src/pages/private/workflows/workflows-editor/components/piece-form.component.tsx rename to frontend/src/pages/private/workflows/workflows-editor/components/piece-form.component/index.tsx index 99701486..492f0f18 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/components/piece-form.component.tsx +++ b/frontend/src/pages/private/workflows/workflows-editor/components/piece-form.component/index.tsx @@ -1,5 +1,5 @@ import React, { useState, useEffect } from 'react'; -import PieceFormItem from './piece-form-item.component'; +import PieceFormItem from '../piece-form-item.component'; type initialDataType = Record; diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component/container-resource-form.component.tsx b/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component/container-resource-form.component.tsx new file mode 100644 index 00000000..5acad332 --- /dev/null +++ b/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component/container-resource-form.component.tsx @@ -0,0 +1,140 @@ +import React from "react"; +import { + Grid, + Typography, + TextField, + FormControlLabel, + Checkbox, +} from '@mui/material' + +import * as yup from "yup"; +import { useForm } from "react-hook-form"; +import useYupValidationResolver from "utils/validationResolver"; + +// TODO check if these values make sense +const minAcceptedMemory = 128 +const minAcceptedCpu = 100 +const maxAcceptedMemory = 12800 +const maxAcceptedCpu = 10000 + +const defaultContainerResources = { + useGpu: false, + memoryMin: 128, + memoryMax: 128, + cpuMin: 100, + cpuMax: 100 +} + +export const formSchema = yup.object().shape({ + cpuMin: yup.number().integer().max(maxAcceptedCpu).min(minAcceptedCpu).required(), + cpuMax: yup.number().integer().max(maxAcceptedCpu).min(minAcceptedCpu).required(), + memoryMin: yup.number().integer().max(maxAcceptedMemory).min(minAcceptedMemory).required(), + memoryMax: yup.number().integer().max(maxAcceptedMemory).min(minAcceptedMemory).required(), +}); + +interface IContainerResourceFormData { + useGpu: boolean, + cpuMin: number, + cpuMax: number + memoryMin: number, + memoryMax: number +} + +interface IContainerResourceFormProps { + onChange: (data: IContainerResourceFormData) => void +} + +const ContainerResourceForm: React.FC = ({ onChange }) => { + + const resolver = useYupValidationResolver(formSchema); + const { register, watch, formState } = useForm({ resolver, mode: "onChange"}); + + + const data = watch() + onChange(data) + + return ( + + + Container Resources + + + + + + + + + + + + + + + + } + label="Use GPU" + /> + + + ) +} + +export default ContainerResourceForm; \ No newline at end of file diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component/index.tsx b/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component/index.tsx new file mode 100644 index 00000000..29e5e8a6 --- /dev/null +++ b/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component/index.tsx @@ -0,0 +1,122 @@ +import React, { useCallback } from 'react' +import { + Drawer, + Grid, + Typography, + + Accordion, + AccordionSummary, + AccordionDetails +} from '@mui/material' +import ExpandMoreIcon from '@mui/icons-material/ExpandMore'; + +import { useWorkflowsEditor } from 'context/workflows/workflows-editor.context' +import { extractDefaultValues } from 'utils' +import PieceForm from '../piece-form.component' +import ContainerResourceForm from './container-resource-form.component'; +import StorageForm from './storage-form.component'; + +interface ISidebarPieceFormProps { + formId: string, + schema: Record, + title: string, + open: boolean, + onClose: (event: any) => void, +} + +const SidebarPieceForm: React.FC = (props) => { + const { + schema, + formId, + open, + onClose, + title, + } = props + + //load forage + + const handleSaveForage = useCallback((data:any)=>{ + //save on forage with pieceFormsData using context + /** + * pieceFormsData : { + * formId: { + * containerResources: {}, + * storage: {}, + * inputs: {}, + * } + * } + */ + console.log(data) + },[]) + + return ( + +
+ + {title} + + + +
+ + + Input Arguments + + + Upstream + + + + + + + {/* */} + + +
+ + + }> + + Advanced Options + + + + +
+ + + + + +
+ +
+
+ + ) +} + +export default SidebarPieceForm; diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component.tsx b/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component/old.tsx similarity index 99% rename from frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component.tsx rename to frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component/old.tsx index 4efa1fe5..22e647c7 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component.tsx +++ b/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component/old.tsx @@ -19,7 +19,7 @@ import ExpandMoreIcon from '@mui/icons-material/ExpandMore'; import { useWorkflowsEditor } from 'context/workflows/workflows-editor.context' import { extractDefaultValues } from 'utils' -import PieceForm from './piece-form.component' +import PieceForm from '../piece-form.component' // import { createAjv } from '@jsonforms/core' // import { operatorStorageSchema } from 'common/schemas/storageSchemas' // import { workflowFormSchema } from 'common/schemas/workflowFormSchema' diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component/storage-form.component.tsx b/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component/storage-form.component.tsx new file mode 100644 index 00000000..b0f3a6a2 --- /dev/null +++ b/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component/storage-form.component.tsx @@ -0,0 +1,58 @@ +import React from 'react'; +import { useForm } from 'react-hook-form'; +import * as yup from 'yup' +import useYupValidationResolver from 'utils/validationResolver'; +import { FormControl, FormHelperText, Grid, InputLabel, MenuItem, Select, Typography } from '@mui/material'; + +const storageAccessModes = ['None', 'Read', 'Read/Write'] as const +type storageAccessModeType = typeof storageAccessModes + +export const formSchema = yup.object().shape({ + storageAccessMode: yup.mixed().oneOf(storageAccessModes).required(), +}); + +interface IStorageFormData { + storageAccessMode: storageAccessModeType, +} + +interface IStorageFormProps { + onChange: (data: IStorageFormData) => void +} + + +const StorageForm: React.FC = ({ onChange }) => { + const resolver = useYupValidationResolver(formSchema); + const { register, watch, formState } = useForm({ resolver, mode: "onChange" }); + + const data = watch() + + onChange(data) + + return ( + + + Storage + + + + Storage Access Mode + + + {formState.errors.storageAccessMode?.message} + + + + + ); +} + +export default StorageForm; \ No newline at end of file diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/workflow-editor-panel.component.tsx b/frontend/src/pages/private/workflows/workflows-editor/components/workflow-editor-panel.component.tsx index 3c61dd83..9b061a32 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/components/workflow-editor-panel.component.tsx +++ b/frontend/src/pages/private/workflows/workflows-editor/components/workflow-editor-panel.component.tsx @@ -260,7 +260,7 @@ const WorkflowEditorPanelComponent = () => {
- + ) From 45f25aa2536e574ba813798d9d75f4a054dc346a Mon Sep 17 00:00:00 2001 From: Nathan Vieira Marcelino Date: Wed, 5 Jul 2023 10:04:24 -0300 Subject: [PATCH 106/328] chore: create local forage config --- frontend/src/services/config/local-forage.config.ts | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 frontend/src/services/config/local-forage.config.ts diff --git a/frontend/src/services/config/local-forage.config.ts b/frontend/src/services/config/local-forage.config.ts new file mode 100644 index 00000000..e0be5e9a --- /dev/null +++ b/frontend/src/services/config/local-forage.config.ts @@ -0,0 +1,9 @@ +import * as localForage from 'localforage' + +localForage.config({ + name: 'Domino', + storeName: 'domino_data', // Should be alphanumeric, with underscores. + description: 'Domino database' +}) + +export default localForage \ No newline at end of file From 8fea5f28dade6805e2598df9b34e52deb3a8b223 Mon Sep 17 00:00:00 2001 From: Nathan Vieira Marcelino Date: Wed, 5 Jul 2023 10:05:09 -0300 Subject: [PATCH 107/328] chore: add workflow pieces data types --- .../workflows/types/container-resources.ts | 7 +++++++ frontend/src/context/workflows/types/index.ts | 3 +++ frontend/src/context/workflows/types/storage.ts | 15 +++++++++++++++ .../workflows/types/workflow-piece-data.ts | 15 +++++++++++++++ 4 files changed, 40 insertions(+) create mode 100644 frontend/src/context/workflows/types/container-resources.ts create mode 100644 frontend/src/context/workflows/types/index.ts create mode 100644 frontend/src/context/workflows/types/storage.ts create mode 100644 frontend/src/context/workflows/types/workflow-piece-data.ts diff --git a/frontend/src/context/workflows/types/container-resources.ts b/frontend/src/context/workflows/types/container-resources.ts new file mode 100644 index 00000000..5ac34428 --- /dev/null +++ b/frontend/src/context/workflows/types/container-resources.ts @@ -0,0 +1,7 @@ +export interface IContainerResourceFormData { + useGpu: boolean, + cpuMin: number, + cpuMax: number + memoryMin: number, + memoryMax: number +} diff --git a/frontend/src/context/workflows/types/index.ts b/frontend/src/context/workflows/types/index.ts new file mode 100644 index 00000000..d45d46cf --- /dev/null +++ b/frontend/src/context/workflows/types/index.ts @@ -0,0 +1,3 @@ +export * from "./container-resources" +export * from "./storage" +export * from "./workflow-piece-data" diff --git a/frontend/src/context/workflows/types/storage.ts b/frontend/src/context/workflows/types/storage.ts new file mode 100644 index 00000000..a7520c2c --- /dev/null +++ b/frontend/src/context/workflows/types/storage.ts @@ -0,0 +1,15 @@ +export enum storageAccessModes { + None = "None", + Read = "Read", + ReadWrite = "Read/Write", +} + +/** + * This is equivalent to: + * type storageAccessModeType = 'None' | 'Read' | 'Read/Write'; + */ +export type storageAccessModeType = keyof typeof storageAccessModes; + +export interface IStorageFormData { + storageAccessMode: storageAccessModeType, +} diff --git a/frontend/src/context/workflows/types/workflow-piece-data.ts b/frontend/src/context/workflows/types/workflow-piece-data.ts new file mode 100644 index 00000000..4370392a --- /dev/null +++ b/frontend/src/context/workflows/types/workflow-piece-data.ts @@ -0,0 +1,15 @@ +import { IContainerResourceFormData } from "./container-resources" +import { IStorageFormData } from "./storage" + +export type IWorkflowPieceData = { + storage:IStorageFormData, + containerResources: IContainerResourceFormData, + inputs: { + [formKey:string]:{ + fromUpstream: boolean, //? allowed | never | always + upstreamArgument: string | null, + upstreamId: string | null, + value: string | any + } + } +} From c8bae6c68cea4b54754190facc3a22210b33105c Mon Sep 17 00:00:00 2001 From: Nathan Vieira Marcelino Date: Wed, 5 Jul 2023 10:07:44 -0300 Subject: [PATCH 108/328] refactor: edit workflows-editor.context - add separated context - use component provider without a function --- .../workflows/workflows-editor.context.tsx | 593 ------------------ .../forms-data.context.tsx | 114 ++++ .../workflows-editor.context/index.tsx | 296 +++++++++ .../pieces.context.tsx | 98 +++ .../provider-context-wrapper.tsx | 29 + .../upstream-map.context.tsx | 81 +++ .../workflow-edges.context.tsx | 61 ++ .../workflow-nodes.context.tsx | 71 +++ .../workflow-pieces-data.context.tsx | 63 ++ .../workflow-pieces.context.tsx | 66 ++ .../components/workflows-editor.component.tsx | 10 +- .../workflows-editor-page.component.tsx | 8 +- .../requests/workflow/workflow.interface.ts | 2 +- 13 files changed, 892 insertions(+), 600 deletions(-) delete mode 100644 frontend/src/context/workflows/workflows-editor.context.tsx create mode 100644 frontend/src/context/workflows/workflows-editor.context/forms-data.context.tsx create mode 100644 frontend/src/context/workflows/workflows-editor.context/index.tsx create mode 100644 frontend/src/context/workflows/workflows-editor.context/pieces.context.tsx create mode 100644 frontend/src/context/workflows/workflows-editor.context/provider-context-wrapper.tsx create mode 100644 frontend/src/context/workflows/workflows-editor.context/upstream-map.context.tsx create mode 100644 frontend/src/context/workflows/workflows-editor.context/workflow-edges.context.tsx create mode 100644 frontend/src/context/workflows/workflows-editor.context/workflow-nodes.context.tsx create mode 100644 frontend/src/context/workflows/workflows-editor.context/workflow-pieces-data.context.tsx create mode 100644 frontend/src/context/workflows/workflows-editor.context/workflow-pieces.context.tsx diff --git a/frontend/src/context/workflows/workflows-editor.context.tsx b/frontend/src/context/workflows/workflows-editor.context.tsx deleted file mode 100644 index 5f6ad43a..00000000 --- a/frontend/src/context/workflows/workflows-editor.context.tsx +++ /dev/null @@ -1,593 +0,0 @@ -import { FC, useCallback, useEffect, useMemo, useState } from 'react' -import * as localForage from 'localforage' -import { toast } from 'react-toastify' -import { Edge } from 'reactflow' - -import { workflowFormName } from '../../constants'; -import { - IRepositoryOperators, - IOperatorForageSchema, - IGetRepoOperatorsResponseInterface, - IOperatorRepository, - useAuthenticatedGetOperatorRepositories, - IOperator -} from 'services/requests/piece' -import { - IWorkflowElement, - IPostWorkflowParams, - useAuthenticatedPostWorkflow, - IPostWorkflowResponseInterface -} from 'services/requests/workflow' -import { useFetchAuthenticatedGetRepoIdOperators } from 'services/requests/piece/get-piece-repository-pieces.request' -import { useWorkspaces } from 'context/workspaces/workspaces.context'; -import { createCustomContext } from 'utils' - - -// Config localforage -localForage.config({ - name: 'Domino', - storeName: 'domino_data', // Should be alphanumeric, with underscores. - description: 'Domino database' -}) - -interface IWorkflowsEditorContext { - repositories: IOperatorRepository[] - repositoriesError: boolean - repositoriesLoading: boolean - repositoryOperators: IRepositoryOperators - - edges: Edge[] - setEdges: any // todo add type - nodes: IWorkflowElement[] - setNodes: any // todo add type - - fetchForageWorkflowEdges: () => Promise - fetchForageWorkflowNodes: () => Promise - handleCreateWorkflow: (params: IPostWorkflowParams) => Promise - - search: string - handleSearch: (word: string) => void - fetchForagePieceById: (id: number) => Promise - fetchForageDataById: (id: string) => Promise // TODO add type - setFormsForageData: (id: string, data: any) => Promise - removeFormsForageDataById: (id: string) => Promise - removeFormsForageDataNotInIds: (ids: string[]) => Promise - clearForageData: () => Promise - nodeDirection: "horizontal" | "vertical" - toggleNodeDirection: () => void - workflowsEditorBodyFromFlowchart: () => any // TODO add type - - fetchRepoById: (params: { - id: string - }) => Promise - - // Upstream Map - getForageUpstreamMap: () => Promise // TODO add type - setForageUpstreamMap: (data: any) => Promise // TODO add type - clearForageUpstreamMap: () => Promise - removeForageUpstreamMapById: (id: string) => Promise - - setForageCheckboxStates: (checkboxStatesMap: any) => Promise // TODO add type - getForageCheckboxStates: () => Promise // TODO add type - - setForageWorkflowPieces: (workflowPieces: any) => Promise // TODO add type - getForageWorkflowPieces: () => Promise // TODO add type - removeForageWorkflowPiecesById: (id: string) => Promise - fetchWorkflowPieceById: (id: string) => Promise // TODO add type - - setNameKeyUpstreamArgsMap: (nameKeyUpstreamArgsMap: any) => Promise // TODO add type - getNameKeyUpstreamArgsMap: () => Promise // TODO add type - clearNameKeyUpstreamArgsMap: () => Promise -} - -export const [WorkflowsEditorContext, useWorkflowsEditor] = - createCustomContext('WorkflowsEditor Context') - -interface IWorkflowsEditorProviderProps { - children?: React.ReactNode; -} -/** - * WorkflowsEditor provider. - * @TODO: refactor local storage implementation with Local Forage -*/ -export const WorkflowsEditorProvider: FC = ({ children }) => { - const { workspace } = useWorkspaces() - const [search, setSearch] = useState('') - const [nodeDirection, setNodeDirection] = useState<'horizontal' | 'vertical'>('horizontal') - const [repositoryOperators, setRepositoryOperatos] = useState({}) - const [nodes, setNodes] = useState([]) - const [edges, setEdges] = useState([]) - const [loadingNodes, setLoadingNodes] = useState(true) - const [loadingEdges, setLoadingEdges] = useState(true) - - - // Requests hooks - const { - data, - error: repositoriesError, - isValidating: repositoriesLoading - // mutate: repositoriesRefresh - } = useAuthenticatedGetOperatorRepositories({}) - - const fetchRepoById = useFetchAuthenticatedGetRepoIdOperators() - const postWorkflow = useAuthenticatedPostWorkflow() - - // Error handlers - useEffect(() => { - if (!!repositoriesError) { - toast.error('Error loading repositories, try again later') - } - }, [repositoriesError]) - - - // Memoized values - const repositories: IOperatorRepository[] = useMemo( - () => data?.data.filter((repo) => repo.name.includes(search)) ?? [], - [data, search] - ) - - // Requests handlers - const handleCreateWorkflow = useCallback(async (payload: IPostWorkflowParams) => { - return postWorkflow({ ...payload, workspace_id: workspace?.id ?? '' }) - }, [postWorkflow, workspace]) - - - - /** Operators */ - useEffect(() => { - const updateRepositoriesOperators = async () => { - var repositoyOperatorsAux: IRepositoryOperators = {} - var forageOperators: IOperatorForageSchema = {} - for (const repo of repositories) { - fetchRepoById({ id: repo.id }) - .then((pieces: any) => { - repositoyOperatorsAux[repo.id] = [] - for (const op of pieces) { - repositoyOperatorsAux[repo.id].push(op) - forageOperators[op.id] = op - } - setRepositoryOperatos(repositoyOperatorsAux) - localForage.setItem("pieces", forageOperators) - }) - // Set piece item to storage -> {piece_id: Operator} - } - } - updateRepositoriesOperators() - }, [repositories, fetchRepoById]) - - // Forage handlers - const setForageCheckboxStates = useCallback(async (checkboxStatesMap: any) => { - await localForage.setItem('checkboxStates', checkboxStatesMap) - }, []) - - const getForageCheckboxStates = useCallback(async () => { - const checkboxStates = await localForage.getItem('checkboxStates') - if (!checkboxStates) { - return {} - } - return checkboxStates - }, []) - - const clearForageCheckboxStates = useCallback(async () => { - await localForage.setItem('checkboxStates', {}) - }, []) - - // Mapping state to map upstream dropdown names to upstream real keys - const setNameKeyUpstreamArgsMap = useCallback(async (nameKeyUpstreamArgsMap: any) => { - await localForage.setItem('nameKeyUpstreamArgsMap', nameKeyUpstreamArgsMap) - }, []) - - const getNameKeyUpstreamArgsMap = useCallback(async () => { - const nameKeyUpstreamArgsMap = await localForage.getItem('nameKeyUpstreamArgsMap') - if (!nameKeyUpstreamArgsMap) { - return {} - } - return nameKeyUpstreamArgsMap - }, []) - - const clearNameKeyUpstreamArgsMap = useCallback(async () => { - await localForage.setItem('nameKeyUpstreamArgsMap', {}) - }, []) - - - - const fetchForagePieceById = useCallback(async (id: number) => { - const pieces = await localForage.getItem("pieces") - if (pieces !== null) { - return pieces[id] - } - }, []) - - - // UpstreamMap forage - const getForageUpstreamMap = useCallback(async () => { - const currentUpstreamMap = await localForage.getItem("upstreamMap") - if (!currentUpstreamMap) { - return {} - } - return currentUpstreamMap - }, []) - - const setForageUpstreamMap = useCallback(async (upstreamMap: any) => { - await localForage.setItem('upstreamMap', upstreamMap) - }, []) - - const clearForageUpstreamMap = useCallback(async () => { - await localForage.setItem('upstreamMap', {}) - }, []) - - const removeForageUpstreamMapById = useCallback(async (id: string) => { - const currentUpstreamMap = await localForage.getItem("upstreamMap") - if (!currentUpstreamMap) { - return - } - delete currentUpstreamMap[id] - await localForage.setItem('upstreamMap', currentUpstreamMap) - }, []) - - // Forage forms data - const fetchForageDataById = useCallback(async (id: string) => { - const data = await localForage.getItem('formsData') - if (data === null) { - return {} - } - return data[id] - }, []) - - const setFormsForageData = useCallback(async (id: string, data: any) => { - var currentData = await localForage.getItem('formsData') - if (!currentData) { - currentData = {} - } - currentData[id] = data - await localForage.setItem('formsData', currentData) - }, []) - - const fetchFormsForageData = useCallback(async () => { - const data = await localForage.getItem('formsData') - if (data === null) { - return {} - } - return data - }, []) - - const removeFormsForageDataById = useCallback(async (id: string) => { - var currentData = await localForage.getItem('formsData') - if (!currentData) { - return - } - delete currentData[id] - await localForage.setItem('formsData', currentData) - }, []) - - const removeFormsForageDataNotInIds = useCallback(async (ids: string[]) => { - // Remove from forage "data" key the data that have keys different from the defined ids list - var currentData = await localForage.getItem('formsData') - if (!currentData) { - return - } - Object.entries(currentData).forEach(([nodeId, formData], index) => { - if (!ids.includes(nodeId) && nodeId !== workflowFormName) { - delete currentData[nodeId] - } - }); - localForage.setItem('formsData', currentData); - }, []) - - const clearForageWorkflowPieces = useCallback(async () => { - await localForage.setItem('workflowPieces', {}) - }, []) - - - const clearForageData = useCallback(async () => { - await localForage.setItem('formsData', {}) - await clearForageUpstreamMap() - await clearForageCheckboxStates() - await clearNameKeyUpstreamArgsMap() - await clearForageWorkflowPieces() - }, [clearForageUpstreamMap, clearForageCheckboxStates, clearNameKeyUpstreamArgsMap, clearForageWorkflowPieces]) - - const setForageWorkflowNodes = useCallback(async (nodes: IWorkflowElement[]) => { - await localForage.setItem('workflowNodes', nodes) - }, []) - - const setForageWorkflowEdges = useCallback(async (edges: Edge[]) => { - await localForage.setItem('workflowEdges', edges) - }, []) - - const fetchForageWorkflowNodes = useCallback(async () => { - var workflowNodes = await localForage.getItem("workflowNodes") - if ((!workflowNodes) || (workflowNodes.length === 0)) { - workflowNodes = [] - } - return workflowNodes - }, []) - - const fetchForageWorkflowEdges = useCallback(async () => { - var workflowEdges = await localForage.getItem("workflowEdges") - if ((!workflowEdges) || (workflowEdges.length === 0)) { - workflowEdges = [] - } - return workflowEdges - }, []) - - const setForageWorkflowPieces = useCallback(async (workflowPieces: any) => { - await localForage.setItem('workflowPieces', workflowPieces) - }, []) - - const getForageWorkflowPieces = useCallback(async () => { - const workflowPieces = await localForage.getItem("workflowPieces") - if (!workflowPieces) { - return {} - } - return workflowPieces - }, []) - - const removeForageWorkflowPiecesById = useCallback(async (id: string) => { - const workflowPieces = await localForage.getItem("workflowPieces") - if (!workflowPieces) { - return - } - delete workflowPieces[id] - await localForage.setItem('workflowPieces', workflowPieces) - }, []) - - const fetchWorkflowPieceById = useCallback(async (id: string) => { - const workflowPieces = await localForage.getItem("workflowPieces") - if (workflowPieces !== null) { - return workflowPieces[id] - } - }, []) - - - useEffect(() => { - (async () => { - const forageNodes = await fetchForageWorkflowNodes() - await setForageWorkflowNodes(forageNodes) - setLoadingNodes(false) - })() - }, []) - - useEffect(() => { - (async () => { - const forageEdges = await fetchForageWorkflowEdges() - await setForageWorkflowEdges(forageEdges) - setLoadingEdges(false) - })() - }, []) - - // Update nodes in forage if nodes array is updated - useEffect(() => { - (async () => { - if (loadingNodes) { - return - } - await setForageWorkflowNodes(nodes) - })() - }, [nodes, setForageWorkflowNodes, loadingNodes]) - - // Update edges forage on edges change - useEffect(() => { - (async () => { - if (loadingEdges) { - return - } - await setForageWorkflowEdges(edges) - })() - }, [edges, setForageWorkflowEdges, loadingEdges]) - - const workflowsEditorBodyFromFlowchart = useCallback(async () => { - - const dag_dict: any = {} - const tasks_dict: any = {} - const nodeId2taskName: any = {} - const taskName2nodeId: any = {} - - const ui_schema: any = { - "nodes": {}, - "edges": [] - } - - const data = await fetchFormsForageData() - const upstreamMap = await getForageUpstreamMap() - const nodes = await fetchForageWorkflowNodes() - const edges = await fetchForageWorkflowEdges() - - const workflowFormData = 'workflowForm' in data ? data['workflowForm'] : null - dag_dict['workflow'] = workflowFormData?.config - const storageWorkflowData = workflowFormData?.storage - - const auxTaskDict: any = {} - for (let index = 0; index < nodes.length; index++) { - let element = nodes[index] - let taskIndex = 0 - let taskName = `task_${element.data.name}_${taskIndex}` - while (taskName in auxTaskDict) { - taskIndex += 1 - taskName = `task_${element.data.name}_${taskIndex}` - } - auxTaskDict[taskName] = true - nodeId2taskName[element.id] = taskName - taskName2nodeId[taskName] = element.id - } - - //var task_index = 1 - for (let index = 0; index < nodes.length; index++) { - const element = nodes[index] - const elementData = data[element.id] - - try { - var taskIndex = 0 - var taskName = `task_${element.data.name}_${taskIndex}` - while (taskName in tasks_dict) { - taskIndex += 1 - taskName = `task_${element.data.name}_${taskIndex}` - } - ui_schema['nodes'][taskName] = element - const taskDict: any = {} - - const { storageSource, baseFolder, ...providerOptions } = storageWorkflowData || {} - const storageDict: any = { - "source": storageSource || null, - "base_folder": baseFolder || null, - "mode": elementData?.storage?.storageAccessMode, - "provider_options": providerOptions || null - } - taskDict['workflow_shared_storage'] = storageDict - - const containerResources = { - requests: { - cpu: elementData?.containerResources?.cpu.min, - memory: elementData?.containerResources?.memory.min - }, - limits: { - cpu: elementData?.containerResources?.cpu.max, - memory: elementData?.containerResources?.memory.max - }, - use_gpu: elementData?.containerResources?.useGpu - } - taskDict['container_resources'] = containerResources - - const nodeId = element.id - taskDict['task_id'] = taskName - taskDict['piece'] = { - id: parseInt(nodeId.split('_')[0]), - name: element.data.name - } - const pieceInputKwargs: any = {} - if (nodeId in upstreamMap) { - for (const key in upstreamMap[nodeId]) { - const value = upstreamMap[nodeId][key] - const fromUpstream = value['fromUpstream'] - pieceInputKwargs[key] = { - fromUpstream: fromUpstream, - upstreamTaskId: fromUpstream ? nodeId2taskName[value['upstreamId']] : null, - upstreamArgument: fromUpstream ? value['upstreamArgument'] : null, - value: value['value'] - } - } - } - //console.log(pieceInputKwargs) - - taskDict['piece_input_kwargs'] = pieceInputKwargs - - tasks_dict[taskName] = taskDict - //task_index += 1 - } catch (err) { - console.log('Error', err) - } - - } - - // Organize dependencies - const dependencies_dict: any = {} - for (let index = 0; index < edges.length; index++) { - const edge: any = edges[index] - const source_task_name = nodeId2taskName[edge.source] - const target_task_name = nodeId2taskName[edge.target] - if (target_task_name in dependencies_dict) { - dependencies_dict[target_task_name].push(source_task_name) - } else { - dependencies_dict[target_task_name] = [source_task_name] - } - } - - // Fill in dependencies for each task - const keys = Object.keys(tasks_dict) - keys.forEach((key, index) => { - tasks_dict[key]['dependencies'] = dependencies_dict[key] ? dependencies_dict[key] : [] - }) - // Finalize dag dictionary - ui_schema['edges'] = edges - dag_dict['tasks'] = tasks_dict - dag_dict['ui_schema'] = ui_schema - - return dag_dict - }, [fetchFormsForageData, getForageUpstreamMap, fetchForageWorkflowNodes, fetchForageWorkflowEdges]) - - const value: IWorkflowsEditorContext = useMemo( - () => ({ - repositories, - repositoriesError: !!repositoriesError, - repositoriesLoading, - repositoryOperators, - search, - edges, - setEdges, - nodes, - setNodes, - handleSearch: (word: string) => setSearch(word), - fetchRepoById, - fetchForagePieceById, - setFormsForageData, - fetchForageDataById, - removeFormsForageDataById, - clearForageData, - removeFormsForageDataNotInIds, - handleCreateWorkflow, - fetchForageWorkflowEdges: () => fetchForageWorkflowEdges(), - fetchForageWorkflowNodes: () => fetchForageWorkflowNodes(), - workflowsEditorBodyFromFlowchart, - getForageUpstreamMap, - setForageUpstreamMap, - clearForageUpstreamMap, - removeForageUpstreamMapById, - nodeDirection, - setForageCheckboxStates, - getForageCheckboxStates, - setForageWorkflowPieces, - getForageWorkflowPieces, - removeForageWorkflowPiecesById, - fetchWorkflowPieceById, - setNameKeyUpstreamArgsMap, - getNameKeyUpstreamArgsMap, - clearNameKeyUpstreamArgsMap, - toggleNodeDirection: () => - setNodeDirection((current: any) => - current === 'vertical' ? 'horizontal' : 'vertical' - ) - }), - [ - fetchRepoById, - fetchForagePieceById, - setFormsForageData, - fetchForageDataById, - removeFormsForageDataById, - clearForageData, - removeFormsForageDataNotInIds, - handleCreateWorkflow, - fetchForageWorkflowEdges, - fetchForageWorkflowNodes, - workflowsEditorBodyFromFlowchart, - getForageUpstreamMap, - setForageUpstreamMap, - clearForageUpstreamMap, - removeForageUpstreamMapById, - nodeDirection, - repositories, - repositoriesError, - repositoriesLoading, - repositoryOperators, - search, - edges, - setEdges, - nodes, - setNodes, - setForageCheckboxStates, - getForageCheckboxStates, - setForageWorkflowPieces, - getForageWorkflowPieces, - removeForageWorkflowPiecesById, - fetchWorkflowPieceById, - setNameKeyUpstreamArgsMap, - getNameKeyUpstreamArgsMap, - clearNameKeyUpstreamArgsMap - ] - ) - - return ( - - {children} - - ) -} diff --git a/frontend/src/context/workflows/workflows-editor.context/forms-data.context.tsx b/frontend/src/context/workflows/workflows-editor.context/forms-data.context.tsx new file mode 100644 index 00000000..9d64d828 --- /dev/null +++ b/frontend/src/context/workflows/workflows-editor.context/forms-data.context.tsx @@ -0,0 +1,114 @@ +import { workflowFormName } from '../../../constants'; +import React, { useCallback } from 'react'; +import localForage from 'services/config/local-forage.config'; + +import { createCustomContext } from 'utils'; + +export interface IFormsDataContext { + setForageCheckboxStates: (checkboxStatesMap: any) => Promise // TODO add type + getForageCheckboxStates: () => Promise // TODO add type + + fetchForageDataById: (id: string) => Promise // TODO add type + fetchFormsForageData: () => Promise // TODO add type + setFormsForageData: (id: string, data: any) => Promise + removeFormsForageDataById: (id: string) => Promise + removeFormsForageDataNotInIds: (ids: string[]) => Promise + clearForageFormsData: ()=> Promise + clearForageCheckboxStates: ()=> Promise +} + +export const [FormsDataContext, useFormsData] = + createCustomContext('FormsData Context') + +const FormsDataProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => { + + // Forage forms data + const fetchForageDataById = useCallback(async (id: string) => { + const data = await localForage.getItem('formsData') + if (data === null) { + return {} + } + return data[id] + }, []) + + const setFormsForageData = useCallback(async (id: string, data: any) => { + var currentData = await localForage.getItem('formsData') + if (!currentData) { + currentData = {} + } + currentData[id] = data + await localForage.setItem('formsData', currentData) + }, []) + + const fetchFormsForageData = useCallback(async () => { + const data = await localForage.getItem('formsData') + if (data === null) { + return {} + } + return data + }, []) + + const removeFormsForageDataById = useCallback(async (id: string) => { + var currentData = await localForage.getItem('formsData') + if (!currentData) { + return + } + delete currentData[id] + await localForage.setItem('formsData', currentData) + }, []) + + const removeFormsForageDataNotInIds = useCallback(async (ids: string[]) => { + // Remove from forage "data" key the data that have keys different from the defined ids list + var currentData = await localForage.getItem('formsData') + if (!currentData) { + return + } + Object.entries(currentData).forEach(([nodeId, formData], index) => { + if (!ids.includes(nodeId) && nodeId !== workflowFormName) { + delete currentData[nodeId] + } + }); + localForage.setItem('formsData', currentData); + }, []) + + const setForageCheckboxStates = useCallback(async (checkboxStatesMap: any) => { + await localForage.setItem('checkboxStates', checkboxStatesMap) + }, []) + + const getForageCheckboxStates = useCallback(async () => { + const checkboxStates = await localForage.getItem('checkboxStates') + if (!checkboxStates) { + return {} + } + return checkboxStates + }, []) + + const clearForageCheckboxStates = useCallback(async () => { + await localForage.setItem('checkboxStates', {}) + }, []) + + const clearForageFormsData = useCallback(async()=>{ + await localForage.setItem('formsData', {}) + },[]) + + + const value = { + fetchFormsForageData, + fetchForageDataById, + removeFormsForageDataById, + removeFormsForageDataNotInIds, + setFormsForageData, + setForageCheckboxStates, + clearForageFormsData, + getForageCheckboxStates, + clearForageCheckboxStates, + } + + return ( + + {children} + + ); +} + +export default FormsDataProvider; \ No newline at end of file diff --git a/frontend/src/context/workflows/workflows-editor.context/index.tsx b/frontend/src/context/workflows/workflows-editor.context/index.tsx new file mode 100644 index 00000000..8cc4b049 --- /dev/null +++ b/frontend/src/context/workflows/workflows-editor.context/index.tsx @@ -0,0 +1,296 @@ +import React, { FC, useCallback } from 'react' + +import { + IPostWorkflowParams, + useAuthenticatedPostWorkflow, + IPostWorkflowResponseInterface +} from 'services/requests/workflow' + +import { useWorkspaces } from 'context/workspaces/workspaces.context'; + +import { createCustomContext } from 'utils' + +import { useFormsData, IFormsDataContext } from './forms-data.context'; +import { usesPieces, IPiecesContext } from './pieces.context'; +import { useUpstreamMap, IUpstreamMapContext } from './upstream-map.context'; +import { useWorkflowsEdges, IWorkflowsEdgesContext } from './workflow-edges.context'; +import { useWorkflowsNodes, IWorkflowsNodesContext } from './workflow-nodes.context'; +import { useWorkflowPiece, IWorkflowPieceContext } from './workflow-pieces.context'; +import { useWorkflowPiecesData, IWorkflowPiecesDataContext } from './workflow-pieces-data.context'; + +interface IWorkflowsEditorContext extends IFormsDataContext, IPiecesContext, IUpstreamMapContext, IWorkflowsEdgesContext, IWorkflowsNodesContext, IWorkflowPieceContext, IWorkflowPiecesDataContext { + + workflowsEditorBodyFromFlowchart: () => any // TODO add type + handleCreateWorkflow: (params: IPostWorkflowParams) => Promise + clearForageData: () => Promise +} + +export const [WorkflowsEditorContext, useWorkflowsEditor] = + createCustomContext('WorkflowsEditor Context') + +export const WorkflowsEditorProvider: FC<{ children?: React.ReactNode }> = ({ children }) => { + const { workspace } = useWorkspaces() + const postWorkflow = useAuthenticatedPostWorkflow() + + const { + fetchFormsForageData, + fetchForageDataById, + setFormsForageData, + removeFormsForageDataById, + removeFormsForageDataNotInIds, + getForageCheckboxStates, + setForageCheckboxStates, + clearForageCheckboxStates, + clearForageFormsData, + } = useFormsData() + + const { + repositories, + repositoriesError, + repositoriesLoading, + repositoryOperators, + fetchForagePieceById, + fetchRepoById, + search, + handleSearch, + } = usesPieces() + + const { + edges, + fetchForageWorkflowEdges, + setEdges, + } = useWorkflowsEdges() + + const { + nodes, + nodeDirection, + fetchForageWorkflowNodes, + setNodes, + toggleNodeDirection, + } = useWorkflowsNodes() + + const { + getForageUpstreamMap, + getNameKeyUpstreamArgsMap, + setForageUpstreamMap, + setNameKeyUpstreamArgsMap, + removeForageUpstreamMapById, + clearForageUpstreamMap, + clearNameKeyUpstreamArgsMap, + } = useUpstreamMap() + + const { + fetchWorkflowPieceById, + setForageWorkflowPieces, + getForageWorkflowPieces, + removeForageWorkflowPiecesById, + clearForageWorkflowPieces, + } = useWorkflowPiece() + + const { + fetchForageWorkflowPiecesData, + fetchForageWorkflowPiecesDataById, + setForageWorkflowPiecesData, + clearForageWorkflowPiecesData, + } = useWorkflowPiecesData() + + + const handleCreateWorkflow = useCallback(async (payload: IPostWorkflowParams) => { + return postWorkflow({ ...payload, workspace_id: workspace?.id ?? '' }) + }, [postWorkflow, workspace]) + + const workflowsEditorBodyFromFlowchart = useCallback(async () => { + + const dag_dict: any = {} + const tasks_dict: any = {} + const nodeId2taskName: any = {} + const taskName2nodeId: any = {} + + const ui_schema: any = { + "nodes": {}, + "edges": [] + } + + const data = await fetchFormsForageData() + const workflowPiecesData = await fetchForageWorkflowPiecesData() + const upstreamMap = await getForageUpstreamMap() + const nodes = await fetchForageWorkflowNodes() + const edges = await fetchForageWorkflowEdges() + + const workflowFormData = 'workflowForm' in data ? data['workflowForm'] : null + dag_dict['workflow'] = workflowFormData?.config + const storageWorkflowData = workflowFormData?.storage + + const auxTaskDict: any = {} + for (let index = 0; index < nodes.length; index++) { + let element = nodes[index] + let taskIndex = 0 + let taskName = `task_${element.data.name}_${taskIndex}` + while (taskName in auxTaskDict) { + taskIndex += 1 + taskName = `task_${element.data.name}_${taskIndex}` + } + auxTaskDict[taskName] = true + nodeId2taskName[element.id] = taskName + taskName2nodeId[taskName] = element.id + } + + //var task_index = 1 + for (let index = 0; index < nodes.length; index++) { + const element = nodes[index] + const elementData = data[element.id] + + try { + var taskIndex = 0 + var taskName = `task_${element.data.name}_${taskIndex}` + while (taskName in tasks_dict) { + taskIndex += 1 + taskName = `task_${element.data.name}_${taskIndex}` + } + ui_schema['nodes'][taskName] = element + const taskDict: any = {} + + const { storageSource, baseFolder, ...providerOptions } = storageWorkflowData || {} + const storageDict: any = { + "source": storageSource || null, + "base_folder": baseFolder || null, + "mode": elementData?.storage?.storageAccessMode, + "provider_options": providerOptions || null + } + taskDict['workflow_shared_storage'] = storageDict + + const containerResources = { + requests: { + cpu: elementData?.containerResources?.cpu.min, + memory: elementData?.containerResources?.memory.min + }, + limits: { + cpu: elementData?.containerResources?.cpu.max, + memory: elementData?.containerResources?.memory.max + }, + use_gpu: elementData?.containerResources?.useGpu + } + taskDict['container_resources'] = containerResources + + const nodeId = element.id + taskDict['task_id'] = taskName + taskDict['piece'] = { + id: parseInt(nodeId.split('_')[0]), + name: element.data.name + } + const pieceInputKwargs: any = {} + if (nodeId in upstreamMap) { + for (const key in upstreamMap[nodeId]) { + const value = upstreamMap[nodeId][key] + const fromUpstream = value['fromUpstream'] + pieceInputKwargs[key] = { + fromUpstream: fromUpstream, + upstreamTaskId: fromUpstream ? nodeId2taskName[value['upstreamId']] : null, + upstreamArgument: fromUpstream ? value['upstreamArgument'] : null, + value: value['value'] + } + } + } + //console.log(pieceInputKwargs) + + taskDict['piece_input_kwargs'] = pieceInputKwargs + + tasks_dict[taskName] = taskDict + //task_index += 1 + } catch (err) { + console.log('Error', err) + } + + } + + // Organize dependencies + const dependencies_dict: any = {} + for (let index = 0; index < edges.length; index++) { + const edge: any = edges[index] + const source_task_name = nodeId2taskName[edge.source] + const target_task_name = nodeId2taskName[edge.target] + if (target_task_name in dependencies_dict) { + dependencies_dict[target_task_name].push(source_task_name) + } else { + dependencies_dict[target_task_name] = [source_task_name] + } + } + + // Fill in dependencies for each task + const keys = Object.keys(tasks_dict) + keys.forEach((key, index) => { + tasks_dict[key]['dependencies'] = dependencies_dict[key] ? dependencies_dict[key] : [] + }) + // Finalize dag dictionary + ui_schema['edges'] = edges + dag_dict['tasks'] = tasks_dict + dag_dict['ui_schema'] = ui_schema + + return dag_dict + }, [fetchFormsForageData, getForageUpstreamMap, fetchForageWorkflowNodes, fetchForageWorkflowEdges]) + + const clearForageData = useCallback(async () => { + await clearForageFormsData() + await clearForageUpstreamMap() + await clearForageCheckboxStates() + await clearNameKeyUpstreamArgsMap() + await clearForageWorkflowPieces() + await clearForageWorkflowPiecesData() + }, [clearForageUpstreamMap, clearForageCheckboxStates, clearNameKeyUpstreamArgsMap, clearForageWorkflowPieces, clearForageFormsData, clearForageWorkflowPiecesData]) + + const value: IWorkflowsEditorContext = { + repositories, + repositoriesError: !!repositoriesError, + repositoriesLoading, + repositoryOperators, + search, + edges, + setEdges, + nodes, + setNodes, + handleSearch, + fetchRepoById, + fetchForagePieceById, + setFormsForageData, + fetchForageDataById, + removeFormsForageDataById, + removeFormsForageDataNotInIds, + handleCreateWorkflow, + fetchForageWorkflowEdges, + fetchForageWorkflowNodes, + workflowsEditorBodyFromFlowchart, + getForageUpstreamMap, + setForageUpstreamMap, + removeForageUpstreamMapById, + nodeDirection, + setForageCheckboxStates, + getForageCheckboxStates, + setForageWorkflowPieces, + getForageWorkflowPieces, + removeForageWorkflowPiecesById, + fetchWorkflowPieceById, + setNameKeyUpstreamArgsMap, + getNameKeyUpstreamArgsMap, + toggleNodeDirection, + fetchFormsForageData, + + fetchForageWorkflowPiecesData, + fetchForageWorkflowPiecesDataById, + setForageWorkflowPiecesData, + + clearForageData, + clearForageWorkflowPiecesData, + clearForageUpstreamMap, + clearNameKeyUpstreamArgsMap, + clearForageFormsData, + clearForageCheckboxStates, + clearForageWorkflowPieces + } + + return ( + + {children} + + ) +} + diff --git a/frontend/src/context/workflows/workflows-editor.context/pieces.context.tsx b/frontend/src/context/workflows/workflows-editor.context/pieces.context.tsx new file mode 100644 index 00000000..21d14323 --- /dev/null +++ b/frontend/src/context/workflows/workflows-editor.context/pieces.context.tsx @@ -0,0 +1,98 @@ +import React, { useCallback, useEffect, useMemo, useState } from "react"; +import { toast } from "react-toastify"; +import localForage from "services/config/local-forage.config"; +import { IGetRepoOperatorsResponseInterface, IOperator, IOperatorForageSchema, IOperatorRepository, IRepositoryOperators, useAuthenticatedGetOperatorRepositories } from "services/requests/piece"; +import { useFetchAuthenticatedGetRepoIdOperators } from "services/requests/piece/get-piece-repository-pieces.request"; +import { createCustomContext } from "utils"; + +export interface IPiecesContext { + repositories: IOperatorRepository[] + repositoriesError: boolean + repositoriesLoading: boolean + repositoryOperators: IRepositoryOperators + + search: string + handleSearch: (word: string) => void + + fetchRepoById: (params: { + id: string + }) => Promise + fetchForagePieceById: (id: number) => Promise +} + +export const [PiecesContext, usesPieces] = + createCustomContext('Pieces Context') + +const PiecesProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => { + + const [search, handleSearch] = useState('') + const [repositoryOperators, setRepositoryOperatos] = useState({}) + + const fetchRepoById = useFetchAuthenticatedGetRepoIdOperators() + + const { + data, + error: repositoriesError, + isValidating: repositoriesLoading + // mutate: repositoriesRefresh + } = useAuthenticatedGetOperatorRepositories({}) + + const repositories: IOperatorRepository[] = useMemo( + () => data?.data.filter((repo) => repo.name.includes(search)) ?? [], + [data, search] + ) + + const fetchForagePieceById = useCallback(async (id: number) => { + const pieces = await localForage.getItem("pieces") + if (pieces !== null) { + return pieces[id] + } + }, []) + + useEffect(() => { + const updateRepositoriesOperators = async () => { + var repositoyOperatorsAux: IRepositoryOperators = {} + var forageOperators: IOperatorForageSchema = {} + for (const repo of repositories) { + fetchRepoById({ id: repo.id }) + .then((pieces: any) => { + repositoyOperatorsAux[repo.id] = [] + for (const op of pieces) { + repositoyOperatorsAux[repo.id].push(op) + forageOperators[op.id] = op + } + setRepositoryOperatos(repositoyOperatorsAux) + localForage.setItem("pieces", forageOperators) + }) + // Set piece item to storage -> {piece_id: Operator} + } + } + updateRepositoriesOperators() + }, [repositories, fetchRepoById]) + + useEffect(() => { + if (!!repositoriesError) { + toast.error('Error loading repositories, try again later') + } + }, [repositoriesError]) + + + const value: IPiecesContext = { + fetchForagePieceById, + fetchRepoById, + handleSearch, + repositories, + repositoriesError, + repositoriesLoading, + repositoryOperators, + search, + } + + return ( + + {children} + + ) +} + +export default PiecesProvider \ No newline at end of file diff --git a/frontend/src/context/workflows/workflows-editor.context/provider-context-wrapper.tsx b/frontend/src/context/workflows/workflows-editor.context/provider-context-wrapper.tsx new file mode 100644 index 00000000..d6b8dc89 --- /dev/null +++ b/frontend/src/context/workflows/workflows-editor.context/provider-context-wrapper.tsx @@ -0,0 +1,29 @@ +import FormsDataProvider from "./forms-data.context"; +import PiecesProvider from "./pieces.context"; +import UpstreamMapProvider from "./upstream-map.context"; +import WorkflowsEdgesProvider from "./workflow-edges.context"; +import WorkflowsNodesProvider from "./workflow-nodes.context"; +import WorkflowPiecesProvider from "./workflow-pieces.context"; +import WorkflowPiecesDataProvider from "./workflow-pieces-data.context"; + +const ProviderContextWrapper: React.FC<{ children: React.ReactNode }> = ({ children }) => { + return ( + + + + + + + + {children} + + + + + + + + ); +} + +export default ProviderContextWrapper \ No newline at end of file diff --git a/frontend/src/context/workflows/workflows-editor.context/upstream-map.context.tsx b/frontend/src/context/workflows/workflows-editor.context/upstream-map.context.tsx new file mode 100644 index 00000000..3736b91d --- /dev/null +++ b/frontend/src/context/workflows/workflows-editor.context/upstream-map.context.tsx @@ -0,0 +1,81 @@ +import React, { useCallback } from "react"; +import localForage from "services/config/local-forage.config"; +import { createCustomContext } from "utils"; + +export interface IUpstreamMapContext { + getForageUpstreamMap: () => Promise // TODO add type + setForageUpstreamMap: (data: any) => Promise // TODO add type + clearForageUpstreamMap: () => Promise + removeForageUpstreamMapById: (id: string) => Promise + + setNameKeyUpstreamArgsMap: (nameKeyUpstreamArgsMap: any) => Promise // TODO add type + getNameKeyUpstreamArgsMap: () => Promise // TODO add type + clearNameKeyUpstreamArgsMap: () => Promise +} + +export const [UpstreamMapContext, useUpstreamMap] = + createCustomContext('upstreamMap Context') + +const UpstreamMapProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => { + + // Mapping state to map upstream dropdown names to upstream real keys + const setNameKeyUpstreamArgsMap = useCallback(async (nameKeyUpstreamArgsMap: any) => { + await localForage.setItem('nameKeyUpstreamArgsMap', nameKeyUpstreamArgsMap) + }, []) + + const getNameKeyUpstreamArgsMap = useCallback(async () => { + const nameKeyUpstreamArgsMap = await localForage.getItem('nameKeyUpstreamArgsMap') + if (!nameKeyUpstreamArgsMap) { + return {} + } + return nameKeyUpstreamArgsMap + }, []) + + const clearNameKeyUpstreamArgsMap = useCallback(async () => { + await localForage.setItem('nameKeyUpstreamArgsMap', {}) + }, []) + + // UpstreamMap forage + const getForageUpstreamMap = useCallback(async () => { + const currentUpstreamMap = await localForage.getItem("upstreamMap") + if (!currentUpstreamMap) { + return {} + } + return currentUpstreamMap + }, []) + + const setForageUpstreamMap = useCallback(async (upstreamMap: any) => { + await localForage.setItem('upstreamMap', upstreamMap) + }, []) + + const clearForageUpstreamMap = useCallback(async () => { + await localForage.setItem('upstreamMap', {}) + }, []) + + const removeForageUpstreamMapById = useCallback(async (id: string) => { + const currentUpstreamMap = await localForage.getItem("upstreamMap") + if (!currentUpstreamMap) { + return + } + delete currentUpstreamMap[id] + await localForage.setItem('upstreamMap', currentUpstreamMap) + }, []) + + const value: IUpstreamMapContext = { + clearForageUpstreamMap, + clearNameKeyUpstreamArgsMap, + getForageUpstreamMap, + getNameKeyUpstreamArgsMap, + removeForageUpstreamMapById, + setForageUpstreamMap, + setNameKeyUpstreamArgsMap, + } + + return ( + + {children} + + ) +} + +export default UpstreamMapProvider \ No newline at end of file diff --git a/frontend/src/context/workflows/workflows-editor.context/workflow-edges.context.tsx b/frontend/src/context/workflows/workflows-editor.context/workflow-edges.context.tsx new file mode 100644 index 00000000..4c1619e6 --- /dev/null +++ b/frontend/src/context/workflows/workflows-editor.context/workflow-edges.context.tsx @@ -0,0 +1,61 @@ +import React, { useCallback, useEffect, useState } from "react"; +import { Edge } from "reactflow"; +import localForage from "services/config/local-forage.config"; +import { createCustomContext } from "utils"; + +export interface IWorkflowsEdgesContext { + edges: Edge[] + setEdges: React.Dispatch> + fetchForageWorkflowEdges: () => Promise +} + +export const [WorkflowsEdgesContext, useWorkflowsEdges] = + createCustomContext('WorkflowsEdges Context') + +const WorkflowsEdgesProvider: React.FC<{children:React.ReactNode}> = ({ children }) => { + const [edges, setEdges] = useState([]) + const [loadingEdges, setLoadingEdges] = useState(true) + + const setForageWorkflowEdges = useCallback(async (edges: Edge[]) => { + await localForage.setItem('workflowEdges', edges) + }, []) + + const fetchForageWorkflowEdges = useCallback(async () => { + var workflowEdges = await localForage.getItem("workflowEdges") + if ((!workflowEdges) || (workflowEdges.length === 0)) { + workflowEdges = [] + } + return workflowEdges + }, []) + + useEffect(() => { + (async () => { + const forageEdges = await fetchForageWorkflowEdges() + await setForageWorkflowEdges(forageEdges) + setLoadingEdges(false) + })() + }, []) + + useEffect(() => { + (async () => { + if (loadingEdges) { + return + } + await setForageWorkflowEdges(edges) + })() + }, [edges, setForageWorkflowEdges, loadingEdges]) + + const value: IWorkflowsEdgesContext = { + edges, + fetchForageWorkflowEdges: () => fetchForageWorkflowEdges(), + setEdges, + } + + return ( + + {children} + + ) +} + +export default WorkflowsEdgesProvider \ No newline at end of file diff --git a/frontend/src/context/workflows/workflows-editor.context/workflow-nodes.context.tsx b/frontend/src/context/workflows/workflows-editor.context/workflow-nodes.context.tsx new file mode 100644 index 00000000..d23e2777 --- /dev/null +++ b/frontend/src/context/workflows/workflows-editor.context/workflow-nodes.context.tsx @@ -0,0 +1,71 @@ +import React, { useCallback, useEffect, useState } from "react"; +import { Node } from "reactflow"; +import localForage from "services/config/local-forage.config"; +import { IWorkflowElement } from "services/requests/workflow"; +import { createCustomContext } from "utils"; + +export interface IWorkflowsNodesContext { + nodes: IWorkflowElement[] | Node[] + setNodes: React.Dispatch> + fetchForageWorkflowNodes: () => Promise + nodeDirection: "horizontal" | "vertical" + toggleNodeDirection: () => void +} + +export const [WorkflowsNodesContext, useWorkflowsNodes] = + createCustomContext('WorkflowsNodes Context') + +const WorkflowsNodesProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => { + const [nodeDirection, setNodeDirection] = useState<'horizontal' | 'vertical'>('horizontal') + const [nodes, setNodes] = useState([]) + const [loadingNodes, setLoadingNodes] = useState(true) + + const setForageWorkflowNodes = useCallback(async (nodes: IWorkflowElement[]) => { + await localForage.setItem('workflowNodes', nodes) + }, []) + + const fetchForageWorkflowNodes = useCallback(async () => { + var workflowNodes = await localForage.getItem("workflowNodes") + if ((!workflowNodes) || (workflowNodes.length === 0)) { + workflowNodes = [] + } + return workflowNodes + }, []) + + useEffect(() => { + (async () => { + const forageNodes = await fetchForageWorkflowNodes() + await setForageWorkflowNodes(forageNodes) + setLoadingNodes(false) + })() + }, []) + + // Update nodes in forage if nodes array is updated + useEffect(() => { + (async () => { + if (loadingNodes) { + return + } + await setForageWorkflowNodes(nodes) + })() + }, [nodes, setForageWorkflowNodes, loadingNodes]) + + const value = { + nodes, + setNodes, + fetchForageWorkflowNodes: () => fetchForageWorkflowNodes(), + nodeDirection, + toggleNodeDirection: () => + setNodeDirection((current: any) => + current === 'vertical' ? 'horizontal' : 'vertical' + ) + } + + return ( + + {children} + + ) +} + +export default WorkflowsNodesProvider \ No newline at end of file diff --git a/frontend/src/context/workflows/workflows-editor.context/workflow-pieces-data.context.tsx b/frontend/src/context/workflows/workflows-editor.context/workflow-pieces-data.context.tsx new file mode 100644 index 00000000..eac5eba4 --- /dev/null +++ b/frontend/src/context/workflows/workflows-editor.context/workflow-pieces-data.context.tsx @@ -0,0 +1,63 @@ +import React, { useCallback } from "react"; +import localForage from "services/config/local-forage.config"; +import { createCustomContext } from "utils"; +import { IWorkflowPieceData } from "../types"; + +type ForagePiecesData = Record + +export interface IWorkflowPiecesDataContext { + setForageWorkflowPiecesData: (id:string,pieceData: IWorkflowPieceData) => Promise + fetchForageWorkflowPiecesData: ()=> Promise + fetchForageWorkflowPiecesDataById: (id:string)=> Promise + clearForageWorkflowPiecesData: ()=> Promise +} + +export const [WorkflowPiecesDataContext, useWorkflowPiecesData] = + createCustomContext('WorkflowPiecesData Context') + +const WorkflowPiecesDataProvider: React.FC<{children:React.ReactNode}> = ({ children }) => { + + const setForageWorkflowPiecesData = useCallback(async ( id:string,pieceData: IWorkflowPieceData) => { + let currentData = await localForage.getItem('workflowPiecesData') + if (!currentData) { + currentData = {} + } + currentData[id] = pieceData + await localForage.setItem('workflowPiecesData', currentData) + }, []) + + const fetchForageWorkflowPiecesData = useCallback(async () => { + let workflowPiecesData = await localForage.getItem("workflowPiecesData") + + return workflowPiecesData ?? {} + }, []) + + const fetchForageWorkflowPiecesDataById = useCallback(async (id:string) => { + let workflowPiecesData = await localForage.getItem("workflowPiecesData") + + if(!workflowPiecesData?.[id]){ + return + } + + return workflowPiecesData[id] + }, []) + + const clearForageWorkflowPiecesData = useCallback(async()=>{ + await localForage.setItem('workflowPiecesData', {}) + },[]) + + const value: IWorkflowPiecesDataContext = { + setForageWorkflowPiecesData, + fetchForageWorkflowPiecesData, + fetchForageWorkflowPiecesDataById, + clearForageWorkflowPiecesData + } + + return ( + + {children} + + ) +} + +export default WorkflowPiecesDataProvider \ No newline at end of file diff --git a/frontend/src/context/workflows/workflows-editor.context/workflow-pieces.context.tsx b/frontend/src/context/workflows/workflows-editor.context/workflow-pieces.context.tsx new file mode 100644 index 00000000..b7d43e16 --- /dev/null +++ b/frontend/src/context/workflows/workflows-editor.context/workflow-pieces.context.tsx @@ -0,0 +1,66 @@ +import React, { useCallback } from 'react'; +import localForage from 'services/config/local-forage.config'; +import { IOperator } from 'services/requests/piece'; +import { createCustomContext } from 'utils'; + +export interface IWorkflowPieceContext { + setForageWorkflowPieces: (workflowPieces: any) => Promise // TODO add type + getForageWorkflowPieces: () => Promise // TODO add type + removeForageWorkflowPiecesById: (id: string) => Promise + fetchWorkflowPieceById: (id: string) => Promise // TODO add type + clearForageWorkflowPieces: () => Promise +} + +export const [WorkflowPiecesContext, useWorkflowPiece] = + createCustomContext('WorkflowsPieces Context') + +const WorkflowPiecesProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => { + + const setForageWorkflowPieces = useCallback(async (workflowPieces: any) => { + await localForage.setItem('workflowPieces', workflowPieces) + }, []) + + const clearForageWorkflowPieces = useCallback(async () => { + await localForage.setItem('workflowPieces', {}) + }, []) + + const getForageWorkflowPieces = useCallback(async () => { + const workflowPieces = await localForage.getItem("workflowPieces") + if (!workflowPieces) { + return {} + } + return workflowPieces + }, []) + + const removeForageWorkflowPiecesById = useCallback(async (id: string) => { + const workflowPieces = await localForage.getItem("workflowPieces") + if (!workflowPieces) { + return + } + delete workflowPieces[id] + await localForage.setItem('workflowPieces', workflowPieces) + }, []) + + const fetchWorkflowPieceById = useCallback(async (id: string) => { + const workflowPieces = await localForage.getItem("workflowPieces") + if (workflowPieces !== null) { + return workflowPieces[id] + } + }, []) + + const value: IWorkflowPieceContext = { + fetchWorkflowPieceById, + getForageWorkflowPieces, + removeForageWorkflowPiecesById, + setForageWorkflowPieces, + clearForageWorkflowPieces, + } + + return ( + + {children} + + ); +} + +export default WorkflowPiecesProvider; \ No newline at end of file diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/workflows-editor.component.tsx b/frontend/src/pages/private/workflows/workflows-editor/components/workflows-editor.component.tsx index cdc8bd7b..ea2b806d 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/components/workflows-editor.component.tsx +++ b/frontend/src/pages/private/workflows/workflows-editor/components/workflows-editor.component.tsx @@ -21,7 +21,7 @@ import { toast } from "react-toastify" // TODO make it look good // TODO remove all '// @ts-ignore: Unreachable code error"' */ -export const WorkflowsEditorComponent = withContext(WorkflowsEditorProvider, () => { +export const WorkflowsEditorComponent: React.FC = () => { const [formSchema, setFormSchema] = useState({}) const [formUiSchema, setFormUiSchema] = useState({}) @@ -250,11 +250,11 @@ export const WorkflowsEditorComponent = withContext(WorkflowsEditorProvider, () />
{/* */} -
) -}) +} diff --git a/frontend/src/pages/private/workflows/workflows-editor/workflows-editor-page.component.tsx b/frontend/src/pages/private/workflows/workflows-editor/workflows-editor-page.component.tsx index 4d2c47c1..3f69e4ca 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/workflows-editor-page.component.tsx +++ b/frontend/src/pages/private/workflows/workflows-editor/workflows-editor-page.component.tsx @@ -1,6 +1,8 @@ import { PrivateLayout } from 'modules/layout' +import ProviderContextWrapper from 'context/workflows/workflows-editor.context/provider-context-wrapper' import { WorkflowsEditorComponent } from './components/workflows-editor.component' import { Grid } from '@mui/material' +import { WorkflowsEditorProvider } from 'context/workflows/workflows-editor.context' /** * Workflows editor page */ @@ -11,7 +13,11 @@ export const WorkflowsEditorPage = () => { - + + + + + diff --git a/frontend/src/services/requests/workflow/workflow.interface.ts b/frontend/src/services/requests/workflow/workflow.interface.ts index de6f2a97..d5da5355 100644 --- a/frontend/src/services/requests/workflow/workflow.interface.ts +++ b/frontend/src/services/requests/workflow/workflow.interface.ts @@ -1,6 +1,6 @@ export interface IWorkflowElement { id: string - type: string + type?: string data: { name: string handleOrientation: "horizontal" | "vertical" From a8564e0e13ffe8509b52576cef2c38b1cb41f521 Mon Sep 17 00:00:00 2001 From: Nathan Vieira Marcelino Date: Thu, 6 Jul 2023 07:22:32 -0300 Subject: [PATCH 109/328] refactor: edit storage and containerResources use react-hook-form to deal with forms --- .../container-resource-form.component.tsx | 61 +-- .../sidebar-form.component/index.tsx | 227 +++++++-- .../components/sidebar-form.component/old.tsx | 480 ------------------ .../storage-form.component.tsx | 58 +-- 4 files changed, 228 insertions(+), 598 deletions(-) delete mode 100644 frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component/old.tsx diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component/container-resource-form.component.tsx b/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component/container-resource-form.component.tsx index 5acad332..5ffbea5e 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component/container-resource-form.component.tsx +++ b/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component/container-resource-form.component.tsx @@ -8,8 +8,8 @@ import { } from '@mui/material' import * as yup from "yup"; -import { useForm } from "react-hook-form"; -import useYupValidationResolver from "utils/validationResolver"; +import { useFormContext } from "react-hook-form"; +import { IWorkflowPieceData } from "context/workflows/types"; // TODO check if these values make sense const minAcceptedMemory = 128 @@ -17,7 +17,7 @@ const minAcceptedCpu = 100 const maxAcceptedMemory = 12800 const maxAcceptedCpu = 10000 -const defaultContainerResources = { +export const defaultContainerResources = { useGpu: false, memoryMin: 128, memoryMax: 128, @@ -25,33 +25,15 @@ const defaultContainerResources = { cpuMax: 100 } -export const formSchema = yup.object().shape({ +export const ContainerResourceFormSchema = yup.object().shape({ cpuMin: yup.number().integer().max(maxAcceptedCpu).min(minAcceptedCpu).required(), cpuMax: yup.number().integer().max(maxAcceptedCpu).min(minAcceptedCpu).required(), memoryMin: yup.number().integer().max(maxAcceptedMemory).min(minAcceptedMemory).required(), memoryMax: yup.number().integer().max(maxAcceptedMemory).min(minAcceptedMemory).required(), }); -interface IContainerResourceFormData { - useGpu: boolean, - cpuMin: number, - cpuMax: number - memoryMin: number, - memoryMax: number -} - -interface IContainerResourceFormProps { - onChange: (data: IContainerResourceFormData) => void -} - -const ContainerResourceForm: React.FC = ({ onChange }) => { - - const resolver = useYupValidationResolver(formSchema); - const { register, watch, formState } = useForm({ resolver, mode: "onChange"}); - - - const data = watch() - onChange(data) +const ContainerResourceForm: React.FC = () => { + const { register, formState } = useFormContext(); return ( @@ -62,72 +44,67 @@ const ContainerResourceForm: React.FC = ({ onChange } label="Use GPU" diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component/index.tsx b/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component/index.tsx index 29e5e8a6..401195c3 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component/index.tsx +++ b/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component/index.tsx @@ -1,20 +1,28 @@ -import React, { useCallback } from 'react' +import React, { useCallback, useEffect, useState } from 'react' import { Drawer, Grid, Typography, - Accordion, AccordionSummary, AccordionDetails } from '@mui/material' import ExpandMoreIcon from '@mui/icons-material/ExpandMore'; +import { FormProvider, useForm } from 'react-hook-form'; + +import * as yup from "yup" import { useWorkflowsEditor } from 'context/workflows/workflows-editor.context' + import { extractDefaultValues } from 'utils' import PieceForm from '../piece-form.component' -import ContainerResourceForm from './container-resource-form.component'; -import StorageForm from './storage-form.component'; + +import ContainerResourceForm, { ContainerResourceFormSchema, defaultContainerResources } from './container-resource-form.component'; + +import StorageForm, { defaultStorage, storageFormSchema } from './storage-form.component'; + +import { IWorkflowPieceData } from 'context/workflows/types'; +import useYupValidationResolver from 'utils/validationResolver'; interface ISidebarPieceFormProps { formId: string, @@ -24,6 +32,18 @@ interface ISidebarPieceFormProps { onClose: (event: any) => void, } +const defaultValues = { + containerResources: defaultContainerResources, + storage: defaultStorage, + inputs: {}, +} + +const SidebarPieceFormSchema = yup.object().shape({ + storage: storageFormSchema, + containerResources: ContainerResourceFormSchema, + inputs: yup.object().unknown() +}) as unknown as ReturnType; + const SidebarPieceForm: React.FC = (props) => { const { schema, @@ -33,21 +53,135 @@ const SidebarPieceForm: React.FC = (props) => { title, } = props + const [formData, setFormData] = useState({}) + const [formJsonSchema, setFormJsonSchema] = useState({ ...schema }) + const { + setForageWorkflowPiecesData, + fetchForageWorkflowPiecesDataById, + setFormsForageData, + fetchForageDataById, + getForageUpstreamMap, + setForageUpstreamMap, + getNameKeyUpstreamArgsMap + } = useWorkflowsEditor() + + const resolver = useYupValidationResolver(SidebarPieceFormSchema); + + const methods = useForm({ + defaultValues, + resolver, + mode: "onChange" + }) + const data = methods.watch() + + const loadData = useCallback(async () => { + const data = await fetchForageWorkflowPiecesDataById(formId) + methods.reset(data) // put forage data on form if exist + }, [formId, methods.reset]) + + const saveData = useCallback(async () => { + if (formId && open) { + await setForageWorkflowPiecesData(formId, data as IWorkflowPieceData) + } + }, [formId, open, data]) + + // Update form data in forage + const handleOnChange = useCallback(async ({ errors, data }: { errors?: any, data: any }) => { + try { + var upstreamMap = await getForageUpstreamMap() + const nameKeyUpstreamArgsMap = await getNameKeyUpstreamArgsMap() + var upstreamMapFormInfo = (formId in upstreamMap) ? upstreamMap[formId] : {} + for (const key in data) { + const fromUpstream = upstreamMapFormInfo[key] ? upstreamMapFormInfo[key].fromUpstream : false + const upstreamId = fromUpstream && upstreamMapFormInfo[key] ? upstreamMapFormInfo[key].upstreamId : null + if (key !== 'storage') { + var dataValue = data[key] + if (Array.isArray(dataValue)) { + const auxValue = [] + for (const element of dataValue) { + const newValue: any = {} + if (typeof element === 'object') { + for (const [_key, _value] of Object.entries(element)) { + newValue[_key] = { + fromUpstream: fromUpstream, + upstreamId: upstreamId, + upstreamArgument: null, + value: _value + } + } + auxValue.push(newValue) + } else { + newValue[key] = { + fromUpstream: fromUpstream, + upstreamId: upstreamId, + upstreamArgument: null, + value: element + } + auxValue.push(newValue) + } + } + dataValue = auxValue + } + upstreamMapFormInfo[key] = { + fromUpstream: fromUpstream, + upstreamId: upstreamId, + upstreamArgument: fromUpstream && nameKeyUpstreamArgsMap[data[key]] ? nameKeyUpstreamArgsMap[data[key]] : null, + value: (dataValue === null || dataValue === undefined) ? null : dataValue + } + } + } + + upstreamMap[formId] = upstreamMapFormInfo + await setFormsForageData(formId, data) + await setForageUpstreamMap(upstreamMap) + } catch (err) { + console.log(err) + } + }, [formId, setFormsForageData, getForageUpstreamMap, setForageUpstreamMap, getNameKeyUpstreamArgsMap]) + + useEffect(() => { + setFormJsonSchema({ ...schema }) + }, [schema]) + //load forage + useEffect(() => { + if (open) { + loadData() + } else { + methods.reset() + } + }, [open, loadData]) - const handleSaveForage = useCallback((data:any)=>{ - //save on forage with pieceFormsData using context - /** - * pieceFormsData : { - * formId: { - * containerResources: {}, - * storage: {}, - * inputs: {}, - * } - * } - */ - console.log(data) - },[]) + // When opened fetch forage data and update forms data + useEffect(() => { + const fetchForage = async () => { + const forageData = await fetchForageDataById(formId) + + if (!forageData) { + const defaultData = extractDefaultValues(formJsonSchema) + handleOnChange({ data: defaultData }) + setFormData(defaultData) + return + } + + handleOnChange({ data: forageData }) + setFormData(forageData) + } + if (open) { fetchForage() } + + }, [ + formId, + formJsonSchema, + open, + fetchForageDataById, + setFormsForageData, + handleOnChange, + ]) + + // save on forage + useEffect(() => { + saveData() + }, [saveData]) return ( = (props) => { - - - {/* */} + + + + + + +
+ + + }> + + Advanced Options + + + + +
+ + + + -
- - - }> - - Advanced Options - - - - -
- - - -
diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component/old.tsx b/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component/old.tsx deleted file mode 100644 index 22e647c7..00000000 --- a/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component/old.tsx +++ /dev/null @@ -1,480 +0,0 @@ -import { useCallback, useEffect, useState } from 'react' -import { - Divider, - Drawer, - Grid, - Typography, - MenuItem, - Select, - FormControl, - InputLabel, - TextField, - FormControlLabel, - Checkbox, - Accordion, - AccordionSummary, - AccordionDetails -} from '@mui/material' -import ExpandMoreIcon from '@mui/icons-material/ExpandMore'; - -import { useWorkflowsEditor } from 'context/workflows/workflows-editor.context' -import { extractDefaultValues } from 'utils' -import PieceForm from '../piece-form.component' -// import { createAjv } from '@jsonforms/core' -// import { operatorStorageSchema } from 'common/schemas/storageSchemas' -// import { workflowFormSchema } from 'common/schemas/workflowFormSchema' -// import { containerResourcesSchema } from 'common/schemas/containerResourcesSchemas' -// import { toast } from 'react-toastify' - - -// const handleDefaultsAjv = createAjv({ useDefaults: true }) - -interface ISidebarFormProps { - formSchema: any, - uiSchema?: any, - formId: string, - open: boolean, - onClose: (event: any) => void, - title?: string, - isPieceForm?: boolean, -} - -// TODO check if these values make sense -const minAcceptedMemory = 128 -const minAcceptedCpu = 100 -const maxAcceptedMemory = 12800 -const maxAcceptedCpu = 10000 - -const storageValidationValues: any = { - "memory": { - "min": minAcceptedMemory, - "max": maxAcceptedMemory - }, - "cpu": { - "min": minAcceptedCpu, - "max": maxAcceptedCpu - } -} - -const defaultContainerResources = { - "useGpu": false, - "memory": { - "min": 128, - "max": 128 - }, - "cpu": { - "min": 100, - "max": 100 - } -} - -const defaultErrorState = { - "memory": { - "min": false, - "max": false - }, - "cpu": { - "min": false, - "max": false - } -} - - -const SidebarForm = (props: ISidebarFormProps) => { - const { - formSchema, - formId, - open, - onClose, - title, - isPieceForm = true - } = props - //const [checkboxState, setCheckboxState] = useState({}) - const [formData, setFormData] = useState({}) - const [storageFormData, setStorageFormData] = useState('Read/Write') - const [containerResourcesFormData, setContainerResourcesFormData] = useState(defaultContainerResources) - const [containerResourcesFieldsErrors, setContainerResourcesFieldsErrors] = useState(defaultErrorState); - const [formWidthSpace, setFormWidthSpace] = useState(12) - const [formJsonSchema, setFormJsonSchema] = useState({ ...formSchema }) - const { - setFormsForageData, - fetchForageDataById, - getForageUpstreamMap, - setForageUpstreamMap, - getNameKeyUpstreamArgsMap - } = useWorkflowsEditor() - - useEffect(() => { - setFormJsonSchema({ ...formSchema }) - }, [formSchema]) - - useEffect(() => { - setFormWidthSpace(isPieceForm ? 12 : 12) - }, [isPieceForm]) - - // Update form data in forage - const handleOnChange = useCallback(async ({ errors, data }: { errors?: any, data: any }) => { - try { - var upstreamMap = await getForageUpstreamMap() - const nameKeyUpstreamArgsMap = await getNameKeyUpstreamArgsMap() - var upstreamMapFormInfo = (formId in upstreamMap) ? upstreamMap[formId] : {} - for (const key in data) { - const fromUpstream = upstreamMapFormInfo[key] ? upstreamMapFormInfo[key].fromUpstream : false - const upstreamId = fromUpstream && upstreamMapFormInfo[key] ? upstreamMapFormInfo[key].upstreamId : null - if (key !== 'storage') { - var dataValue = data[key] - if (Array.isArray(dataValue)) { - const auxValue = [] - for (const element of dataValue) { - const newValue: any = {} - if (typeof element === 'object') { - for (const [_key, _value] of Object.entries(element)) { - newValue[_key] = { - fromUpstream: fromUpstream, - upstreamId: upstreamId, - upstreamArgument: null, - value: _value - } - } - auxValue.push(newValue) - }else{ - newValue[key] = { - fromUpstream: fromUpstream, - upstreamId: upstreamId, - upstreamArgument: null, - value: element - } - auxValue.push(newValue) - } - } - dataValue = auxValue - } - upstreamMapFormInfo[key] = { - fromUpstream: fromUpstream, - upstreamId: upstreamId, - upstreamArgument: fromUpstream && nameKeyUpstreamArgsMap[data[key]] ? nameKeyUpstreamArgsMap[data[key]] : null, - value: (dataValue === null || dataValue === undefined) ? null : dataValue - } - } - } - - upstreamMap[formId] = upstreamMapFormInfo - await setFormsForageData(formId, data) - await setForageUpstreamMap(upstreamMap) - } catch (err) { - console.log(err) - } - }, [formId, setFormsForageData, getForageUpstreamMap, setForageUpstreamMap, getNameKeyUpstreamArgsMap]) - - // On Change of storage access mode option - const handleOnChangeStorage = useCallback(async (event: any) => { - /* - // On change update node form data in forage - // The storage access mode key is inside the node form data in the `storage` key - { - ...nodeData, - storage: { - storageAccessMode: 'Enum(Read, Write, ReadWrite)' - } - } - */ - if (!event?.target?.value) { - return - } - const data = event.target.value - const currentData = await fetchForageDataById(formId) - const storageData = currentData?.storage ? currentData.storage : {} - storageData['storageAccessMode'] = data - const outputData = { - ...currentData, - storage: storageData - } - await setFormsForageData(formId, outputData) - setStorageFormData(data) - }, [fetchForageDataById, setFormsForageData, formId]) - - // On Change of container resources options - const handleOnChangeContainerResources = useCallback(async (event: any) => { - if (!event?.target) { - return - } - const { name, value, type, checked } = event.target; - - var parsedValue = value; - if (type === 'number') { - parsedValue = parseInt(value); // Convert the value to a float or use parseInt() for an integer - } - var newContainerResourcesData = {} - var newStorageErrors = { - ...containerResourcesFieldsErrors - } - if (name.includes('.')) { - const firstLevelKey = name.split('.')[0] - const secondLevelKey = name.split('.')[1] - - const validationValue: any = storageValidationValues[firstLevelKey] - - if (parsedValue < validationValue.min || parsedValue > validationValue.max) { - newStorageErrors = { - ...containerResourcesFieldsErrors, - [firstLevelKey]: { - ...containerResourcesFieldsErrors[firstLevelKey], - [secondLevelKey]: true - } - } - } else { - newStorageErrors = { - ...containerResourcesFieldsErrors, - [firstLevelKey]: { - ...containerResourcesFieldsErrors[firstLevelKey], - [secondLevelKey]: false - } - } - } - - newContainerResourcesData = { - ...containerResourcesFormData, - [firstLevelKey]: { - ...containerResourcesFormData[firstLevelKey], - [secondLevelKey]: type === 'checkbox' ? checked : parsedValue - } - } - } else { - const firstLevelKey = name - newContainerResourcesData = { - ...containerResourcesFormData, - [firstLevelKey]: type === 'checkbox' ? checked : value - } - } - - const currentData = await fetchForageDataById(formId) - const outputData = { - ...currentData, - containerResources: newContainerResourcesData - } - await setFormsForageData(formId, outputData) - setContainerResourcesFormData(newContainerResourcesData) - setContainerResourcesFieldsErrors(newStorageErrors) - }, - [ - formId, - fetchForageDataById, - setFormsForageData, - containerResourcesFieldsErrors, - containerResourcesFormData - ]) - - // When opened fetch forage data and update forms data - useEffect(() => { - const fetchForage = async () => { - const forageData = await fetchForageDataById(formId) - - if (!forageData) { - const defaultData = extractDefaultValues(formJsonSchema) - handleOnChange({ data: defaultData }) - setFormData(defaultData) - return - } - - handleOnChange({ data: forageData }) - // If the form has checkboxes, we need to update the storage data - if (!forageData.storage) { - setStorageFormData("Read/Write") - } else { - setStorageFormData(forageData.storage.storageAccessMode) - } - - if (!forageData.containerResources) { - setContainerResourcesFormData(defaultContainerResources) - } else { - setContainerResourcesFormData(forageData.containerResources) - } - setFormData(forageData) - } - if (open) { fetchForage() } - - }, [ - formId, - formJsonSchema, - open, - fetchForageDataById, - setFormsForageData, - handleOnChange, - isPieceForm, - ]) - - return ( - -
- { - title ? {title} :
- } - - { - isPieceForm ? -
- - - Input Arguments - - - Upstream - - - - - - - - - -
- - - }> - - Advanced Options - - - - - - Storage - - - - Storage Access Mode - - - - - -
- - - - Container Resources - - - - - - - - - - - - - - - - } - label="Use GPU" - /> - - - - - - -
- : null - } - -
-
- - ) -}; - -export default SidebarForm; \ No newline at end of file diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component/storage-form.component.tsx b/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component/storage-form.component.tsx index b0f3a6a2..ab6ac0fc 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component/storage-form.component.tsx +++ b/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component/storage-form.component.tsx @@ -1,32 +1,19 @@ import React from 'react'; -import { useForm } from 'react-hook-form'; +import { Controller, useFormContext } from 'react-hook-form'; import * as yup from 'yup' -import useYupValidationResolver from 'utils/validationResolver'; import { FormControl, FormHelperText, Grid, InputLabel, MenuItem, Select, Typography } from '@mui/material'; +import { IWorkflowPieceData, storageAccessModeType, storageAccessModes } from 'context/workflows/types'; -const storageAccessModes = ['None', 'Read', 'Read/Write'] as const -type storageAccessModeType = typeof storageAccessModes - -export const formSchema = yup.object().shape({ - storageAccessMode: yup.mixed().oneOf(storageAccessModes).required(), +export const storageFormSchema = yup.object().shape({ + storageAccessMode: yup.mixed().oneOf(Object.values(storageAccessModes)).required(), }); -interface IStorageFormData { - storageAccessMode: storageAccessModeType, -} - -interface IStorageFormProps { - onChange: (data: IStorageFormData) => void +export const defaultStorage = { + storageAccessMode: storageAccessModes.None as storageAccessModeType } - -const StorageForm: React.FC = ({ onChange }) => { - const resolver = useYupValidationResolver(formSchema); - const { register, watch, formState } = useForm({ resolver, mode: "onChange" }); - - const data = watch() - - onChange(data) +const StorageForm: React.FC = () => { + const { formState, control } = useFormContext(); return ( @@ -36,18 +23,27 @@ const StorageForm: React.FC = ({ onChange }) => { Storage Access Mode - + render={({ field }) => ( + + )} + /> + + - {formState.errors.storageAccessMode?.message} + {formState.errors.storage?.storageAccessMode?.message} From 981f63a39f0e0f9dba932edc8c3026918df80610 Mon Sep 17 00:00:00 2001 From: Nathan Vieira Marcelino Date: Fri, 7 Jul 2023 14:58:43 -0300 Subject: [PATCH 110/328] chore:use tab indentation as 2 in front-end --- frontend/.editorconfig | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 frontend/.editorconfig diff --git a/frontend/.editorconfig b/frontend/.editorconfig new file mode 100644 index 00000000..5d47c21c --- /dev/null +++ b/frontend/.editorconfig @@ -0,0 +1,12 @@ +# EditorConfig is awesome: https://EditorConfig.org + +# top-most EditorConfig file +root = true + +[*] +indent_style = space +indent_size = 2 +end_of_line = lf +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = true From 581c543bc8f44cd649e16618fade33fdd844086a Mon Sep 17 00:00:00 2001 From: Nathan Vieira Marcelino Date: Fri, 7 Jul 2023 14:59:42 -0300 Subject: [PATCH 111/328] chore: improve types on workflow pieces data --- frontend/src/context/workflows/types/index.ts | 1 + frontend/src/context/workflows/types/input.ts | 8 ++++++++ .../src/context/workflows/types/workflow-piece-data.ts | 10 ++-------- frontend/src/utils/validationResolver.ts | 4 ++-- 4 files changed, 13 insertions(+), 10 deletions(-) create mode 100644 frontend/src/context/workflows/types/input.ts diff --git a/frontend/src/context/workflows/types/index.ts b/frontend/src/context/workflows/types/index.ts index d45d46cf..aebc89a7 100644 --- a/frontend/src/context/workflows/types/index.ts +++ b/frontend/src/context/workflows/types/index.ts @@ -1,3 +1,4 @@ export * from "./container-resources" export * from "./storage" export * from "./workflow-piece-data" +export * from "./input" diff --git a/frontend/src/context/workflows/types/input.ts b/frontend/src/context/workflows/types/input.ts new file mode 100644 index 00000000..612a54ce --- /dev/null +++ b/frontend/src/context/workflows/types/input.ts @@ -0,0 +1,8 @@ +import { Dayjs } from "dayjs"; + +export interface IInput { + fromUpstream: boolean, //? allowed | never | always + upstreamArgument: string | null, + upstreamId: string | null, + value: string | number | boolean | Dayjs | null | IInput[] +} diff --git a/frontend/src/context/workflows/types/workflow-piece-data.ts b/frontend/src/context/workflows/types/workflow-piece-data.ts index 4370392a..b14ae490 100644 --- a/frontend/src/context/workflows/types/workflow-piece-data.ts +++ b/frontend/src/context/workflows/types/workflow-piece-data.ts @@ -1,15 +1,9 @@ import { IContainerResourceFormData } from "./container-resources" +import { IInput } from "./input" import { IStorageFormData } from "./storage" export type IWorkflowPieceData = { storage:IStorageFormData, containerResources: IContainerResourceFormData, - inputs: { - [formKey:string]:{ - fromUpstream: boolean, //? allowed | never | always - upstreamArgument: string | null, - upstreamId: string | null, - value: string | any - } - } + inputs: Record } diff --git a/frontend/src/utils/validationResolver.ts b/frontend/src/utils/validationResolver.ts index 32126817..334e7479 100644 --- a/frontend/src/utils/validationResolver.ts +++ b/frontend/src/utils/validationResolver.ts @@ -1,8 +1,8 @@ import { useCallback } from 'react'; -import { object, ValidationError } from 'yup'; +import { ObjectSchema, ValidationError } from 'yup'; const useYupValidationResolver = ( - validationSchema: ReturnType + validationSchema: ObjectSchema> ) => useCallback( async (data: any) => { From 8318378ae39ca0a0fff96d41d2b64d1d34d5de32 Mon Sep 17 00:00:00 2001 From: Nathan Vieira Marcelino Date: Fri, 7 Jul 2023 15:00:47 -0300 Subject: [PATCH 112/328] refactor: improve clear forage function --- .../workflow-editor-panel.component.tsx | 29 ++++++++++++++----- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/workflow-editor-panel.component.tsx b/frontend/src/pages/private/workflows/workflows-editor/components/workflow-editor-panel.component.tsx index 9b061a32..f6227eba 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/components/workflow-editor-panel.component.tsx +++ b/frontend/src/pages/private/workflows/workflows-editor/components/workflow-editor-panel.component.tsx @@ -21,8 +21,9 @@ import SidebarForm from './sidebar-form.component' import { useWorkflowsEditor } from "context/workflows/workflows-editor.context" import { INodeData } from './custom-node.component' import { containerResourcesSchema } from 'common/schemas/containerResourcesSchemas' +import { IWorkflowPieceData, storageAccessModes } from 'context/workflows/types' /** - * @todo When change the workspace should we clear the forage ? + * @todo When change the workspace should we clear the forage ? * @todo Solve any types */ @@ -62,7 +63,8 @@ const WorkflowEditorPanelComponent = () => { setForageWorkflowPieces, getForageWorkflowPieces, removeForageWorkflowPiecesById, - fetchWorkflowPieceById + fetchWorkflowPieceById, + setForageWorkflowPiecesData, } = useWorkflowsEditor() // Removing flowchart elements @@ -153,7 +155,7 @@ const WorkflowEditorPanelComponent = () => { for (const key in defaultData) { const fromUpstream = false // TODO - If someday we allow default upstream true we should change this const upstreamId = null - + var defaultValues = defaultData[key] if (Array.isArray(defaultData[key])){ const auxDefaultValues = [] @@ -175,12 +177,12 @@ const WorkflowEditorPanelComponent = () => { upstreamId: upstreamId, upstreamArgument: null, value: element - } + } auxDefaultValues.push(newValue) } } defaultValues = auxDefaultValues - } + } upstreamMapFormInfo[key] = { fromUpstream, upstreamId, @@ -192,9 +194,19 @@ const WorkflowEditorPanelComponent = () => { } upstreamMap[newNode.id] = upstreamMapFormInfo await setForageUpstreamMap(upstreamMap) + + // TODO: refactor types here + const defaultWorkflowPieceData = { + storage: {storageAccessMode: storageAccessModes.ReadWrite}, + containerResources: containerResourcesDefaultData, + inputs: upstreamMapFormInfo + } as unknown as IWorkflowPieceData + + await setForageWorkflowPiecesData(newNode.id,defaultWorkflowPieceData) + defaultData['storage'] = { - "storageAccessMode": 'Read/Write', - } + "storageAccessMode": 'Read/Write', + } defaultData['containerResources'] = containerResourcesDefaultData // Set default data for the node form - used in json-forms await setFormsForageData(newNode.id, defaultData) @@ -207,7 +219,8 @@ const WorkflowEditorPanelComponent = () => { reactFlowInstance, setNodes, setForageWorkflowPieces, - getForageWorkflowPieces + getForageWorkflowPieces, + setForageWorkflowPiecesData, ]) // Left drawer controls From 23d82671d7b900b087588a9da286dcc41ee1f038 Mon Sep 17 00:00:00 2001 From: Nathan Vieira Marcelino Date: Wed, 12 Jul 2023 09:28:58 -0300 Subject: [PATCH 113/328] refactor: react hook form with piece form --- .../piece-form-codeeditor-item.component.tsx | 52 +- .../piece-form-item.component/index.tsx | 699 +++++++----------- .../components/piece-form.component/index.tsx | 170 +++-- .../sidebar-form.component/index.tsx | 103 +-- 4 files changed, 405 insertions(+), 619 deletions(-) diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/piece-form-codeeditor-item.component.tsx b/frontend/src/pages/private/workflows/workflows-editor/components/piece-form-codeeditor-item.component.tsx index 069f2dc9..93531e32 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/components/piece-form-codeeditor-item.component.tsx +++ b/frontend/src/pages/private/workflows/workflows-editor/components/piece-form-codeeditor-item.component.tsx @@ -1,35 +1,27 @@ -import React, { useState } from 'react'; +import React from 'react'; import CodeEditor from '@uiw/react-textarea-code-editor'; +const CodeEditorItem = ({ ...register }) => { -interface CodeEditorItemProps { - itemSchema: any; - codeValue: string; - onChange: (value: any) => void; -} - -const CodeEditorItem: React.FC = ({ itemSchema, codeValue, onChange }) => { - - return ( - onChange(event.target.value)} - padding={15} - style={{ - fontSize: 12, - backgroundColor: "#f5f5f5", - fontFamily: 'ui-monospace,SFMono-Regular,SF Mono,Consolas,Liberation Mono,Menlo,monospace', - borderRadius: 4, - border: "1px solid #ddd", - width: "100%", - minHeight: "200px", - maxHeight: "400px", - overflowY: "scroll", - }} - /> - ); + return ( + + ); }; -export default React.memo(CodeEditorItem); \ No newline at end of file +export default React.forwardRef(CodeEditorItem); diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/piece-form-item.component/index.tsx b/frontend/src/pages/private/workflows/workflows-editor/components/piece-form-item.component/index.tsx index 0799090e..0c98ab28 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/components/piece-form-item.component/index.tsx +++ b/frontend/src/pages/private/workflows/workflows-editor/components/piece-form-item.component/index.tsx @@ -1,15 +1,14 @@ -import React, { useState, useCallback, useEffect } from 'react'; +import React, { useCallback, useEffect, useMemo, useState } from 'react'; import { - TextField, - Select, - MenuItem, - Checkbox, - FormControlLabel, - Box, - FormControl, - InputLabel, - SelectChangeEvent, - Grid + TextField, + Select, + MenuItem, + Checkbox, + FormControlLabel, + Box, + FormControl, + InputLabel, + Grid, } from '@mui/material'; import { DemoContainer } from '@mui/x-date-pickers/internals/demo'; import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; @@ -23,461 +22,263 @@ import dayjs from 'dayjs'; import { useWorkflowsEditor } from 'context/workflows/workflows-editor.context' import ArrayInputItem from '../piece-form-arrayinput-item.component'; import CodeEditorItem from '../piece-form-codeeditor-item.component'; +import { UseFormRegister, Control, Controller, useFormContext } from 'react-hook-form'; +import { IInput, IWorkflowPieceData } from 'context/workflows/types'; interface PieceFormItemProps { - formId: string; - schema: any; - itemKey: any; - value: any; - onChange: (val: any) => void; + formId: string; + schema: any; + itemKey: string; + inputProperties: IInput; + register: UseFormRegister + control: Control + definitions?: any + upstreamOptions: string[] } -const PieceFormItem: React.FC = ({ formId, schema, itemKey, value, onChange }) => { - const { - fetchForageWorkflowEdges, - getForageUpstreamMap, - setForageUpstreamMap, - fetchForagePieceById, - getForageCheckboxStates, - setForageCheckboxStates, - setNameKeyUpstreamArgsMap, - getNameKeyUpstreamArgsMap, - } = useWorkflowsEditor(); - - var formFieldType = schema.properties[itemKey].type; - const formFieldFormat = schema.properties[itemKey].format; - if (formFieldFormat !== undefined && formFieldFormat !== null) { - formFieldType = formFieldFormat; - } - if ('allOf' in schema.properties[itemKey] || "oneOf" in schema.properties[itemKey] || "anyOf" in schema.properties[itemKey]) { - formFieldType = 'enum' - } - const [formLabelUpstreamIdMap, setFormLabelUpstreamIdMap] = useState>({}); - const [upstreamOptions, setUpstreamOptions] = useState([]); - const [upstreamSelectValue, setUpstreamSelectValue] = useState(''); - const [checkedFromUpstream, setCheckedFromUpstream] = useState(() => { - if (schema.properties[itemKey]?.from_upstream === "always") { - if (schema.properties[itemKey].type === 'array') { - return false; - } - return true; - } else { - return false; - } - }); - - // The schema for this item - let itemSchema: any = schema.properties[itemKey]; - - // The value for this item - if (value === undefined) { - value = itemSchema.default; - } - +const PieceFormItem: React.FC = ({ formId, upstreamOptions, itemKey, inputProperties, schema, definitions, register, control }) => { + const [checkedFromUpstream, setCheckedFromUpstream] = useState(false) + const [checkedFromUpstreamAllowed, checkedFromUpstreamEditable] = useMemo(() => { // from_upstream condition, if "never" or "always" - let checkedFromUpstreamAllowed: boolean = true; - let checkedFromUpstreamEditable: boolean = true; - let arrayItemsFromUpstreamOption: string = "allowed"; - if (itemSchema?.from_upstream === "never") { - checkedFromUpstreamAllowed = false; - checkedFromUpstreamEditable = false; - if (itemSchema.type === 'array') { - arrayItemsFromUpstreamOption = "never"; - } - } else if (itemSchema?.from_upstream === "always") { - checkedFromUpstreamAllowed = true; - checkedFromUpstreamEditable = false; - if (itemSchema.type === 'array') { - checkedFromUpstreamAllowed = false; - arrayItemsFromUpstreamOption = "always"; - } + let allowed: boolean = true; + let editable: boolean = true; + let arrayItems: string = "allowed"; + if (schema?.from_upstream === "never") { + allowed = false; + editable = false; + if (schema.type === 'array') { + arrayItems = "never"; + } + } else if (schema?.from_upstream === "always") { + allowed = true; + editable = false; + if (schema.type === 'array') { + allowed = false; + arrayItems = "always"; + } } + return [allowed, editable, arrayItems] + }, [schema]) - // Handle input change - const handleInputChange = useCallback((event: any, source: string) => { - let fieldValue = event?.target?.value || ""; - if (source === 'datePicker' || source === 'dateTimePicker') { - const newDate = event; - fieldValue = new Date(newDate).toISOString(); - } else if (source === 'timePicker') { - const newTime = event; - fieldValue = dayjs(newTime).format('HH:mm'); - } else if (source === 'codeeditor') { - fieldValue = event; - } else if (source === 'array') { - fieldValue = event; - } else { - const { name, value, type, checked } = event.target; - fieldValue = type === 'checkbox' ? checked : value; - } - onChange(fieldValue); - }, [onChange]); - - const handleSelectChange = useCallback((event: SelectChangeEvent) => { - onChange(event.target.value as string); - }, [onChange]); + const { setValue } = useFormContext() - const handleCheckboxFromUpstreamChange = useCallback(async (checked: boolean, showWarnings: boolean = true) => { - setCheckedFromUpstream(checked); - const edges = await fetchForageWorkflowEdges() - - var auxCheckboxState: any = await getForageCheckboxStates() - if (!auxCheckboxState) { - auxCheckboxState = {} - } - if (formId in auxCheckboxState) { - auxCheckboxState[formId][itemKey] = checked - } else { - auxCheckboxState[formId] = { - [itemKey]: checked - } - } - await setForageCheckboxStates(auxCheckboxState) - - var upstreamsIds = [] - for (var ed of edges) { - if (ed.target === formId) { - upstreamsIds.push(ed.source) - } - } - if (!upstreamsIds.length && showWarnings) { - auxCheckboxState[formId][itemKey] = false - setCheckedFromUpstream(false); - await setForageCheckboxStates(auxCheckboxState) - toast.error('This piece has no upstreams.') - return - } - - var upstreamMap = await getForageUpstreamMap() - if (!(formId in upstreamMap)) { - upstreamMap[formId] = {} - } - - const auxNameKeyUpstreamArgsMap: any = {} - const auxLabelUpstreamIdMap: any = {} - const upstreamOptions: string[] = [] - for (const upstreamId of upstreamsIds) { - const upstreamOperatorId = parseInt(upstreamId.split('_')[0]) - var fromUpstream = false - if (checked) { - const upstreamOperator = await fetchForagePieceById(upstreamOperatorId) - const upstreamOutputSchema = upstreamOperator?.output_schema - Object.keys(upstreamOutputSchema?.properties).forEach((key, index) => { - const obj = upstreamOutputSchema?.properties[key] - var objType = obj.format ? obj.format : obj.type - if ('allOf' in obj || "oneOf" in obj || "anyOf" in obj) { - objType = 'enum' - } - - if (objType === formFieldType) { - var upstreamOptionName = `${upstreamOperator?.name} - ${obj['title']}` - const counter = 1; - while (upstreamOptions.includes(upstreamOptionName)) { - upstreamOptionName = `${upstreamOptionName} (${counter})` - } - upstreamOptions.push(upstreamOptionName) - auxNameKeyUpstreamArgsMap[upstreamOptionName] = key - auxLabelUpstreamIdMap[upstreamOptionName] = upstreamId - } - }) - fromUpstream = true - } - upstreamMap[formId][itemKey] = { - ...upstreamMap[formId][itemKey], - fromUpstream: fromUpstream, - upstreamId: null, - } - } - if (checked && !upstreamOptions.length && showWarnings) { - auxCheckboxState[formId][itemKey] = false - setCheckedFromUpstream(false); - await setForageCheckboxStates(auxCheckboxState) - toast.error('There are no upstream outputs with the same type as the selected field') - return - } - - var upstreamValue = upstreamMap[formId][itemKey].value || "" - if (!checked) { - upstreamValue = value - } - if (upstreamOptions.length && !upstreamOptions.includes(upstreamValue)) { - upstreamValue = upstreamOptions[0] - } - const upstreamId = upstreamValue && auxLabelUpstreamIdMap[upstreamValue] ? - auxLabelUpstreamIdMap[upstreamValue] : null - const upstreamArgument = upstreamValue && auxNameKeyUpstreamArgsMap[upstreamValue] - ? auxNameKeyUpstreamArgsMap[upstreamValue] : null - - if (Array.isArray(upstreamValue)) { - const auxValues = [] - for (const element of upstreamValue) { - const newValue: any = {} - if (typeof element === 'object') { - for (const [_key, _value] of Object.entries(element)) { - newValue[_key] = { - fromUpstream: upstreamMap[formId][itemKey].fromUpstream, - upstreamId: upstreamId, - upstreamArgument: null, - value: _value - } - } - auxValues.push(newValue) - } else { - newValue[itemKey] = { - fromUpstream: upstreamMap[formId][itemKey].fromUpstream, - upstreamId: upstreamId, - upstreamArgument: null, - value: element - } - auxValues.push(newValue) - } - } - upstreamValue = auxValues - } - + const handleCheckFromUpstream = useCallback((value: boolean, cb: (e: boolean) => void) => { + if (value === false) { + setValue(`inputs.${itemKey}.value`, schema?.default) + } - upstreamMap[formId][itemKey] = { - ...upstreamMap[formId][itemKey], - upstreamId: upstreamId, - value: upstreamValue, - upstreamArgument: upstreamArgument - } - setUpstreamOptions(upstreamOptions) - setFormLabelUpstreamIdMap(auxLabelUpstreamIdMap) - const currentNameKeyUpstreamArgsMap = await getNameKeyUpstreamArgsMap() - setNameKeyUpstreamArgsMap({ ...auxNameKeyUpstreamArgsMap, ...currentNameKeyUpstreamArgsMap }) - setForageUpstreamMap(upstreamMap) - setUpstreamSelectValue(upstreamValue) - }, [ - value, - formId, - itemKey, - fetchForageWorkflowEdges, - getForageCheckboxStates, - setForageCheckboxStates, - getForageUpstreamMap, - formFieldType, - fetchForagePieceById, - setForageUpstreamMap, - getNameKeyUpstreamArgsMap, - setNameKeyUpstreamArgsMap, - ]); + setCheckedFromUpstream(value); + cb(value) + }, [setCheckedFromUpstream]) - // Load checkboxes states from localForage - useEffect(() => { - (async () => { - var auxCheckboxState: any = await getForageCheckboxStates() - if (!(formId in auxCheckboxState)) { - return - } - const formCheckboxStates = auxCheckboxState[formId] - if (formFieldType === 'array' && typeof formCheckboxStates[itemKey] !== 'boolean'){ - return - } - if (itemKey in formCheckboxStates) { - await handleCheckboxFromUpstreamChange(formCheckboxStates[itemKey], false) - } else { - await handleCheckboxFromUpstreamChange(false, false) - } - })() - }, [getForageCheckboxStates, formId, itemKey, getForageUpstreamMap, handleCheckboxFromUpstreamChange, formFieldType]) + if (!inputProperties || !Object.keys(inputProperties).length) { + return null + } - // Select fromUpstream source - const handleSelectFromUpstreamChange = useCallback(async (event: SelectChangeEvent) => { - setUpstreamSelectValue(event.target.value as string); - var upstreamMap = await getForageUpstreamMap() - const nameKeyUpstreamArgsMap = await getNameKeyUpstreamArgsMap() - var upstreamMapFormInfo = (formId in upstreamMap) ? upstreamMap[formId] : {} - const fromUpstream = upstreamMapFormInfo[itemKey] ? upstreamMapFormInfo[itemKey].fromUpstream : false - const upstreamId = fromUpstream && formLabelUpstreamIdMap[event.target.value as string] ? formLabelUpstreamIdMap[event.target.value as string] : null + let inputElement: React.ReactNode = null - upstreamMapFormInfo[itemKey] = { - fromUpstream: fromUpstream, - upstreamId: upstreamId, - upstreamArgument: fromUpstream && nameKeyUpstreamArgsMap[event.target.value] ? nameKeyUpstreamArgsMap[event.target.value] : null, - value: (event.target.value === null || event.target.value === undefined) ? null : event.target.value + if (checkedFromUpstream && upstreamOptions.length) { + inputElement = ( + + {schema?.title} + + + ); + } else if (schema?.allOf && schema.allOf.length > 0) { + const typeClass = schema.allOf[0]['$ref'].split("/").pop(); + const valuesOptions: Array = definitions?.[typeClass].enum; + inputElement = + + {itemKey} + + ; + } else if ((schema.type === 'number') && !schema.format) { + inputElement = + ; + } else if (schema.type === 'integer' && !schema.format) { + inputElement = + ; + } else if (schema.type === 'boolean' && !schema.format) { + inputElement = + ( + field.onChange(!!e.target.checked)} + /> + )} + /> } - upstreamMap[formId] = upstreamMapFormInfo - await setForageUpstreamMap(upstreamMap) - onChange(event.target.value); - }, [ - itemKey, - getForageUpstreamMap, - getNameKeyUpstreamArgsMap, - formId, - setForageUpstreamMap, - onChange, - formLabelUpstreamIdMap - - ]); - - // Set input element based on type - let inputElement: JSX.Element; - if (checkedFromUpstream) { - inputElement = ( - - {itemSchema?.title} - - - ); - } else if (itemSchema?.allOf && itemSchema.allOf.length > 0) { - const typeClass = itemSchema.allOf[0]['$ref'].split("/").pop(); - const valuesOptions: Array = schema?.definitions?.[typeClass].enum; - inputElement = ( - - {itemKey} - - - ); - } else if (itemSchema.type === 'boolean') { - inputElement = handleInputChange(event, "boolean")} - />} - labelPlacement="start" - label={itemSchema.title} - />; - } else if (itemSchema.type === 'number') { - inputElement = handleInputChange(event, "number")} - />; - } else if (itemSchema.type === 'integer') { - inputElement = handleInputChange(event, "integer")} - />; - } else if (itemSchema.type === 'array') { - inputElement = handleInputChange(event, "array")} - /> - } else if (itemSchema.type === 'string' && itemSchema?.format === 'date') { - inputElement = ( - - - handleInputChange(event, "datePicker")} - /> - - - ); - } else if (itemSchema.type === 'string' && itemSchema?.format === 'time') { - inputElement = ( - - - handleInputChange(event, "timePicker")} - /> - - - ); - } else if (itemSchema.type === 'string' && itemSchema?.format === 'datetime') { - inputElement = ( + labelPlacement="start" + label={schema.title} + />; + } else if (schema.type === 'string' && schema.format === 'date') { + inputElement = + ( + - - handleInputChange(event, "dateTimePicker")} - /> - + { onChange(dayjs(e).format('YYYY-MM-DD')) }} + {...rest} + /> - ); - } else if (itemSchema.type === 'string' && itemSchema?.widget === 'codeeditor') { - inputElement = ( - handleInputChange(event, "codeeditor")} - codeValue={value} - /> - ) - } else if (itemSchema.type === 'string') { - inputElement = ( - handleInputChange(event, "string")} - /> - ); - } else { - inputElement =
- Unknown widget type for {itemSchema.title} -
; - } +
+ )} + />; + } else if (schema.type === 'string' && schema?.format === 'time') { + inputElement = + ( + + + { onChange(dayjs(e).format('HH:mm')) }} + {...rest} + /> + + + )} + />; + } else if (schema.type === 'string' && schema?.format === 'date-time') { + inputElement = + ( + + + - - {inputElement} - - {checkedFromUpstreamAllowed ? ( - - handleCheckboxFromUpstreamChange(event.target.checked)} - disabled={!checkedFromUpstreamEditable} - /> - - ) : null} - - ); + value={dayjs(value as string, 'YYYY-MM-DD HH:mm')} + onChange={(e) => { onChange(dayjs(e).format('YYYY-MM-DD HH:mm')) }} + {...rest} + /> + + + )} + />; + } + else if (schema.type === 'string' && schema?.widget === 'codeeditor') { + inputElement = + ( + + )} + />; + } else if (schema.type === 'string' && !schema.format) { + inputElement = + ; + } else { + inputElement =
+ Unknown widget type for {schema.title} +
; + } + + return ( + + + {inputElement} + + {checkedFromUpstreamAllowed ? ( + + ( + handleCheckFromUpstream(e.target.checked, field.onChange)} + /> + )} + + /> + + ) : null} + + ); }; export default PieceFormItem; diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/piece-form.component/index.tsx b/frontend/src/pages/private/workflows/workflows-editor/components/piece-form.component/index.tsx index 492f0f18..69be6740 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/components/piece-form.component/index.tsx +++ b/frontend/src/pages/private/workflows/workflows-editor/components/piece-form.component/index.tsx @@ -1,51 +1,137 @@ -import React, { useState, useEffect } from 'react'; +import React, { useCallback, useEffect, useMemo, useState } from 'react'; import PieceFormItem from '../piece-form-item.component'; - - -type initialDataType = Record; +import { useFormContext } from 'react-hook-form'; +import { IWorkflowPieceData } from 'context/workflows/types'; +import * as yup from "yup" +import { useWorkflowsEditor } from 'context/workflows/workflows-editor.context'; interface PieceFormProps { - formId: string; - schema: any; - initialData: initialDataType; - onChange: ({ errors, data }: { errors?: any, data: any }) => void; + formId: string; + schema: any; } -const PieceForm: React.FC = ({ formId, schema, initialData, onChange }) => { - const [formData, setFormData] = useState(initialData); - - const handleChange = (key: string) => (value: any) => { - setFormData(prevData => ({ ...prevData, [key]: value })); - // setNodePieceSchema() - }; - - useEffect(() => { - onChange({ data: formData }); - }, [formData, onChange]); - - useEffect(() => { - setFormData(initialData) - }, [initialData]) - - - if (!schema.properties) return null; - return ( - - { - Object.keys(schema.properties).map(key => ( -
- -
- )) +type UpstreamOptions = Record + +export const inputsSchema = yup.lazy((value) => { + if (!Object.keys(value).length) { + const validationObject = { + fromUpstream: yup.boolean().required(), //? allowed | never | always + upstreamArgument: yup.string().nullable().required(), + upstreamId: yup.string().nullable().required(), + value: yup.lazy(value => { + switch (typeof value) { + case 'object': + return yup.object().required(); + case 'string': + return yup.string().required(); + case 'number': + return yup.number().required(); + default: + return yup.mixed(); // decide what is the default + } + }) + } + const newEntries = Object.keys(value).reduce( + (acc, val) => ({ + ...acc, + [val]: yup.object(validationObject), + }), + {} + ) + + return yup.object().shape(newEntries) + } + return yup.mixed().notRequired() +}) + +const PieceForm: React.FC = ({ formId, schema }) => { + const { fetchForageWorkflowEdges, getForageWorkflowPieces } = useWorkflowsEditor() + const { register, control, watch } = useFormContext() + const { inputs } = watch() + const [upstreamOptions, setUpstreamOptions] = useState({}) + + const shouldRender = useMemo(() => { + return schema.properties && Object.keys(inputs).length + }, [schema, inputs]) + + const getInputType = useCallback((schema: Record) => { + let type = schema.format ? schema.format : schema.type + if ('allOf' in schema || "oneOf" in schema || "anyOf" in schema) { + type = 'enum' + } + return type as string + }, []) + + const handleUpstreamOptions = useCallback(async () => { + if (!shouldRender) { + return + } + + const workflowPieces = await getForageWorkflowPieces(); + const workflowEdges = await fetchForageWorkflowEdges(); + const upstreamIds: string[] = [] + const upstreamOptions = {} as Record + + + for (const ed of workflowEdges) { + if (ed.target === formId) { + upstreamIds.push(ed.source) + } + } + + /** + * TODO: fix counter + */ + Object.keys(schema.properties).map(key => { + const currentSchema = schema.properties[key] + upstreamOptions[key] = upstreamIds.flatMap(upstreamId => { + const upSchema = workflowPieces[upstreamId].output_schema.properties + const currentType = getInputType(currentSchema) + const options: string[] = [] + let counter = 0 + for (const outputs in upSchema) { + const upType = getInputType(upSchema[outputs]) + if (upType === currentType) { + let value = `${workflowPieces[upstreamId]?.name} - ${upSchema[outputs].title}` + if (options.includes(value)) { + ++counter + value = `${value} (${counter})` } - - ); + options.push(value) + } + } + return options + }) + + setUpstreamOptions(upstreamOptions) + }) + }, [fetchForageWorkflowEdges, formId, getForageWorkflowPieces, getInputType, schema.properties, shouldRender]) + + useEffect(() => { + handleUpstreamOptions() + }, []) + + if (!shouldRender) return null; + return ( +
+ { + Object.keys(schema.properties).map(key => ( +
+ +
+ )) + } +
+ ); }; export default React.memo(PieceForm); diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component/index.tsx b/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component/index.tsx index 401195c3..9cf76d66 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component/index.tsx +++ b/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component/index.tsx @@ -14,8 +14,8 @@ import * as yup from "yup" import { useWorkflowsEditor } from 'context/workflows/workflows-editor.context' -import { extractDefaultValues } from 'utils' -import PieceForm from '../piece-form.component' + +import PieceForm, { inputsSchema } from '../piece-form.component' import ContainerResourceForm, { ContainerResourceFormSchema, defaultContainerResources } from './container-resource-form.component'; @@ -32,7 +32,7 @@ interface ISidebarPieceFormProps { onClose: (event: any) => void, } -const defaultValues = { +const defaultValues: IWorkflowPieceData = { containerResources: defaultContainerResources, storage: defaultStorage, inputs: {}, @@ -41,8 +41,8 @@ const defaultValues = { const SidebarPieceFormSchema = yup.object().shape({ storage: storageFormSchema, containerResources: ContainerResourceFormSchema, - inputs: yup.object().unknown() -}) as unknown as ReturnType; + inputs: inputsSchema, +}); const SidebarPieceForm: React.FC = (props) => { const { @@ -53,20 +53,12 @@ const SidebarPieceForm: React.FC = (props) => { title, } = props - const [formData, setFormData] = useState({}) - const [formJsonSchema, setFormJsonSchema] = useState({ ...schema }) const { setForageWorkflowPiecesData, fetchForageWorkflowPiecesDataById, - setFormsForageData, - fetchForageDataById, - getForageUpstreamMap, - setForageUpstreamMap, - getNameKeyUpstreamArgsMap } = useWorkflowsEditor() const resolver = useYupValidationResolver(SidebarPieceFormSchema); - const methods = useForm({ defaultValues, resolver, @@ -85,63 +77,6 @@ const SidebarPieceForm: React.FC = (props) => { } }, [formId, open, data]) - // Update form data in forage - const handleOnChange = useCallback(async ({ errors, data }: { errors?: any, data: any }) => { - try { - var upstreamMap = await getForageUpstreamMap() - const nameKeyUpstreamArgsMap = await getNameKeyUpstreamArgsMap() - var upstreamMapFormInfo = (formId in upstreamMap) ? upstreamMap[formId] : {} - for (const key in data) { - const fromUpstream = upstreamMapFormInfo[key] ? upstreamMapFormInfo[key].fromUpstream : false - const upstreamId = fromUpstream && upstreamMapFormInfo[key] ? upstreamMapFormInfo[key].upstreamId : null - if (key !== 'storage') { - var dataValue = data[key] - if (Array.isArray(dataValue)) { - const auxValue = [] - for (const element of dataValue) { - const newValue: any = {} - if (typeof element === 'object') { - for (const [_key, _value] of Object.entries(element)) { - newValue[_key] = { - fromUpstream: fromUpstream, - upstreamId: upstreamId, - upstreamArgument: null, - value: _value - } - } - auxValue.push(newValue) - } else { - newValue[key] = { - fromUpstream: fromUpstream, - upstreamId: upstreamId, - upstreamArgument: null, - value: element - } - auxValue.push(newValue) - } - } - dataValue = auxValue - } - upstreamMapFormInfo[key] = { - fromUpstream: fromUpstream, - upstreamId: upstreamId, - upstreamArgument: fromUpstream && nameKeyUpstreamArgsMap[data[key]] ? nameKeyUpstreamArgsMap[data[key]] : null, - value: (dataValue === null || dataValue === undefined) ? null : dataValue - } - } - } - - upstreamMap[formId] = upstreamMapFormInfo - await setFormsForageData(formId, data) - await setForageUpstreamMap(upstreamMap) - } catch (err) { - console.log(err) - } - }, [formId, setFormsForageData, getForageUpstreamMap, setForageUpstreamMap, getNameKeyUpstreamArgsMap]) - - useEffect(() => { - setFormJsonSchema({ ...schema }) - }, [schema]) //load forage useEffect(() => { @@ -152,32 +87,6 @@ const SidebarPieceForm: React.FC = (props) => { } }, [open, loadData]) - // When opened fetch forage data and update forms data - useEffect(() => { - const fetchForage = async () => { - const forageData = await fetchForageDataById(formId) - - if (!forageData) { - const defaultData = extractDefaultValues(formJsonSchema) - handleOnChange({ data: defaultData }) - setFormData(defaultData) - return - } - - handleOnChange({ data: forageData }) - setFormData(forageData) - } - if (open) { fetchForage() } - - }, [ - formId, - formJsonSchema, - open, - fetchForageDataById, - setFormsForageData, - handleOnChange, - ]) - // save on forage useEffect(() => { saveData() @@ -220,8 +129,6 @@ const SidebarPieceForm: React.FC = (props) => {
From fa5340a3b78d73d1b0bd58881ab9907034ae9fab Mon Sep 17 00:00:00 2001 From: luiz Date: Thu, 13 Jul 2023 13:26:03 +0200 Subject: [PATCH 114/328] outputmodifier model class --- domino/models/__init__.py | 1 + domino/models/output_modifier.py | 32 +++++++++++++++++++++++++++ domino/schemas/container_resources.py | 2 ++ domino/schemas/piece_metadata.py | 2 +- 4 files changed, 36 insertions(+), 1 deletion(-) create mode 100644 domino/models/__init__.py create mode 100644 domino/models/output_modifier.py diff --git a/domino/models/__init__.py b/domino/models/__init__.py new file mode 100644 index 00000000..3707f930 --- /dev/null +++ b/domino/models/__init__.py @@ -0,0 +1 @@ +from .output_modifier import OutputModifierModel, OutputModifierItemType \ No newline at end of file diff --git a/domino/models/output_modifier.py b/domino/models/output_modifier.py new file mode 100644 index 00000000..8d6ddf2a --- /dev/null +++ b/domino/models/output_modifier.py @@ -0,0 +1,32 @@ +from pydantic import BaseModel, Field, FilePath, Extra +from enum import Enum +from typing import List + + +class OutputModifierItemType(str, Enum): + """ + OutputArgsType Enum + """ + string = 'string' + integer = 'integer' + float = 'float' + boolean = 'boolean' + array = 'array' + + +class OutputModifierModel(BaseModel): + name: str = Field( + default=None, + description='Name of the output argument.', + from_upstream="never" + ) + description: str = Field( + default=None, + description='Description of the output argument.', + from_upstream="never" + ) + type: OutputModifierItemType = Field( + default=OutputModifierItemType.string, + description='Type of the output argument.', + from_upstream="never" + ) \ No newline at end of file diff --git a/domino/schemas/container_resources.py b/domino/schemas/container_resources.py index f609ee03..95e55146 100644 --- a/domino/schemas/container_resources.py +++ b/domino/schemas/container_resources.py @@ -1,9 +1,11 @@ from pydantic import BaseModel, Field + class SystemRequirementsModel(BaseModel): cpu: str = Field(regex=r"^\d+\.*\d*m$") memory: str = Field(regex=r"^\d+\.*\d*Mi$") + class ContainerResourcesModel(BaseModel): requests: SystemRequirementsModel = Field(default=SystemRequirementsModel(cpu="100m", memory="128Mi")) limits: SystemRequirementsModel = Field(default=SystemRequirementsModel(cpu="100m", memory="128Mi")) \ No newline at end of file diff --git a/domino/schemas/piece_metadata.py b/domino/schemas/piece_metadata.py index 6f9c06e1..b9943a14 100644 --- a/domino/schemas/piece_metadata.py +++ b/domino/schemas/piece_metadata.py @@ -46,7 +46,7 @@ class PieceMetadata(BaseModel): name: str = Field( description="Piece name", example="ExamplePiece", - # regex= # TODO - regex for *Operator + # regex= # TODO - regex for *Piece ) description: str = Field( description="Description of this Piece", From cd442bf6f7c47d0c1a20ccc4054cd414c6b045fb Mon Sep 17 00:00:00 2001 From: luiz Date: Thu, 13 Jul 2023 13:39:24 +0200 Subject: [PATCH 115/328] improve modular imports --- domino/base_piece.py | 3 +-- domino/cli/utils/pieces_repository.py | 2 +- domino/custom_operators/docker_operator.py | 2 +- domino/custom_operators/k8s_operator.py | 2 +- domino/schemas/__init__.py | 9 +++++++++ domino/task.py | 4 +--- 6 files changed, 14 insertions(+), 8 deletions(-) diff --git a/domino/base_piece.py b/domino/base_piece.py index ae763631..19502054 100644 --- a/domino/base_piece.py +++ b/domino/base_piece.py @@ -12,8 +12,7 @@ import base64 from domino.logger import get_configured_logger -from domino.schemas.deploy_mode import DeployModeType -from domino.schemas.display_result import DisplayResultFileType +from domino.schemas import DeployModeType, DisplayResultFileType from domino.exceptions.exceptions import InvalidPieceOutputError diff --git a/domino/cli/utils/pieces_repository.py b/domino/cli/utils/pieces_repository.py index e3270e15..b916e687 100644 --- a/domino/cli/utils/pieces_repository.py +++ b/domino/cli/utils/pieces_repository.py @@ -169,7 +169,7 @@ def validate_pieces_folders() -> None: """ Validate the Pieces folders from an Pieces repository. """ - from domino.schemas.piece_metadata import PieceMetadata + from domino.schemas import PieceMetadata pieces_path = Path(".") / "pieces" dependencies_path = Path(".") / "dependencies" diff --git a/domino/custom_operators/docker_operator.py b/domino/custom_operators/docker_operator.py index 0bd0b4a3..79af40f3 100644 --- a/domino/custom_operators/docker_operator.py +++ b/domino/custom_operators/docker_operator.py @@ -3,7 +3,7 @@ from typing import Dict, Optional import os from domino.client.domino_backend_client import DominoBackendRestClient -from domino.schemas.shared_storage import WorkflowSharedStorage, StorageSource +from domino.schemas import WorkflowSharedStorage, StorageSource class DominoDockerOperator(DockerOperator): diff --git a/domino/custom_operators/k8s_operator.py b/domino/custom_operators/k8s_operator.py index 0f80eb6d..55461833 100644 --- a/domino/custom_operators/k8s_operator.py +++ b/domino/custom_operators/k8s_operator.py @@ -7,7 +7,7 @@ from contextlib import closing from kubernetes.stream import stream as kubernetes_stream from domino.client.domino_backend_client import DominoBackendRestClient -from domino.schemas.shared_storage import WorkflowSharedStorage +from domino.schemas import WorkflowSharedStorage # Ref: https://github.com/apache/airflow/blob/main/airflow/providers/cncf/kubernetes/operators/kubernetes_pod.py diff --git a/domino/schemas/__init__.py b/domino/schemas/__init__.py index e69de29b..49c52291 100644 --- a/domino/schemas/__init__.py +++ b/domino/schemas/__init__.py @@ -0,0 +1,9 @@ +from .container_resources import ContainerResourcesModel +from .deploy_mode import DeployModeType +from .display_result import DisplayResultFileType +from .piece_metadata import PieceMetadata +from .shared_storage import ( + WorkflowSharedStorage, + StorageSource, + shared_storage_map +) \ No newline at end of file diff --git a/domino/task.py b/domino/task.py index d1a04d2c..ac8dc860 100644 --- a/domino/task.py +++ b/domino/task.py @@ -6,11 +6,9 @@ from domino.custom_operators.docker_operator import DominoDockerOperator from domino.custom_operators.python_operator import PythonOperator from domino.custom_operators.k8s_operator import DominoKubernetesPodOperator -from domino.schemas.shared_storage import shared_storage_map from domino.utils import dict_deep_update from domino.logger import get_configured_logger -from domino.schemas.shared_storage import StorageSource -from domino.schemas.container_resources import ContainerResourcesModel +from domino.schemas import ContainerResourcesModel, shared_storage_map, StorageSource from kubernetes import client, config import os From b25e1b83618f3a190f3c5d32f1d7769911e902c4 Mon Sep 17 00:00:00 2001 From: luiz Date: Thu, 13 Jul 2023 13:39:43 +0200 Subject: [PATCH 116/328] remove unused --- domino/schemas/from_upstream.py | 10 ---------- 1 file changed, 10 deletions(-) delete mode 100644 domino/schemas/from_upstream.py diff --git a/domino/schemas/from_upstream.py b/domino/schemas/from_upstream.py deleted file mode 100644 index 34410f28..00000000 --- a/domino/schemas/from_upstream.py +++ /dev/null @@ -1,10 +0,0 @@ -from pydantic import BaseModel, Field - - -class FromUpstream(BaseModel): - upstream_task_id: str = Field( - description="Upstream task id", - ) - output_arg: str = Field( - description="Output argument from upstream task", - ) \ No newline at end of file From 5292af34802d59c275ad6c0a51c0c5edad4d8723 Mon Sep 17 00:00:00 2001 From: luiz Date: Thu, 13 Jul 2023 21:57:02 +0200 Subject: [PATCH 117/328] list as type --- domino/models/output_modifier.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/domino/models/output_modifier.py b/domino/models/output_modifier.py index 8d6ddf2a..0525efcd 100644 --- a/domino/models/output_modifier.py +++ b/domino/models/output_modifier.py @@ -1,4 +1,4 @@ -from pydantic import BaseModel, Field, FilePath, Extra +from pydantic import BaseModel, Field from enum import Enum from typing import List @@ -14,7 +14,7 @@ class OutputModifierItemType(str, Enum): array = 'array' -class OutputModifierModel(BaseModel): +class SingleOutputModifierModel(BaseModel): name: str = Field( default=None, description='Name of the output argument.', @@ -29,4 +29,7 @@ class OutputModifierModel(BaseModel): default=OutputModifierItemType.string, description='Type of the output argument.', from_upstream="never" - ) \ No newline at end of file + ) + + +OutputModifierModel: List[SingleOutputModifierModel] \ No newline at end of file From 5a43e7b22c26f754014a34dbcdd2cd66a7f88074 Mon Sep 17 00:00:00 2001 From: luiz Date: Fri, 14 Jul 2023 17:35:02 +0200 Subject: [PATCH 118/328] not list --- domino/models/output_modifier.py | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/domino/models/output_modifier.py b/domino/models/output_modifier.py index 0525efcd..7b2b724c 100644 --- a/domino/models/output_modifier.py +++ b/domino/models/output_modifier.py @@ -14,7 +14,7 @@ class OutputModifierItemType(str, Enum): array = 'array' -class SingleOutputModifierModel(BaseModel): +class OutputModifierModel(BaseModel): name: str = Field( default=None, description='Name of the output argument.', @@ -29,7 +29,4 @@ class SingleOutputModifierModel(BaseModel): default=OutputModifierItemType.string, description='Type of the output argument.', from_upstream="never" - ) - - -OutputModifierModel: List[SingleOutputModifierModel] \ No newline at end of file + ) \ No newline at end of file From a94920d62fd83a4cafe59eb328d1b84294ab93fa Mon Sep 17 00:00:00 2001 From: Nathan Vieira Marcelino Date: Mon, 17 Jul 2023 06:49:45 -0300 Subject: [PATCH 119/328] refactor: form components on each file --- frontend/src/context/workflows/types/input.ts | 21 +- .../workflows/types/workflow-piece-data.ts | 5 +- .../components/custom-node.component.tsx | 5 +- .../index.tsx | 611 ------------------ .../piece-form-codeeditor-item.component.tsx | 27 - .../checkbox-input.tsx | 33 + .../codeeditor-input.tsx | 40 ++ .../datetime-input.tsx | 88 +++ .../piece-form-item.component/index.tsx | 248 +++---- .../number-input.tsx | 32 + .../select-input.tsx | 35 + .../select-upstream-input.tsx | 65 ++ .../piece-form-item.component/text-input.tsx | 25 + .../components/piece-form.component/index.tsx | 31 +- .../workflow-editor-panel.component.tsx | 1 + 15 files changed, 431 insertions(+), 836 deletions(-) delete mode 100644 frontend/src/pages/private/workflows/workflows-editor/components/piece-form-arrayinput-item.component/index.tsx delete mode 100644 frontend/src/pages/private/workflows/workflows-editor/components/piece-form-codeeditor-item.component.tsx create mode 100644 frontend/src/pages/private/workflows/workflows-editor/components/piece-form-item.component/checkbox-input.tsx create mode 100644 frontend/src/pages/private/workflows/workflows-editor/components/piece-form-item.component/codeeditor-input.tsx create mode 100644 frontend/src/pages/private/workflows/workflows-editor/components/piece-form-item.component/datetime-input.tsx create mode 100644 frontend/src/pages/private/workflows/workflows-editor/components/piece-form-item.component/number-input.tsx create mode 100644 frontend/src/pages/private/workflows/workflows-editor/components/piece-form-item.component/select-input.tsx create mode 100644 frontend/src/pages/private/workflows/workflows-editor/components/piece-form-item.component/select-upstream-input.tsx create mode 100644 frontend/src/pages/private/workflows/workflows-editor/components/piece-form-item.component/text-input.tsx diff --git a/frontend/src/context/workflows/types/input.ts b/frontend/src/context/workflows/types/input.ts index 612a54ce..532b1de8 100644 --- a/frontend/src/context/workflows/types/input.ts +++ b/frontend/src/context/workflows/types/input.ts @@ -1,8 +1,25 @@ import { Dayjs } from "dayjs"; -export interface IInput { +type Value = string | number | boolean | Dayjs | null +interface BaseInput { fromUpstream: boolean, //? allowed | never | always upstreamArgument: string | null, upstreamId: string | null, - value: string | number | boolean | Dayjs | null | IInput[] + upstreamValue: string | null, + value: Value } + +interface ObjectInput { + fromUpstream: boolean, //? allowed | never | always + upstreamArgument: string | null, + upstreamId: string | null, + upstreamValue: string | null, + value: Record +} + +export type InputArray = BaseInput & { + value: Record[] +} + +export type Input = BaseInput + diff --git a/frontend/src/context/workflows/types/workflow-piece-data.ts b/frontend/src/context/workflows/types/workflow-piece-data.ts index b14ae490..6372aa9c 100644 --- a/frontend/src/context/workflows/types/workflow-piece-data.ts +++ b/frontend/src/context/workflows/types/workflow-piece-data.ts @@ -1,9 +1,10 @@ import { IContainerResourceFormData } from "./container-resources" -import { IInput } from "./input" +import { InputArray, Input } from "./input" import { IStorageFormData } from "./storage" export type IWorkflowPieceData = { storage:IStorageFormData, containerResources: IContainerResourceFormData, - inputs: Record + inputs: Record + } diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/custom-node.component.tsx b/frontend/src/pages/private/workflows/workflows-editor/components/custom-node.component.tsx index 260f2155..57a605cb 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/components/custom-node.component.tsx +++ b/frontend/src/pages/private/workflows/workflows-editor/components/custom-node.component.tsx @@ -12,7 +12,7 @@ interface IStyleData { iconId: string } /** - * @todo improve dtypes + * @todo improve dtypes */ export interface INodeData { name: string @@ -101,6 +101,9 @@ const CustomNode = memo((data: any) => { { extendedData?.style?.label ? extendedData?.style?.label : extendedData?.name } +

+ {data.id.substring(2, 8)} +

{ useIcon ? ( diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/piece-form-arrayinput-item.component/index.tsx b/frontend/src/pages/private/workflows/workflows-editor/components/piece-form-arrayinput-item.component/index.tsx deleted file mode 100644 index fb0f095d..00000000 --- a/frontend/src/pages/private/workflows/workflows-editor/components/piece-form-arrayinput-item.component/index.tsx +++ /dev/null @@ -1,611 +0,0 @@ -import React, { useState, useCallback, useMemo, useEffect } from 'react'; -import { - Card, - CardContent, - IconButton, - Box, - Checkbox, - Select, - MenuItem, - FormControl, - InputLabel, -} from '@mui/material'; -import TextField from '@mui/material/TextField'; -import DeleteIcon from '@mui/icons-material/Delete'; -import AddIcon from '@mui/icons-material/Add'; -import { useWorkflowsEditor } from 'context/workflows/workflows-editor.context' -import { toast } from 'react-toastify'; - - -enum FromUpstreamOptions { - always = "always", - never = "never", - allowed = "allowed" -} - -// Arrays usually have their inner schema defined in the main schema definitions -interface ArrayInputItemProps { - formId: string; - itemKey: string; - itemSchema: any; - parentSchemaDefinitions: any; - fromUpstreamMode?: FromUpstreamOptions | string; - arrayItems: Array | { [key: string]: any }[]; - onChange: (value: any) => void; -} - -const ArrayInputItem: React.FC = ({ - formId, - itemKey, - itemSchema, - parentSchemaDefinitions, - fromUpstreamMode, - arrayItems, - onChange -}) => { - - const { - fetchForageWorkflowEdges, - getForageUpstreamMap, - setForageUpstreamMap, - fetchForagePieceById, - getForageCheckboxStates, - setForageCheckboxStates, - } = useWorkflowsEditor(); - - // Sub-items schema - let subItemSchema: any = itemSchema.items; - if (itemSchema.items?.$ref) { - const subItemSchemaName = itemSchema.items.$ref.split('/').pop(); - subItemSchema = parentSchemaDefinitions[subItemSchemaName]; - } - const itemsType = subItemSchema?.type - let arrayOfProperties: { [key: string]: any } = useMemo(()=>{return {}},[]); - // If array subtypes were not defined in the schema, we create a default one - if (subItemSchema?.properties) { - arrayOfProperties = subItemSchema?.properties; - } else { - arrayOfProperties[itemKey] = { - "title": itemSchema.title, - "type": itemsType, - "description": itemSchema.description, - }; - } - const numProps = Object.keys(arrayOfProperties).length; - - const [upstreamOptions, setUpstreamOptions] = useState([]); - const [renderElements, setRenderElements] = useState(null) - - type ObjectWithBooleanValues = { [key: string]: {[key: string]: boolean} }; - const [checkedFromUpstreamItemProp, setCheckedFromUpstreamItemProp] = useState(() => { - if (itemSchema.default && itemSchema.default.length > 0) { - const initArray = new Array(itemSchema.default.length).fill({}); - // set the default values from the schema in cases where from_upstream==="always" - initArray.map((obj, index) => { - initArray[index][itemKey] = {} - Object.keys(arrayOfProperties).map((_key) => { - if (subItemSchema?.properties?.[itemKey]?.from_upstream === "always") { - initArray[index][itemKey][_key] = true; - } else { - initArray[index][itemKey][_key] = false; - } - return null; - }); - return null; - }); - return initArray; - } - return []; - }); - - - const handleArrayItemChange = useCallback((index: number, itemKey: string, value: string) => { - const updatedItems = [...arrayItems]; - updatedItems[index][itemKey] = value; - onChange(updatedItems); - }, [onChange, arrayItems]); - - // Add and delete items - // TODO - fix setArrayItems to fill the props with correct values types, - // right now just guessing an empty string, but this will most likely fail e.g. boolen types - const handleAddItem = useCallback(async() => { - const newItemDefaultValue: string = '' - let newItemPropsChecked: ObjectWithBooleanValues = { - [itemKey]: {} - }; - Object.keys(arrayOfProperties).map((_key) => { - if (subItemSchema?.properties?.[itemKey]?.from_upstream === "always") { - newItemPropsChecked[itemKey][_key] = true; - } else { - newItemPropsChecked[itemKey][_key] = false; - } - return null; - }); - const upstreamMap = await getForageUpstreamMap() - const fromUpstream = false - const upstreamId = null - const newValue: any = {} - for (const _key of Object.keys(arrayOfProperties)) { - newValue[_key] = { - fromUpstream: fromUpstream, - upstreamId: upstreamId, - upstreamArgument: null, - value: newItemDefaultValue - } - } - - const newValues = upstreamMap[formId][itemKey].value - newValues.push(newValue) - - const updatedUpstreaMap = { - ...upstreamMap, - [formId]: { - ...upstreamMap[formId], - [itemKey]: { - fromUpstream: fromUpstream, - upstreamId: upstreamId, - upstreamArgument: null, - value: newValues - } - } - } - - const checkboxStates = await getForageCheckboxStates() - const checkboxStatesArray = checkboxStates[formId][itemKey] - checkboxStatesArray.push(newItemPropsChecked[itemKey]) - await setForageCheckboxStates({ - ...checkboxStates, - [formId]: { - ...checkboxStates[formId], - [itemKey]: checkboxStatesArray - } - }) - - - setForageUpstreamMap(updatedUpstreaMap) - setCheckedFromUpstreamItemProp([...checkedFromUpstreamItemProp, newItemPropsChecked]); - onChange([...arrayItems, newItemDefaultValue]); - }, [ - onChange, - arrayItems, - checkedFromUpstreamItemProp, - arrayOfProperties, - subItemSchema, - itemKey, - formId, - getForageUpstreamMap, - setForageUpstreamMap, - getForageCheckboxStates, - setForageCheckboxStates - ]); - - // TODO - this is not working when deleting items with fromUpstrem checked - const handleDeleteItem = useCallback(async(index: number) => { - - const currentCheckboxStates = await getForageCheckboxStates() - const currentCheckboxStatesArray = currentCheckboxStates[formId][itemKey] - currentCheckboxStatesArray.splice(index, 1) - await setForageCheckboxStates({ - ...currentCheckboxStates, - [formId]: { - ...currentCheckboxStates[formId], - [itemKey]: currentCheckboxStatesArray - } - }) - - const upstreamMap = await getForageUpstreamMap() - const currentValues = upstreamMap[formId][itemKey].value - currentValues.splice(index, 1) - await setForageUpstreamMap({ - ...upstreamMap, - [formId]: { - ...upstreamMap[formId], - [itemKey]: { - ...upstreamMap[formId][itemKey], - value: currentValues - } - } - }) - const updatedItems = [...arrayItems]; - updatedItems.splice(index, 1); - const updatedCheckedFromUpstreamItemProp = [...checkedFromUpstreamItemProp]; - updatedCheckedFromUpstreamItemProp.splice(index, 1); - setCheckedFromUpstreamItemProp(updatedCheckedFromUpstreamItemProp); - onChange(updatedItems); - - }, [ - onChange, - arrayItems, - checkedFromUpstreamItemProp, - itemKey, - formId, - getForageUpstreamMap, - setForageUpstreamMap, - getForageCheckboxStates, - setForageCheckboxStates, - ]); - - - - const _handleCheckboxFromUpstreamChange = useCallback(async (checked: boolean, index: number, checkboxKey: string) => { - //const checked = event.target.checked; - setCheckedFromUpstreamItemProp((prevArray) => { - const newArray = prevArray.map((item, i) => { - for (const [key, value] of Object.entries(item)) { - for (const valueKey of Object.keys(value)) { - if (i === index && valueKey === checkboxKey) { - return { - ...item, - [key]: { - ...value, - [valueKey]: checked - } - }; - } - } - } - return item; - }); - return newArray; - }); - - const edges = await fetchForageWorkflowEdges() - var auxCheckboxState: any = await getForageCheckboxStates() - if (!auxCheckboxState) { - auxCheckboxState = {} - } - - - - var upstreamsIds = [] - for (var ed of edges) { - if (ed.target === formId) { - upstreamsIds.push(ed.source) - } - } - - if (!upstreamsIds.length) { - // set checkbox react states to false - setCheckedFromUpstreamItemProp((prevArray) => { - const newArray = prevArray.map((item, i) => { - for (const [key, value] of Object.entries(item)) { - for (const valueKey of Object.keys(value)) { - if (i === index && valueKey === checkboxKey) { - return { - ...item, - [key]: { - ...value, - [valueKey]: false - } - }; - } - } - } - return item; - }); - return newArray; - }); - await setForageCheckboxStates(auxCheckboxState) - toast.error('This piece has no upstreams.') - return - } - - - for (var i=0; i { - const obj = upstreamOutputSchema?.properties[key] - var objType = obj.format ? obj.format : obj.type - if (itemsType === 'object') { - for (const [subItemKey, subItemValue] of Object.entries(subItemSchema.properties)) { - if (!(subItemKey in upstreamOptions)) { - upstreamOptions[subItemKey] = [] - } - let itemType = subItemValue.format ? subItemValue.format : subItemValue.type - if (objType === itemType && checkboxKey === subItemKey){ - let upstreamOptionName = `${upstreamOperator?.name} - ${obj['title']}` - let counter = 1; - while (upstreamOptions[subItemKey].includes(upstreamOptionName)) { - upstreamOptionName = `${upstreamOptionName} (${counter})` - } - upstreamOptions[subItemKey].push(upstreamOptionName) - auxNameKeyUpstreamArgsMap[upstreamOptionName] = key - auxLabelUpstreamIdMap[upstreamOptionName] = upstreamId - } - } - } - - if (objType === itemsType){ - let upstreamOptionName = `${upstreamOperator?.name} - ${obj['title']}` - let counter = 1; - if (!(itemKey in upstreamOptions)) { - upstreamOptions[itemKey] = [] - } - while (upstreamOptions[itemKey].includes(upstreamOptionName)) { - upstreamOptionName = `${upstreamOptionName} (${counter})` - } - upstreamOptions[itemKey].push(upstreamOptionName) - auxNameKeyUpstreamArgsMap[upstreamOptionName] = key - auxLabelUpstreamIdMap[upstreamOptionName] = upstreamId - } - }) - } - - const auxUpstreamValue: any = {} - for (let _key of Object.keys(upstreamMap[formId][itemKey].value[index])){ - const upstreamValue = upstreamOptions[_key] ? upstreamOptions[_key][0] : null - const valueUpstreamId = upstreamValue && auxLabelUpstreamIdMap[upstreamValue] ? auxLabelUpstreamIdMap[upstreamValue] : null - const upstreamArgument = upstreamValue && auxNameKeyUpstreamArgsMap[upstreamValue] ? auxNameKeyUpstreamArgsMap[upstreamValue] : null - if (checkboxKey === _key){ - auxUpstreamValue[_key] = { - fromUpstream: checked, - value: upstreamValue, - upstreamId: valueUpstreamId, - upstreamArgument: upstreamArgument - } - }else { - auxUpstreamValue[_key] = { - ...upstreamMap[formId][itemKey].value[index][_key] - } - } - } - upstreamMap[formId][itemKey].value[index] = auxUpstreamValue - } - return { - upstreamOptions, - upstreamMap - } - }, [ - arrayOfProperties, - subItemSchema.properties, - getForageUpstreamMap, - //setForageUpstreamMap, - fetchForagePieceById, - fetchForageWorkflowEdges, - getForageCheckboxStates, - formId, - setForageCheckboxStates, - checkedFromUpstreamItemProp, - itemKey, - itemsType - ]); - - const handleCheckboxFromUpstreamChange = useCallback(async (event: React.ChangeEvent, index: number, checkboxKey: string) => { - const results = await _handleCheckboxFromUpstreamChange(event.target.checked, index, checkboxKey) - const upstreamOptions = results?.upstreamOptions - const upstreamMap = results?.upstreamMap - setUpstreamOptions(upstreamOptions) - setForageUpstreamMap(upstreamMap) - }, [_handleCheckboxFromUpstreamChange, setForageUpstreamMap]) - - // FromUpstream select logic - const handleSelectFromUpstreamChange = useCallback((index: number, itemKey: string, value: string) => { - const updatedItems = [...arrayItems]; - if (typeof updatedItems[index] === 'object') { - updatedItems[index][itemKey] = value; - } else { - updatedItems[index] = value; - } - // setArrayItems(updatedItems); - }, [arrayItems]); - - - useEffect(() => { - (async () => { - const newElements: any = {} - const upstreamMap = await getForageUpstreamMap() - const checkboxStates = await getForageCheckboxStates() - - if ((!(formId in checkboxStates))) { - checkboxStates[formId] = {} - } - - if ((!(itemKey in checkboxStates[formId])) || typeof checkboxStates[formId][itemKey] !== 'object') { - checkboxStates[formId][itemKey] = [] - for (let i = 0; i < arrayItems.length; i++) { - const newObj: any = {} - for (let key of Object.keys(arrayOfProperties)) { - newObj[key] = false - } - checkboxStates[formId][itemKey].push(newObj) - } - setForageCheckboxStates(checkboxStates) - } - - if (!(formId in upstreamMap)) { - return - } - if (!(itemKey in upstreamMap[formId])) { - return - } - - var _upstreamOptions = upstreamOptions - const upstreamMapData = upstreamMap[formId][itemKey].value - if ((typeof upstreamMapData !== 'object') || (checkboxStates[formId][itemKey].length === 0) || (checkboxStates[formId][itemKey].length !== arrayItems.length)) { - return - } - - arrayItems.map((item, index) => { - const value = upstreamMapData[index] - let itemElements: JSX.Element[] = []; - // Loop through each of the item's properties and create the inputs for them - Promise.all( - Object.keys(arrayOfProperties).map(async(_itemKey: any, subIndex: any) => { - let inputElement: JSX.Element; - - const subItemPropSchema = arrayOfProperties[_itemKey]; - const title = subItemPropSchema.title - const checkboxFormState = checkboxStates[formId][itemKey] - var checkboxValue = false; - var isParentChecked = false; - if (typeof checkboxFormState === 'boolean'){ - isParentChecked = true - } - if (!(typeof checkboxFormState === 'boolean')){ - checkboxValue = checkboxStates[formId][itemKey][index][_itemKey] - } - - // TODO this can be improved, it is slow but is working for now - // upstreamOptionsArray is undefined when user open the form for the first time - // it is generated only when user clicks on the checkbox - // it will cause a bug if the user close and open the form again since the checkbox will be checked - // but the upstreamOptionsArray will be undefined so the form will be rendered as textfield - // to solve this maybe we need to generate upstreamOptionsArray when the form is opened for the already checked checkboxes - if (upstreamOptions.length === 0 && typeof checkboxFormState !== 'boolean' && checkboxValue) { - const results = await _handleCheckboxFromUpstreamChange(checkboxValue, index, _itemKey) - _upstreamOptions = results?.upstreamOptions - setUpstreamOptions(_upstreamOptions) - setForageUpstreamMap(results?.upstreamMap) - } - var initialValue: any = '' - var upstreamOptionsArray: any = [] - if (!isParentChecked){ - initialValue = value[_itemKey].value || ''; - upstreamOptionsArray = _upstreamOptions[_itemKey] - } - - if (!isParentChecked && (upstreamOptionsArray && value[_itemKey].fromUpstream)) { - inputElement = ( - - {`${title} [${index}]`} - - - ); - } else if (subItemPropSchema?.allOf && subItemPropSchema.allOf.length > 0) { - const typeClass = subItemPropSchema.allOf[0]['$ref'].split("/").pop(); - const valuesOptions: Array = parentSchemaDefinitions?.[typeClass].enum; - inputElement = ( - - {`${title} [${index}]`} - - - ); - } else { - inputElement = handleArrayItemChange(index, itemKey, e.target.value)} - /> - } - itemElements.push( -
- {inputElement} - {subItemPropSchema?.from_upstream !== "never" ? ( - handleCheckboxFromUpstreamChange(event, index, _itemKey)} - disabled={subItemPropSchema?.from_upstream === 'never' || subItemPropSchema?.from_upstream === 'always'} - /> - ) : null} -
- ); - return null; - })); - newElements[index] = (
- {itemElements} -
) - return null; - }) - - setRenderElements(newElements) - })() - }, [ - setForageUpstreamMap, - _handleCheckboxFromUpstreamChange, - formId, - setForageCheckboxStates, - getForageCheckboxStates, - getForageUpstreamMap, - arrayOfProperties, - arrayItems, - checkedFromUpstreamItemProp, - fromUpstreamMode, - handleArrayItemChange, - handleCheckboxFromUpstreamChange, - itemKey, - numProps, - parentSchemaDefinitions, - upstreamOptions, - handleSelectFromUpstreamChange, - ]) - - return ( - -
- - - - {itemSchema.title} -
- - {arrayItems.map((item, index) => ( - - handleDeleteItem(index)} aria-label="Delete"> - - - {renderElements ? renderElements[index] : ''} - - ))} - -
- ); -}; - -export default React.memo(ArrayInputItem); \ No newline at end of file diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/piece-form-codeeditor-item.component.tsx b/frontend/src/pages/private/workflows/workflows-editor/components/piece-form-codeeditor-item.component.tsx deleted file mode 100644 index 93531e32..00000000 --- a/frontend/src/pages/private/workflows/workflows-editor/components/piece-form-codeeditor-item.component.tsx +++ /dev/null @@ -1,27 +0,0 @@ -import React from 'react'; -import CodeEditor from '@uiw/react-textarea-code-editor'; - -const CodeEditorItem = ({ ...register }) => { - - return ( - - ); -}; - -export default React.forwardRef(CodeEditorItem); diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/piece-form-item.component/checkbox-input.tsx b/frontend/src/pages/private/workflows/workflows-editor/components/piece-form-item.component/checkbox-input.tsx new file mode 100644 index 00000000..7bc88705 --- /dev/null +++ b/frontend/src/pages/private/workflows/workflows-editor/components/piece-form-item.component/checkbox-input.tsx @@ -0,0 +1,33 @@ +import { Checkbox, FormControlLabel } from '@mui/material'; +import { IWorkflowPieceData } from 'context/workflows/types'; +import React from 'react'; +import { Controller, useFormContext } from 'react-hook-form'; + +interface Props { + label: string + itemKey: string +} + +const CheckboxInput: React.FC = ({ itemKey, label}) => { + const { control } = useFormContext() + + return ( + field.onChange(!!e.target.checked)} + /> + )} + /> + } + labelPlacement="start" + label={label} +/>; +} + +export default CheckboxInput; diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/piece-form-item.component/codeeditor-input.tsx b/frontend/src/pages/private/workflows/workflows-editor/components/piece-form-item.component/codeeditor-input.tsx new file mode 100644 index 00000000..d51fe886 --- /dev/null +++ b/frontend/src/pages/private/workflows/workflows-editor/components/piece-form-item.component/codeeditor-input.tsx @@ -0,0 +1,40 @@ +import React from 'react'; +import CodeEditor from '@uiw/react-textarea-code-editor'; +import { Controller, useFormContext } from 'react-hook-form'; +import { IWorkflowPieceData } from 'context/workflows/types'; + +const CodeEditorItem = React.forwardRef(({ ...register }) => ( + +)) + +const CodeEditorInput: React.FC<{ itemKey: string }> = ({ itemKey }) => { + const { control } = useFormContext() + + return ( ( + + )} + />); +} + +export default CodeEditorInput; diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/piece-form-item.component/datetime-input.tsx b/frontend/src/pages/private/workflows/workflows-editor/components/piece-form-item.component/datetime-input.tsx new file mode 100644 index 00000000..ec91199f --- /dev/null +++ b/frontend/src/pages/private/workflows/workflows-editor/components/piece-form-item.component/datetime-input.tsx @@ -0,0 +1,88 @@ +import React from 'react'; +import { Controller, useFormContext } from 'react-hook-form'; +import dayjs from 'dayjs'; + +import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; +import { DatePicker, DateTimePicker, LocalizationProvider, TimePicker } from '@mui/x-date-pickers'; +import { DemoContainer } from '@mui/x-date-pickers/internals/demo'; +import { IWorkflowPieceData } from 'context/workflows/types'; + +interface Props { + label: string + itemKey: string + defaultValue: string + type?: "time" | "date" | "date-time" +} + +const DatetimeInput: React.FC = ({ label, itemKey, defaultValue, type="date" }) => { + + const { control } = useFormContext() + + switch (type) { + case "date-time": + return ( + + + { onChange(dayjs(e).format('YYYY-MM-DD HH:mm')) }} + {...rest} + /> + + + )} + />; + case 'time': + return ( + + + { onChange(dayjs(e).format('HH:mm')) }} + {...rest} + /> + + + )} + />; + case 'date': + default: + return ( + + + { onChange(dayjs(e).format('YYYY-MM-DD')) }} + {...rest} + /> + + + )} + />; + } +} + +export default DatetimeInput; diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/piece-form-item.component/index.tsx b/frontend/src/pages/private/workflows/workflows-editor/components/piece-form-item.component/index.tsx index 0c98ab28..9f8f089e 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/components/piece-form-item.component/index.tsx +++ b/frontend/src/pages/private/workflows/workflows-editor/components/piece-form-item.component/index.tsx @@ -1,44 +1,34 @@ -import React, { useCallback, useEffect, useMemo, useState } from 'react'; +import React, { useMemo } from 'react'; import { - TextField, - Select, - MenuItem, Checkbox, - FormControlLabel, Box, - FormControl, - InputLabel, Grid, } from '@mui/material'; -import { DemoContainer } from '@mui/x-date-pickers/internals/demo'; -import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; -import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; -import { DatePicker } from '@mui/x-date-pickers/DatePicker'; -import { TimePicker } from '@mui/x-date-pickers/TimePicker'; -import { DateTimePicker } from '@mui/x-date-pickers/DateTimePicker'; -import { toast } from 'react-toastify'; -import dayjs from 'dayjs'; - -import { useWorkflowsEditor } from 'context/workflows/workflows-editor.context' -import ArrayInputItem from '../piece-form-arrayinput-item.component'; -import CodeEditorItem from '../piece-form-codeeditor-item.component'; import { UseFormRegister, Control, Controller, useFormContext } from 'react-hook-form'; -import { IInput, IWorkflowPieceData } from 'context/workflows/types'; + +import { Input, IWorkflowPieceData, InputArray } from 'context/workflows/types'; +import { Option } from '../piece-form.component'; + +import SelectUpstreamInput from './select-upstream-input'; +import NumberInput from './number-input'; +import CheckboxInput from './checkbox-input'; +import SelectInput from './select-input'; +import DatetimeInput from './datetime-input'; +import CodeEditorInput from './codeeditor-input'; +import TextInput from './text-input'; interface PieceFormItemProps { - formId: string; schema: any; itemKey: string; - inputProperties: IInput; + inputProperties: Input | InputArray; register: UseFormRegister control: Control definitions?: any - upstreamOptions: string[] + upstreamOptions: Option[] } -const PieceFormItem: React.FC = ({ formId, upstreamOptions, itemKey, inputProperties, schema, definitions, register, control }) => { - const [checkedFromUpstream, setCheckedFromUpstream] = useState(false) +const PieceFormItem: React.FC = ({ upstreamOptions, itemKey, inputProperties, schema, definitions, register, control }) => { const [checkedFromUpstreamAllowed, checkedFromUpstreamEditable] = useMemo(() => { // from_upstream condition, if "never" or "always" let allowed: boolean = true; @@ -61,16 +51,9 @@ const PieceFormItem: React.FC = ({ formId, upstreamOptions, return [allowed, editable, arrayItems] }, [schema]) - const { setValue } = useFormContext() - - const handleCheckFromUpstream = useCallback((value: boolean, cb: (e: boolean) => void) => { - if (value === false) { - setValue(`inputs.${itemKey}.value`, schema?.default) - } - - setCheckedFromUpstream(value); - cb(value) - }, [setCheckedFromUpstream]) + const { watch } = useFormContext() + const data = watch() + const checkedFromUpstream = data.inputs[itemKey]?.fromUpstream if (!inputProperties || !Object.keys(inputProperties).length) { return null @@ -80,169 +63,83 @@ const PieceFormItem: React.FC = ({ formId, upstreamOptions, if (checkedFromUpstream && upstreamOptions.length) { inputElement = ( - - {schema?.title} - - - ); + ); } else if (schema?.allOf && schema.allOf.length > 0) { const typeClass = schema.allOf[0]['$ref'].split("/").pop(); const valuesOptions: Array = definitions?.[typeClass].enum; inputElement = - - {itemKey} - - ; + } else if ((schema.type === 'number') && !schema.format) { inputElement = - ; + defaultValue={schema?.default ?? 10.5} + /> } else if (schema.type === 'integer' && !schema.format) { inputElement = - ; + defaultValue={schema?.default ?? 10} + /> } else if (schema.type === 'boolean' && !schema.format) { - inputElement = - ( - field.onChange(!!e.target.checked)} - /> - )} - /> - } - labelPlacement="start" - label={schema.title} - />; + inputElement = + } else if (schema.type === 'array') { + inputElement = null + // } else if (schema.type === 'string' && schema.format === 'date') { inputElement = - ( - - - { onChange(dayjs(e).format('YYYY-MM-DD')) }} - {...rest} - /> - - - )} + ; } else if (schema.type === 'string' && schema?.format === 'time') { inputElement = - ( - - - { onChange(dayjs(e).format('HH:mm')) }} - {...rest} - /> - - - )} + ; } else if (schema.type === 'string' && schema?.format === 'date-time') { inputElement = - ( - - - { onChange(dayjs(e).format('YYYY-MM-DD HH:mm')) }} - {...rest} - /> - - - )} + ; } else if (schema.type === 'string' && schema?.widget === 'codeeditor') { inputElement = - ( - - )} - />; + } else if (schema.type === 'string' && !schema.format) { inputElement = - ; + ; } else { inputElement =
Unknown widget type for {schema.title} @@ -264,16 +161,15 @@ const PieceFormItem: React.FC = ({ formId, upstreamOptions, ( handleCheckFromUpstream(e.target.checked, field.onChange)} + onChange={field.onChange} /> )} - /> ) : null} diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/piece-form-item.component/number-input.tsx b/frontend/src/pages/private/workflows/workflows-editor/components/piece-form-item.component/number-input.tsx new file mode 100644 index 00000000..62b5f45b --- /dev/null +++ b/frontend/src/pages/private/workflows/workflows-editor/components/piece-form-item.component/number-input.tsx @@ -0,0 +1,32 @@ +import { TextField } from '@mui/material'; +import { IWorkflowPieceData } from 'context/workflows/types'; +import React from 'react'; +import { useFormContext } from 'react-hook-form'; + +interface Props { + label: string + itemKey: string + defaultValue: number + type: "float" | "int" +} + +const NumberInput: React.FC = ({ itemKey, label, type="int", defaultValue}) => { + const { register } = useFormContext() + + return ( + ); +} + +export default NumberInput; diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/piece-form-item.component/select-input.tsx b/frontend/src/pages/private/workflows/workflows-editor/components/piece-form-item.component/select-input.tsx new file mode 100644 index 00000000..136ad09d --- /dev/null +++ b/frontend/src/pages/private/workflows/workflows-editor/components/piece-form-item.component/select-input.tsx @@ -0,0 +1,35 @@ +import { FormControl, InputLabel, MenuItem, Select } from '@mui/material'; +import React from 'react'; +import { useFormContext } from 'react-hook-form'; +import { IWorkflowPieceData } from 'context/workflows/types'; + +interface Props { + label: string + itemKey: string + defaultValue: string + options: string[] +} + +const SelectInput: React.FC = ({ options, label, itemKey, defaultValue }) => { + const { register } = useFormContext() + + return ( + + {label} + + ); +} + +export default SelectInput; diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/piece-form-item.component/select-upstream-input.tsx b/frontend/src/pages/private/workflows/workflows-editor/components/piece-form-item.component/select-upstream-input.tsx new file mode 100644 index 00000000..8b6ce01f --- /dev/null +++ b/frontend/src/pages/private/workflows/workflows-editor/components/piece-form-item.component/select-upstream-input.tsx @@ -0,0 +1,65 @@ +import { FormControl, InputLabel, MenuItem, Select, SelectChangeEvent } from '@mui/material'; +import React, { useCallback } from 'react'; +import { Controller, useFormContext } from 'react-hook-form'; +import { Option } from '../piece-form.component'; +import { IWorkflowPieceData } from 'context/workflows/types'; + +interface Props { + label: string + itemKey: string + options: Option[] +} + +const SelectUpstreamInput: React.FC = ({options, label, itemKey}) => { + const {getValues, setValue, control} = useFormContext() + + const handleSelectChange = useCallback((event: SelectChangeEvent, onChange: (e: any) => void) => { + const value = event.target.value + const upstream = options.find(op => op?.value === value) as Option + + const data = getValues(`inputs.${itemKey}`) + console.log("upstream",upstream) + + setValue(`inputs.${itemKey}`, { + ...data, + upstreamArgument: upstream.argument, + upstreamId: upstream.id + }) + + onChange(event) + }, [getValues, itemKey, options, setValue]); + + + return ( + + {label} + ( + + )} + /> + + ); +} + +export default SelectUpstreamInput; diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/piece-form-item.component/text-input.tsx b/frontend/src/pages/private/workflows/workflows-editor/components/piece-form-item.component/text-input.tsx new file mode 100644 index 00000000..55038206 --- /dev/null +++ b/frontend/src/pages/private/workflows/workflows-editor/components/piece-form-item.component/text-input.tsx @@ -0,0 +1,25 @@ +import { TextField } from '@mui/material'; +import { IWorkflowPieceData } from 'context/workflows/types'; +import React from 'react'; +import { useFormContext } from 'react-hook-form'; + +interface Props { + label: string + itemKey: string + defaultValue?: string +} + +const TextInput: React.FC = ({ itemKey, label, defaultValue =""}) => { + const { register } = useFormContext() + + return ( + ); +} + +export default TextInput; diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/piece-form.component/index.tsx b/frontend/src/pages/private/workflows/workflows-editor/components/piece-form.component/index.tsx index 69be6740..1cac1588 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/components/piece-form.component/index.tsx +++ b/frontend/src/pages/private/workflows/workflows-editor/components/piece-form.component/index.tsx @@ -10,7 +10,13 @@ interface PieceFormProps { schema: any; } -type UpstreamOptions = Record +export type Option = { + id: string, + argument: string, + value: string +} + +type UpstreamOptions = Record export const inputsSchema = yup.lazy((value) => { if (!Object.keys(value).length) { @@ -70,8 +76,7 @@ const PieceForm: React.FC = ({ formId, schema }) => { const workflowPieces = await getForageWorkflowPieces(); const workflowEdges = await fetchForageWorkflowEdges(); const upstreamIds: string[] = [] - const upstreamOptions = {} as Record - + const upstreamOptions = {} as Record for (const ed of workflowEdges) { if (ed.target === formId) { @@ -79,25 +84,18 @@ const PieceForm: React.FC = ({ formId, schema }) => { } } - /** - * TODO: fix counter - */ - Object.keys(schema.properties).map(key => { + Object.keys(schema.properties).forEach(key => { const currentSchema = schema.properties[key] upstreamOptions[key] = upstreamIds.flatMap(upstreamId => { const upSchema = workflowPieces[upstreamId].output_schema.properties const currentType = getInputType(currentSchema) - const options: string[] = [] - let counter = 0 + const options: Option[] = [] for (const outputs in upSchema) { const upType = getInputType(upSchema[outputs]) if (upType === currentType) { - let value = `${workflowPieces[upstreamId]?.name} - ${upSchema[outputs].title}` - if (options.includes(value)) { - ++counter - value = `${value} (${counter})` - } - options.push(value) + const value = `${workflowPieces[upstreamId]?.name} - ${upSchema[outputs].title} (${upstreamId.substring(2, 8)})` + const upstreamArgument = outputs + options.push({ id: upstreamId, argument: upstreamArgument, value }) } } return options @@ -109,7 +107,7 @@ const PieceForm: React.FC = ({ formId, schema }) => { useEffect(() => { handleUpstreamOptions() - }, []) + }, [handleUpstreamOptions]) if (!shouldRender) return null; return ( @@ -118,7 +116,6 @@ const PieceForm: React.FC = ({ formId, schema }) => { Object.keys(schema.properties).map(key => (
{ fromUpstream, upstreamId, upstreamArgument: null, + upstreamValue: "", value: ( defaultValues === null || defaultValues === undefined ) ? null : defaultValues From 3c5bbd0e8a0c17fdf5646e0ead909310a9e49548 Mon Sep 17 00:00:00 2001 From: luiz Date: Wed, 19 Jul 2023 19:49:11 +0200 Subject: [PATCH 120/328] comment docker mount --- domino/custom_operators/docker_operator.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/domino/custom_operators/docker_operator.py b/domino/custom_operators/docker_operator.py index 70bd2231..a65631fe 100644 --- a/domino/custom_operators/docker_operator.py +++ b/domino/custom_operators/docker_operator.py @@ -52,7 +52,7 @@ def __init__( # TODO remove mounts=[ # TODO remove - Mount(source='/media/luiz/storage2/Github/domino/domino', target='/home/domino/domino_py/domino', type='bind', read_only=True), + # Mount(source='/media/luiz/storage2/Github/domino/domino', target='/home/domino/domino_py/domino', type='bind', read_only=True), # Mount(source='/media/luiz/storage2/Github/default_domino_pieces', target='/home/domino/pieces_repository/', type='bind', read_only=True), ] if self.workflow_shared_storage and str(self.workflow_shared_storage.source.value).lower() == str(getattr(StorageSource, 'local').value).lower(): From 5add7c530d145787ffeca529ffd18072b4c4614c Mon Sep 17 00:00:00 2001 From: Nathan Vieira Marcelino Date: Thu, 20 Jul 2023 22:23:37 -0300 Subject: [PATCH 121/328] feat: add array input --- frontend/src/context/workflows/types/input.ts | 4 +- .../components/custom-node.component.tsx | 2 +- .../piece-form-item.component/array-input.tsx | 230 ++++++++++++++++++ .../checkbox-input.tsx | 44 ++-- .../codeeditor-input.tsx | 6 +- .../datetime-input.tsx | 49 ++-- .../piece-form-item.component/index.tsx | 138 ++++++----- .../number-input.tsx | 12 +- .../select-input.tsx | 8 +- .../select-upstream-input.tsx | 72 +++--- .../piece-form-item.component/text-input.tsx | 10 +- .../components/piece-form.component/index.tsx | 58 +---- .../piece-form.component/upstream-options.ts | 93 +++++++ .../sidebar-form.component/index.tsx | 2 +- .../workflow-editor-panel.component.tsx | 44 +++- 15 files changed, 534 insertions(+), 238 deletions(-) create mode 100644 frontend/src/pages/private/workflows/workflows-editor/components/piece-form-item.component/array-input.tsx create mode 100644 frontend/src/pages/private/workflows/workflows-editor/components/piece-form.component/upstream-options.ts diff --git a/frontend/src/context/workflows/types/input.ts b/frontend/src/context/workflows/types/input.ts index 532b1de8..d4909d2a 100644 --- a/frontend/src/context/workflows/types/input.ts +++ b/frontend/src/context/workflows/types/input.ts @@ -9,7 +9,7 @@ interface BaseInput { value: Value } -interface ObjectInput { +export interface ObjectInput { fromUpstream: boolean, //? allowed | never | always upstreamArgument: string | null, upstreamId: string | null, @@ -18,7 +18,7 @@ interface ObjectInput { } export type InputArray = BaseInput & { - value: Record[] + value: Record[] | Record[] } export type Input = BaseInput diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/custom-node.component.tsx b/frontend/src/pages/private/workflows/workflows-editor/components/custom-node.component.tsx index 57a605cb..5a2047a7 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/components/custom-node.component.tsx +++ b/frontend/src/pages/private/workflows/workflows-editor/components/custom-node.component.tsx @@ -102,7 +102,7 @@ const CustomNode = memo((data: any) => { extendedData?.style?.label ? extendedData?.style?.label : extendedData?.name }

- {data.id.substring(2, 8)} + {data.id.split("_")[1].substring(0, 6)}

{ diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/piece-form-item.component/array-input.tsx b/frontend/src/pages/private/workflows/workflows-editor/components/piece-form-item.component/array-input.tsx new file mode 100644 index 00000000..b524b3ee --- /dev/null +++ b/frontend/src/pages/private/workflows/workflows-editor/components/piece-form-item.component/array-input.tsx @@ -0,0 +1,230 @@ +import React, { useCallback, useMemo, useState } from 'react'; +import { Control, FieldArrayWithId, useFieldArray, useFormContext } from 'react-hook-form'; + +import { Card, CardContent, IconButton, Box, Grid } from '@mui/material'; +import AddIcon from '@mui/icons-material/Add'; +import DeleteIcon from '@mui/icons-material/Delete'; + +import { IWorkflowPieceData, InputArray } from 'context/workflows/types'; +import { ArrayOption } from '../piece-form.component/upstream-options'; +import TextInput from './text-input'; +import SelectInput from './select-input'; +import NumberInput from './number-input'; +import CheckboxInput from './checkbox-input'; +import DatetimeInput from './datetime-input'; +import CodeEditorInput from './codeeditor-input'; +import SelectUpstreamInput from './select-upstream-input'; + +interface ArrayInputItemProps { + inputKey: string + schema: any; + control: Control + definitions?: any + upstreamOptions: ArrayOption +} + +const ArrayInput: React.FC = ({ inputKey, schema, upstreamOptions, definitions, control }) => { + const name = `inputs.${inputKey}.value` as `inputs.${string}.value` + const { fields: data, append, remove } = useFieldArray({ + name, + control, + }) + const { watch } = useFormContext() + const formsData = watch() + const fields = data as unknown as FieldArrayWithId[] + + const [valuesOptions, setValuesOptions] = useState([]) + + const subItemSchema = useMemo(() => { + let subItemSchema: any = schema?.items; + if (schema?.items?.$ref) { + const subItemSchemaName = schema.items.$ref.split('/').pop(); + subItemSchema = definitions?.[subItemSchemaName]; + } + return subItemSchema + }, [definitions, schema]) + + const [checkedFromUpstreamDefault, checkedFromUpstreamEditable] = useMemo(() => { + // from_upstream condition, if "never" or "always" + let defaultChecked: boolean = true; + let editable: boolean = true; + if (subItemSchema?.from_upstream === "never") { + defaultChecked = false; + editable = false; + } else if (subItemSchema?.from_upstream === "always") { + defaultChecked = true; + editable = false; + } + return [defaultChecked, editable] + }, [subItemSchema]) + + const getFromUpstream = useCallback((index: number) => { + return formsData?.inputs?.[inputKey]?.value?.[index]?.fromUpstream + }, [formsData?.inputs, inputKey]) + + const elementType = useMemo(() => { + if (subItemSchema?.allOf && subItemSchema.allOf.length > 0) { + const typeClass = subItemSchema.allOf[0]['$ref'].split("/").pop(); + const valuesOptions: Array = definitions?.[typeClass].enum; + setValuesOptions(valuesOptions) + return "SelectInput" + } else if ((subItemSchema?.type === 'number') && !subItemSchema?.format) { + return "NumberInput" + } else if (subItemSchema?.type === 'integer' && !subItemSchema?.format) { + return "NumberInputInt" + } else if (subItemSchema?.type === 'boolean' && !subItemSchema?.format) { + return "CheckboxInput"; + } else if (subItemSchema?.type === 'string' && !subItemSchema?.format && !subItemSchema?.widget) { + return "TextInput"; + } else if (subItemSchema?.type === 'string' && subItemSchema?.format === 'date') { + return "DateInput"; + } else if (subItemSchema?.type === 'string' && subItemSchema?.format === 'time') { + return "TimeInput"; + } else if (subItemSchema?.type === 'string' && subItemSchema?.format === 'date-time') { + return "DatetimeInput"; + } else if (subItemSchema?.type === 'string' && subItemSchema?.widget === 'codeeditor') { + return "CodeEditorInput" + } else if (subItemSchema?.type === 'object') { + return "ObjectInput"; + } else { + return "Unknown"; + } + }, [subItemSchema, definitions]) + + const handleAddInput = useCallback(() => { + + append(subItemSchema?.default) + }, [append, subItemSchema?.default]) + + return ( + +
+ + + + {schema?.title} +
+ + {fields && fields.map((fieldWithId, index) => { + const {id} = fieldWithId + const fromUpstream = getFromUpstream(index) + return ( + + { remove(index) }} aria-label="Delete"> + + + {fromUpstream && elementType !== "ObjectInput" && ( + )} + {!fromUpstream && elementType === "SelectInput" && ( + ) + } + {!fromUpstream && elementType === "NumberInput" && ( + ) + } + {!fromUpstream && elementType === "NumberInputInt" && ( + ) + } + {!fromUpstream && elementType === "CheckboxInput" && ( + ) + } + {!fromUpstream && elementType === "TextInput" && ( + ) + } + {!fromUpstream && elementType === "DateInput" && ( + ) + } + {!fromUpstream && elementType === "TimeInput" && ( + ) + } + {!fromUpstream && elementType === "DatetimeInput" && ( + ) + } + {!fromUpstream && elementType === "CodeEditorInput" && ( + ) + } + {!fromUpstream && elementType === "Unknown" && ( +
+ Unknown widget type for {subItemSchema?.title} +
) + } + + + +
+ ); + + })} +
+
+ ); +} + +export default React.memo(ArrayInput); diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/piece-form-item.component/checkbox-input.tsx b/frontend/src/pages/private/workflows/workflows-editor/components/piece-form-item.component/checkbox-input.tsx index 7bc88705..083ab5b5 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/components/piece-form-item.component/checkbox-input.tsx +++ b/frontend/src/pages/private/workflows/workflows-editor/components/piece-form-item.component/checkbox-input.tsx @@ -1,33 +1,35 @@ import { Checkbox, FormControlLabel } from '@mui/material'; import { IWorkflowPieceData } from 'context/workflows/types'; import React from 'react'; -import { Controller, useFormContext } from 'react-hook-form'; +import { useFormContext, Controller } from 'react-hook-form'; interface Props { - label: string - itemKey: string + name: `inputs.${string}.value` | `inputs.${string}.fromUpstream` + label?: string + defaultChecked?: boolean + disabled?: boolean } -const CheckboxInput: React.FC = ({ itemKey, label}) => { +const CheckboxInput: React.FC = ({ label, name, defaultChecked = false, disabled = false }) => { const { control } = useFormContext() return ( - field.onChange(!!e.target.checked)} - /> - )} - /> - } - labelPlacement="start" - label={label} -/>; + control={ + ( + + )} + /> + } + labelPlacement={label ? "start" : undefined} + label={label ? label : undefined} + />; } -export default CheckboxInput; +export default React.memo(CheckboxInput); diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/piece-form-item.component/codeeditor-input.tsx b/frontend/src/pages/private/workflows/workflows-editor/components/piece-form-item.component/codeeditor-input.tsx index d51fe886..0aa1bb5d 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/components/piece-form-item.component/codeeditor-input.tsx +++ b/frontend/src/pages/private/workflows/workflows-editor/components/piece-form-item.component/codeeditor-input.tsx @@ -23,11 +23,11 @@ const CodeEditorItem = React.forwardRef(({ ...register }) => ( /> )) -const CodeEditorInput: React.FC<{ itemKey: string }> = ({ itemKey }) => { +const CodeEditorInput: React.FC<{ name: `inputs.${string}.value` }> = ({ name }) => { const { control } = useFormContext() return ( ( = ({ itemKey }) => { />); } -export default CodeEditorInput; +export default React.memo(CodeEditorInput); diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/piece-form-item.component/datetime-input.tsx b/frontend/src/pages/private/workflows/workflows-editor/components/piece-form-item.component/datetime-input.tsx index ec91199f..31085f0e 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/components/piece-form-item.component/datetime-input.tsx +++ b/frontend/src/pages/private/workflows/workflows-editor/components/piece-form-item.component/datetime-input.tsx @@ -9,39 +9,40 @@ import { IWorkflowPieceData } from 'context/workflows/types'; interface Props { label: string - itemKey: string - defaultValue: string + name: `inputs.${string}.value` type?: "time" | "date" | "date-time" } -const DatetimeInput: React.FC = ({ label, itemKey, defaultValue, type="date" }) => { +const DatetimeInput: React.FC = ({ label, name, type = "date" }) => { const { control } = useFormContext() + const defaultValue = new Date().toISOString() + switch (type) { case "date-time": return ( - - - { onChange(dayjs(e).format('YYYY-MM-DD HH:mm')) }} - {...rest} - /> - - - )} - />; + name={name} + control={control} + defaultValue={dayjs(defaultValue as string, 'YYYY-MM-DD HH:mm')} + render={({ field: { onChange, value, ...rest } }) => ( + + + { onChange(dayjs(e).format('YYYY-MM-DD HH:mm')) }} + {...rest} + /> + + + )} + />; case 'time': return ( @@ -63,7 +64,7 @@ const DatetimeInput: React.FC = ({ label, itemKey, defaultValue, type="da case 'date': default: return ( @@ -85,4 +86,4 @@ const DatetimeInput: React.FC = ({ label, itemKey, defaultValue, type="da } } -export default DatetimeInput; +export default React.memo(DatetimeInput); diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/piece-form-item.component/index.tsx b/frontend/src/pages/private/workflows/workflows-editor/components/piece-form-item.component/index.tsx index 9f8f089e..8aaf473e 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/components/piece-form-item.component/index.tsx +++ b/frontend/src/pages/private/workflows/workflows-editor/components/piece-form-item.component/index.tsx @@ -1,13 +1,11 @@ import React, { useMemo } from 'react'; import { - Checkbox, Box, Grid, } from '@mui/material'; -import { UseFormRegister, Control, Controller, useFormContext } from 'react-hook-form'; +import { UseFormRegister, Control, useFormContext } from 'react-hook-form'; import { Input, IWorkflowPieceData, InputArray } from 'context/workflows/types'; -import { Option } from '../piece-form.component'; import SelectUpstreamInput from './select-upstream-input'; import NumberInput from './number-input'; @@ -17,56 +15,65 @@ import DatetimeInput from './datetime-input'; import CodeEditorInput from './codeeditor-input'; import TextInput from './text-input'; +import ArrayInput from './array-input'; +import { ArrayOption, Option } from '../piece-form.component/upstream-options'; interface PieceFormItemProps { schema: any; itemKey: string; - inputProperties: Input | InputArray; - register: UseFormRegister control: Control definitions?: any - upstreamOptions: Option[] + upstreamOptions: Option[] | ArrayOption } -const PieceFormItem: React.FC = ({ upstreamOptions, itemKey, inputProperties, schema, definitions, register, control }) => { - const [checkedFromUpstreamAllowed, checkedFromUpstreamEditable] = useMemo(() => { +const PieceFormItem: React.FC = ({ upstreamOptions, itemKey, schema, definitions, control }) => { + const [checkedFromUpstreamDefault, checkedFromUpstreamEditable] = useMemo(() => { // from_upstream condition, if "never" or "always" - let allowed: boolean = true; + let defaultChecked: boolean = true; let editable: boolean = true; - let arrayItems: string = "allowed"; if (schema?.from_upstream === "never") { - allowed = false; + defaultChecked = false; editable = false; - if (schema.type === 'array') { - arrayItems = "never"; - } } else if (schema?.from_upstream === "always") { - allowed = true; + defaultChecked = true; editable = false; - if (schema.type === 'array') { - allowed = false; - arrayItems = "always"; - } } - return [allowed, editable, arrayItems] - }, [schema]) + + if (schema?.allOf && schema.allOf.length > 0) { + defaultChecked = true; + editable = false; + } + + if (!(upstreamOptions as Option[])?.length) { + editable = false; + } + + if ((upstreamOptions as ArrayOption)?.array?.length) { + editable = true; + } + + return [defaultChecked, editable] + }, [schema, upstreamOptions]) const { watch } = useFormContext() const data = watch() const checkedFromUpstream = data.inputs[itemKey]?.fromUpstream - if (!inputProperties || !Object.keys(inputProperties).length) { - return null - } - let inputElement: React.ReactNode = null - if (checkedFromUpstream && upstreamOptions.length) { + if (checkedFromUpstream) { + let options: Option[] = [] + if (schema.type === 'array') { + options = (upstreamOptions as ArrayOption).array + } else { + options = upstreamOptions as Option[] + } + inputElement = ( ); } else if (schema?.allOf && schema.allOf.length > 0) { const typeClass = schema.allOf[0]['$ref'].split("/").pop(); @@ -75,13 +82,13 @@ const PieceFormItem: React.FC = ({ upstreamOptions, itemKey, } else if ((schema.type === 'number') && !schema.format) { inputElement = = ({ upstreamOptions, itemKey, } else if (schema.type === 'integer' && !schema.format) { inputElement = } else if (schema.type === 'boolean' && !schema.format) { - inputElement = + inputElement = } else if (schema.type === 'array') { - inputElement = null - // + inputElement = + } else if (schema.type === 'string' && schema.format === 'date') { inputElement = ; } else if (schema.type === 'string' && schema?.format === 'time') { inputElement = ; } else if (schema.type === 'string' && schema?.format === 'date-time') { inputElement = ; - } - else if (schema.type === 'string' && schema?.widget === 'codeeditor') { + } else if (schema.type === 'string' && schema?.widget === 'codeeditor') { inputElement = } else if (schema.type === 'string' && !schema.format) { inputElement = - ; + ; } else { inputElement =
Unknown widget type for {schema.title} @@ -156,25 +163,16 @@ const PieceFormItem: React.FC = ({ upstreamOptions, itemKey, {inputElement} - {checkedFromUpstreamAllowed ? ( - - ( - - )} - /> - - ) : null} + + + + ); }; -export default PieceFormItem; +export default React.memo(PieceFormItem); diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/piece-form-item.component/number-input.tsx b/frontend/src/pages/private/workflows/workflows-editor/components/piece-form-item.component/number-input.tsx index 62b5f45b..5b3e5c7c 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/components/piece-form-item.component/number-input.tsx +++ b/frontend/src/pages/private/workflows/workflows-editor/components/piece-form-item.component/number-input.tsx @@ -5,12 +5,12 @@ import { useFormContext } from 'react-hook-form'; interface Props { label: string - itemKey: string + name: `inputs.${string}.value` defaultValue: number type: "float" | "int" } -const NumberInput: React.FC = ({ itemKey, label, type="int", defaultValue}) => { +const NumberInput: React.FC = ({ name, label, type = "int", defaultValue }) => { const { register } = useFormContext() return ( @@ -21,12 +21,12 @@ const NumberInput: React.FC = ({ itemKey, label, type="int", defaultValue label={label} defaultValue={defaultValue} inputProps={{ - step: type==="int" ? 1 : 0.1, + step: type === "int" ? 1 : 0.1, }} - {...register(`inputs.${itemKey}.value`, { + {...register(name, { valueAsNumber: true })} - />); + />); } -export default NumberInput; +export default React.memo(NumberInput); diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/piece-form-item.component/select-input.tsx b/frontend/src/pages/private/workflows/workflows-editor/components/piece-form-item.component/select-input.tsx index 136ad09d..9d138be1 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/components/piece-form-item.component/select-input.tsx +++ b/frontend/src/pages/private/workflows/workflows-editor/components/piece-form-item.component/select-input.tsx @@ -5,12 +5,12 @@ import { IWorkflowPieceData } from 'context/workflows/types'; interface Props { label: string - itemKey: string + name: `inputs.${string}.value` defaultValue: string options: string[] } -const SelectInput: React.FC = ({ options, label, itemKey, defaultValue }) => { +const SelectInput: React.FC = ({ options, label, name, defaultValue }) => { const { register } = useFormContext() return ( @@ -18,7 +18,7 @@ const SelectInput: React.FC = ({ options, label, itemKey, defaultValue }) {label} - handleSelectChange(event, field.onChange) - } - > - - None + {label} + ( + - )} - /> - + ))} + + )} + /> + ); } -export default SelectUpstreamInput; +export default React.memo(SelectUpstreamInput); diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/piece-form-item.component/text-input.tsx b/frontend/src/pages/private/workflows/workflows-editor/components/piece-form-item.component/text-input.tsx index 55038206..041ee1a1 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/components/piece-form-item.component/text-input.tsx +++ b/frontend/src/pages/private/workflows/workflows-editor/components/piece-form-item.component/text-input.tsx @@ -5,11 +5,11 @@ import { useFormContext } from 'react-hook-form'; interface Props { label: string - itemKey: string + name: `inputs.${string}.value` defaultValue?: string } -const TextInput: React.FC = ({ itemKey, label, defaultValue =""}) => { +const TextInput: React.FC = ({ name, label, defaultValue = "" }) => { const { register } = useFormContext() return ( @@ -18,8 +18,8 @@ const TextInput: React.FC = ({ itemKey, label, defaultValue =""}) => { variant="outlined" label={label} defaultValue={defaultValue} - {...register(`inputs.${itemKey}.value`)} - />); + {...register(name)} + />); } -export default TextInput; +export default React.memo(TextInput); diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/piece-form.component/index.tsx b/frontend/src/pages/private/workflows/workflows-editor/components/piece-form.component/index.tsx index 1cac1588..722d7b1f 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/components/piece-form.component/index.tsx +++ b/frontend/src/pages/private/workflows/workflows-editor/components/piece-form.component/index.tsx @@ -1,23 +1,16 @@ import React, { useCallback, useEffect, useMemo, useState } from 'react'; import PieceFormItem from '../piece-form-item.component'; -import { useFormContext } from 'react-hook-form'; +import { useFormContext, useWatch } from 'react-hook-form'; import { IWorkflowPieceData } from 'context/workflows/types'; import * as yup from "yup" import { useWorkflowsEditor } from 'context/workflows/workflows-editor.context'; +import { UpstreamOptions, getUpstreamOptions } from './upstream-options'; interface PieceFormProps { formId: string; schema: any; } -export type Option = { - id: string, - argument: string, - value: string -} - -type UpstreamOptions = Record - export const inputsSchema = yup.lazy((value) => { if (!Object.keys(value).length) { const validationObject = { @@ -52,21 +45,12 @@ export const inputsSchema = yup.lazy((value) => { const PieceForm: React.FC = ({ formId, schema }) => { const { fetchForageWorkflowEdges, getForageWorkflowPieces } = useWorkflowsEditor() - const { register, control, watch } = useFormContext() - const { inputs } = watch() + const { control } = useFormContext() const [upstreamOptions, setUpstreamOptions] = useState({}) const shouldRender = useMemo(() => { - return schema.properties && Object.keys(inputs).length - }, [schema, inputs]) - - const getInputType = useCallback((schema: Record) => { - let type = schema.format ? schema.format : schema.type - if ('allOf' in schema || "oneOf" in schema || "anyOf" in schema) { - type = 'enum' - } - return type as string - }, []) + return schema?.properties + }, [schema]) const handleUpstreamOptions = useCallback(async () => { if (!shouldRender) { @@ -75,35 +59,11 @@ const PieceForm: React.FC = ({ formId, schema }) => { const workflowPieces = await getForageWorkflowPieces(); const workflowEdges = await fetchForageWorkflowEdges(); - const upstreamIds: string[] = [] - const upstreamOptions = {} as Record - for (const ed of workflowEdges) { - if (ed.target === formId) { - upstreamIds.push(ed.source) - } - } - - Object.keys(schema.properties).forEach(key => { - const currentSchema = schema.properties[key] - upstreamOptions[key] = upstreamIds.flatMap(upstreamId => { - const upSchema = workflowPieces[upstreamId].output_schema.properties - const currentType = getInputType(currentSchema) - const options: Option[] = [] - for (const outputs in upSchema) { - const upType = getInputType(upSchema[outputs]) - if (upType === currentType) { - const value = `${workflowPieces[upstreamId]?.name} - ${upSchema[outputs].title} (${upstreamId.substring(2, 8)})` - const upstreamArgument = outputs - options.push({ id: upstreamId, argument: upstreamArgument, value }) - } - } - return options - }) + const upstreamOptions = getUpstreamOptions(formId, schema, workflowPieces, workflowEdges) + setUpstreamOptions(upstreamOptions) - setUpstreamOptions(upstreamOptions) - }) - }, [fetchForageWorkflowEdges, formId, getForageWorkflowPieces, getInputType, schema.properties, shouldRender]) + }, [fetchForageWorkflowEdges, formId, getForageWorkflowPieces, schema, shouldRender]) useEffect(() => { handleUpstreamOptions() @@ -118,8 +78,6 @@ const PieceForm: React.FC = ({ formId, schema }) => { + +const getInputType = (schema: Record) => { + let type = schema.format ? schema.format : schema.type + if ('allOf' in schema || "oneOf" in schema || "anyOf" in schema) { + type = 'enum' + } + return type as string +} + +const getOptions = (upstreamPieces: Record, type: string): Option[] | ArrayOption => { + const options: Option[] = [] + + Object.keys(upstreamPieces).forEach(upstreamId => { + + const upPieces = upstreamPieces[upstreamId] + + for (const upPiece of upPieces) { + const upSchema = upPiece.output_schema.properties + + for (const property in upSchema) { + + const upType = getInputType(upSchema[property]) + + if (upType === type) { + const value = `${upPiece?.name} (${upPiece.id.split("_")[1].substring(0, 6)}) - ${upSchema[property].title}` + const upstreamArgument = property + options.push({ id: upstreamId, argument: upstreamArgument, value }) + } + } + } + }) + + return options +} + +export const getUpstreamOptions = (formId: string, schema: any, workflowPieces: any, workflowEdges: any): UpstreamOptions => { + const upstreamPieces: Record = {} + const upstreamOptions: UpstreamOptions = {} + + for (const ed of workflowEdges) { + if (ed.target === formId) { + if (Array.isArray(upstreamPieces[formId])) { + upstreamPieces[formId].push({...workflowPieces[ed.source], id: ed.source}) + } else { + upstreamPieces[formId] = [] + upstreamPieces[formId].push({...workflowPieces[ed.source], id: ed.source}) + } + } + } + + Object.keys(schema.properties).forEach(key => { + + let currentSchema = schema.properties[key] + const currentType = getInputType(currentSchema) + + if (currentType === "array") { + + let itemsSchema = currentSchema?.items; + if (currentSchema?.items?.$ref) { + const subItemSchemaName = currentSchema.items.$ref.split('/').pop(); + itemsSchema = schema.definitions?.[subItemSchemaName]; + } + + const itemsType = getInputType(itemsSchema) + + const array = getOptions(upstreamPieces, currentType) + const items = getOptions(upstreamPieces, itemsType) + + upstreamOptions[key] = { array, items } as ArrayOption + + } else { + + const options = getOptions(upstreamPieces, currentType) + + upstreamOptions[key] = options + + } + }) + + return upstreamOptions +} diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component/index.tsx b/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component/index.tsx index 9cf76d66..5f66d1c9 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component/index.tsx +++ b/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component/index.tsx @@ -1,4 +1,4 @@ -import React, { useCallback, useEffect, useState } from 'react' +import React, { useCallback, useEffect } from 'react' import { Drawer, Grid, diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/workflow-editor-panel.component.tsx b/frontend/src/pages/private/workflows/workflows-editor/components/workflow-editor-panel.component.tsx index d1db5b7e..816532ec 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/components/workflow-editor-panel.component.tsx +++ b/frontend/src/pages/private/workflows/workflows-editor/components/workflow-editor-panel.component.tsx @@ -157,25 +157,43 @@ const WorkflowEditorPanelComponent = () => { const upstreamId = null var defaultValues = defaultData[key] - if (Array.isArray(defaultData[key])){ + if (Array.isArray(defaultData[key])) { const auxDefaultValues = [] for (const element of defaultData[key]) { - const newValue: any = {} + let newValue: any = {} if (typeof element === 'object') { + newValue = { + fromUpstream: fromUpstream, + upstreamId: {}, + upstreamArgument: {}, + upstreamValue: {}, + value: {} + } for (const [_key, _value] of Object.entries(element)) { - newValue[_key] = { - fromUpstream: fromUpstream, - upstreamId: upstreamId, - upstreamArgument: null, - value: _value + newValue.upstreamId = { + ...newValue.upstreamId, + [_key]: _value + } + newValue.upstreamArgument = { + ...newValue.upstreamArgument, + [_key]: _value + } + newValue.upstreamValue = { + ...newValue.upstreamValue, + [_key]: _value + } + newValue.value = { + ...newValue.value, + [_key]: _value } } auxDefaultValues.push(newValue) - }else{ - newValue[key] = { + } else { + newValue = { fromUpstream: fromUpstream, upstreamId: upstreamId, upstreamArgument: null, + upstreamValue: "", value: element } auxDefaultValues.push(newValue) @@ -198,16 +216,16 @@ const WorkflowEditorPanelComponent = () => { // TODO: refactor types here const defaultWorkflowPieceData = { - storage: {storageAccessMode: storageAccessModes.ReadWrite}, + storage: { storageAccessMode: storageAccessModes.ReadWrite }, containerResources: containerResourcesDefaultData, inputs: upstreamMapFormInfo } as unknown as IWorkflowPieceData - await setForageWorkflowPiecesData(newNode.id,defaultWorkflowPieceData) + await setForageWorkflowPiecesData(newNode.id, defaultWorkflowPieceData) defaultData['storage'] = { - "storageAccessMode": 'Read/Write', - } + "storageAccessMode": 'Read/Write', + } defaultData['containerResources'] = containerResourcesDefaultData // Set default data for the node form - used in json-forms await setFormsForageData(newNode.id, defaultData) From 48bc58e067db1b4793ca5bafee25f2615b348b61 Mon Sep 17 00:00:00 2001 From: Nathan Vieira Marcelino Date: Fri, 21 Jul 2023 17:14:40 -0300 Subject: [PATCH 122/328] fix: docker compose dev build --- docker-compose-dev.yaml | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/docker-compose-dev.yaml b/docker-compose-dev.yaml index 67704b01..610e7101 100644 --- a/docker-compose-dev.yaml +++ b/docker-compose-dev.yaml @@ -360,18 +360,18 @@ services: # Domino Frontend domino_frontend: - image: ghcr.io/tauffer-consulting/domino-frontend:compose - # build: - # context: ./frontend - # dockerfile: Dockerfile + # image: ghcr.io/tauffer-consulting/domino-frontend:compose + build: + context: ./frontend + dockerfile: Dockerfile container_name: domino-frontend - # command: yarn start:local + command: yarn start:local environment: - REACT_APP_DOMINO_DEPLOY_MODE=local-compose ports: - - "3000:80" - # volumes: - # - ./frontend:/usr/src/app # Enable hot reload for frontend + - "3000:3000" + volumes: + - ./frontend:/usr/src/app # Enable hot reload for frontend depends_on: domino_rest: condition: service_started From dfc14e55743783955ddfa618ec236e3f917bb34c Mon Sep 17 00:00:00 2001 From: Nathan Vieira Marcelino Date: Fri, 21 Jul 2023 17:33:03 -0300 Subject: [PATCH 123/328] feat: add object input --- frontend/src/context/workflows/types/input.ts | 1 - .../piece-form-item.component/array-input.tsx | 15 ++++- .../object-input.tsx | 65 +++++++++++++++++++ .../select-upstream-input.tsx | 5 +- .../piece-form-item.component/text-input.tsx | 2 +- .../piece-form.component/upstream-options.ts | 5 +- .../workflow-editor-panel.component.tsx | 6 +- 7 files changed, 90 insertions(+), 9 deletions(-) create mode 100644 frontend/src/pages/private/workflows/workflows-editor/components/piece-form-item.component/object-input.tsx diff --git a/frontend/src/context/workflows/types/input.ts b/frontend/src/context/workflows/types/input.ts index d4909d2a..389bb260 100644 --- a/frontend/src/context/workflows/types/input.ts +++ b/frontend/src/context/workflows/types/input.ts @@ -22,4 +22,3 @@ export type InputArray = BaseInput & { } export type Input = BaseInput - diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/piece-form-item.component/array-input.tsx b/frontend/src/pages/private/workflows/workflows-editor/components/piece-form-item.component/array-input.tsx index b524b3ee..95b4d023 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/components/piece-form-item.component/array-input.tsx +++ b/frontend/src/pages/private/workflows/workflows-editor/components/piece-form-item.component/array-input.tsx @@ -14,6 +14,7 @@ import CheckboxInput from './checkbox-input'; import DatetimeInput from './datetime-input'; import CodeEditorInput from './codeeditor-input'; import SelectUpstreamInput from './select-upstream-input'; +import ObjectInputComponent from './object-input'; interface ArrayInputItemProps { inputKey: string @@ -106,7 +107,7 @@ const ArrayInput: React.FC = ({ inputKey, schema, upstreamO
{fields && fields.map((fieldWithId, index) => { - const {id} = fieldWithId + const { id } = fieldWithId const fromUpstream = getFromUpstream(index) return ( = ({ inputKey, schema, upstreamO Unknown widget type for {subItemSchema?.title}
) } + + {elementType === "ObjectInput" && ( + ) + } + = ({ schema,name,fromUpstream, upstreamOptions }) => { + /** + * { + * "id":"1ef601c7-9b67-409f-98f3-937de10d83dc"} + * "fromUpstream":false, + * "upstreamId":{ + * "arg_name":"", + * "arg_value":"" + * }, + * "upstreamArgument":{ + * "arg_name":"", + * "arg_value":"" + * }, + * "upstreamValue":"", + * "value": { + * "arg_name":"country", + * "arg_value":"Brazil" + * }, + */ + + const defaultValues = useMemo(()=>{ + const defaultValues = schema.default[0] + + return defaultValues + },[schema]) + + return ( + <> + {!fromUpstream && Object.entries(defaultValues).map(([key,value])=>{ + return ( + + ) + })} + {fromUpstream && Object.entries(defaultValues).map(([key])=>{ + return ( + + ) + })} + + ); +} + +export default ObjectInputComponent; diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/piece-form-item.component/select-upstream-input.tsx b/frontend/src/pages/private/workflows/workflows-editor/components/piece-form-item.component/select-upstream-input.tsx index b904564b..c2170ec1 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/components/piece-form-item.component/select-upstream-input.tsx +++ b/frontend/src/pages/private/workflows/workflows-editor/components/piece-form-item.component/select-upstream-input.tsx @@ -8,9 +8,10 @@ interface Props { label: string name: `inputs.${string}` options: Option[] + object?: boolean } -const SelectUpstreamInput: React.FC = ({ options, label, name }) => { +const SelectUpstreamInput: React.FC = ({ options, label, name, object }) => { const { getValues, setValue, control } = useFormContext() const handleSelectChange = useCallback((event: SelectChangeEvent, onChange: (e: any) => void) => { @@ -31,7 +32,7 @@ const SelectUpstreamInput: React.FC = ({ options, label, name }) => { {label} ( { let newValue: any = {} if (typeof element === 'object') { newValue = { - fromUpstream: fromUpstream, + fromUpstream: {}, upstreamId: {}, upstreamArgument: {}, upstreamValue: {}, value: {} } for (const [_key, _value] of Object.entries(element)) { + newValue.fromUpstream = { + ...newValue.fromUpstream, + [_key]: "" + } newValue.upstreamId = { ...newValue.upstreamId, [_key]: "" From 592e905df93905f60c5757c8365d640f258a4f0c Mon Sep 17 00:00:00 2001 From: Nathan Vieira Marcelino Date: Tue, 25 Jul 2023 08:40:04 -0300 Subject: [PATCH 125/328] refactor: remove upstreamMap and nameKeyUpstreamArgsMap from forage --- .../workflows-editor.context/index.tsx | 45 +++-------- .../provider-context-wrapper.tsx | 23 +++--- .../upstream-map.context.tsx | 81 ------------------- .../workflow-editor-panel.component.tsx | 11 +-- 4 files changed, 22 insertions(+), 138 deletions(-) delete mode 100644 frontend/src/context/workflows/workflows-editor.context/upstream-map.context.tsx diff --git a/frontend/src/context/workflows/workflows-editor.context/index.tsx b/frontend/src/context/workflows/workflows-editor.context/index.tsx index 8cc4b049..5121fa73 100644 --- a/frontend/src/context/workflows/workflows-editor.context/index.tsx +++ b/frontend/src/context/workflows/workflows-editor.context/index.tsx @@ -12,13 +12,12 @@ import { createCustomContext } from 'utils' import { useFormsData, IFormsDataContext } from './forms-data.context'; import { usesPieces, IPiecesContext } from './pieces.context'; -import { useUpstreamMap, IUpstreamMapContext } from './upstream-map.context'; import { useWorkflowsEdges, IWorkflowsEdgesContext } from './workflow-edges.context'; import { useWorkflowsNodes, IWorkflowsNodesContext } from './workflow-nodes.context'; import { useWorkflowPiece, IWorkflowPieceContext } from './workflow-pieces.context'; import { useWorkflowPiecesData, IWorkflowPiecesDataContext } from './workflow-pieces-data.context'; -interface IWorkflowsEditorContext extends IFormsDataContext, IPiecesContext, IUpstreamMapContext, IWorkflowsEdgesContext, IWorkflowsNodesContext, IWorkflowPieceContext, IWorkflowPiecesDataContext { +interface IWorkflowsEditorContext extends IFormsDataContext, IPiecesContext, IWorkflowsEdgesContext, IWorkflowsNodesContext, IWorkflowPieceContext, IWorkflowPiecesDataContext { workflowsEditorBodyFromFlowchart: () => any // TODO add type handleCreateWorkflow: (params: IPostWorkflowParams) => Promise @@ -69,16 +68,6 @@ export const WorkflowsEditorProvider: FC<{ children?: React.ReactNode }> = ({ ch toggleNodeDirection, } = useWorkflowsNodes() - const { - getForageUpstreamMap, - getNameKeyUpstreamArgsMap, - setForageUpstreamMap, - setNameKeyUpstreamArgsMap, - removeForageUpstreamMapById, - clearForageUpstreamMap, - clearNameKeyUpstreamArgsMap, - } = useUpstreamMap() - const { fetchWorkflowPieceById, setForageWorkflowPieces, @@ -113,7 +102,7 @@ export const WorkflowsEditorProvider: FC<{ children?: React.ReactNode }> = ({ ch const data = await fetchFormsForageData() const workflowPiecesData = await fetchForageWorkflowPiecesData() - const upstreamMap = await getForageUpstreamMap() + const nodes = await fetchForageWorkflowNodes() const edges = await fetchForageWorkflowEdges() @@ -179,16 +168,9 @@ export const WorkflowsEditorProvider: FC<{ children?: React.ReactNode }> = ({ ch name: element.data.name } const pieceInputKwargs: any = {} - if (nodeId in upstreamMap) { - for (const key in upstreamMap[nodeId]) { - const value = upstreamMap[nodeId][key] - const fromUpstream = value['fromUpstream'] - pieceInputKwargs[key] = { - fromUpstream: fromUpstream, - upstreamTaskId: fromUpstream ? nodeId2taskName[value['upstreamId']] : null, - upstreamArgument: fromUpstream ? value['upstreamArgument'] : null, - value: value['value'] - } + if (nodeId in workflowPiecesData) { + for (const key in workflowPiecesData[nodeId]) { + pieceInputKwargs[key] = (workflowPiecesData[nodeId]as any)[key] } } //console.log(pieceInputKwargs) @@ -227,16 +209,16 @@ export const WorkflowsEditorProvider: FC<{ children?: React.ReactNode }> = ({ ch dag_dict['ui_schema'] = ui_schema return dag_dict - }, [fetchFormsForageData, getForageUpstreamMap, fetchForageWorkflowNodes, fetchForageWorkflowEdges]) + }, [fetchFormsForageData, fetchForageWorkflowPiecesData, fetchForageWorkflowNodes, fetchForageWorkflowEdges]) const clearForageData = useCallback(async () => { await clearForageFormsData() - await clearForageUpstreamMap() + await clearForageCheckboxStates() - await clearNameKeyUpstreamArgsMap() + await clearForageWorkflowPieces() await clearForageWorkflowPiecesData() - }, [clearForageUpstreamMap, clearForageCheckboxStates, clearNameKeyUpstreamArgsMap, clearForageWorkflowPieces, clearForageFormsData, clearForageWorkflowPiecesData]) + }, [clearForageCheckboxStates, clearForageWorkflowPieces, clearForageFormsData, clearForageWorkflowPiecesData]) const value: IWorkflowsEditorContext = { repositories, @@ -259,9 +241,7 @@ export const WorkflowsEditorProvider: FC<{ children?: React.ReactNode }> = ({ ch fetchForageWorkflowEdges, fetchForageWorkflowNodes, workflowsEditorBodyFromFlowchart, - getForageUpstreamMap, - setForageUpstreamMap, - removeForageUpstreamMapById, + nodeDirection, setForageCheckboxStates, getForageCheckboxStates, @@ -269,8 +249,7 @@ export const WorkflowsEditorProvider: FC<{ children?: React.ReactNode }> = ({ ch getForageWorkflowPieces, removeForageWorkflowPiecesById, fetchWorkflowPieceById, - setNameKeyUpstreamArgsMap, - getNameKeyUpstreamArgsMap, + toggleNodeDirection, fetchFormsForageData, @@ -280,8 +259,6 @@ export const WorkflowsEditorProvider: FC<{ children?: React.ReactNode }> = ({ ch clearForageData, clearForageWorkflowPiecesData, - clearForageUpstreamMap, - clearNameKeyUpstreamArgsMap, clearForageFormsData, clearForageCheckboxStates, clearForageWorkflowPieces diff --git a/frontend/src/context/workflows/workflows-editor.context/provider-context-wrapper.tsx b/frontend/src/context/workflows/workflows-editor.context/provider-context-wrapper.tsx index d6b8dc89..9fe6a46f 100644 --- a/frontend/src/context/workflows/workflows-editor.context/provider-context-wrapper.tsx +++ b/frontend/src/context/workflows/workflows-editor.context/provider-context-wrapper.tsx @@ -1,6 +1,5 @@ import FormsDataProvider from "./forms-data.context"; import PiecesProvider from "./pieces.context"; -import UpstreamMapProvider from "./upstream-map.context"; import WorkflowsEdgesProvider from "./workflow-edges.context"; import WorkflowsNodesProvider from "./workflow-nodes.context"; import WorkflowPiecesProvider from "./workflow-pieces.context"; @@ -10,20 +9,18 @@ const ProviderContextWrapper: React.FC<{ children: React.ReactNode }> = ({ child return ( - - - - - - {children} - - - - - + + + + + {children} + + + + ); } -export default ProviderContextWrapper \ No newline at end of file +export default ProviderContextWrapper diff --git a/frontend/src/context/workflows/workflows-editor.context/upstream-map.context.tsx b/frontend/src/context/workflows/workflows-editor.context/upstream-map.context.tsx deleted file mode 100644 index 3736b91d..00000000 --- a/frontend/src/context/workflows/workflows-editor.context/upstream-map.context.tsx +++ /dev/null @@ -1,81 +0,0 @@ -import React, { useCallback } from "react"; -import localForage from "services/config/local-forage.config"; -import { createCustomContext } from "utils"; - -export interface IUpstreamMapContext { - getForageUpstreamMap: () => Promise // TODO add type - setForageUpstreamMap: (data: any) => Promise // TODO add type - clearForageUpstreamMap: () => Promise - removeForageUpstreamMapById: (id: string) => Promise - - setNameKeyUpstreamArgsMap: (nameKeyUpstreamArgsMap: any) => Promise // TODO add type - getNameKeyUpstreamArgsMap: () => Promise // TODO add type - clearNameKeyUpstreamArgsMap: () => Promise -} - -export const [UpstreamMapContext, useUpstreamMap] = - createCustomContext('upstreamMap Context') - -const UpstreamMapProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => { - - // Mapping state to map upstream dropdown names to upstream real keys - const setNameKeyUpstreamArgsMap = useCallback(async (nameKeyUpstreamArgsMap: any) => { - await localForage.setItem('nameKeyUpstreamArgsMap', nameKeyUpstreamArgsMap) - }, []) - - const getNameKeyUpstreamArgsMap = useCallback(async () => { - const nameKeyUpstreamArgsMap = await localForage.getItem('nameKeyUpstreamArgsMap') - if (!nameKeyUpstreamArgsMap) { - return {} - } - return nameKeyUpstreamArgsMap - }, []) - - const clearNameKeyUpstreamArgsMap = useCallback(async () => { - await localForage.setItem('nameKeyUpstreamArgsMap', {}) - }, []) - - // UpstreamMap forage - const getForageUpstreamMap = useCallback(async () => { - const currentUpstreamMap = await localForage.getItem("upstreamMap") - if (!currentUpstreamMap) { - return {} - } - return currentUpstreamMap - }, []) - - const setForageUpstreamMap = useCallback(async (upstreamMap: any) => { - await localForage.setItem('upstreamMap', upstreamMap) - }, []) - - const clearForageUpstreamMap = useCallback(async () => { - await localForage.setItem('upstreamMap', {}) - }, []) - - const removeForageUpstreamMapById = useCallback(async (id: string) => { - const currentUpstreamMap = await localForage.getItem("upstreamMap") - if (!currentUpstreamMap) { - return - } - delete currentUpstreamMap[id] - await localForage.setItem('upstreamMap', currentUpstreamMap) - }, []) - - const value: IUpstreamMapContext = { - clearForageUpstreamMap, - clearNameKeyUpstreamArgsMap, - getForageUpstreamMap, - getNameKeyUpstreamArgsMap, - removeForageUpstreamMapById, - setForageUpstreamMap, - setNameKeyUpstreamArgsMap, - } - - return ( - - {children} - - ) -} - -export default UpstreamMapProvider \ No newline at end of file diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/workflow-editor-panel.component.tsx b/frontend/src/pages/private/workflows/workflows-editor/components/workflow-editor-panel.component.tsx index 3263d059..1ff45cce 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/components/workflow-editor-panel.component.tsx +++ b/frontend/src/pages/private/workflows/workflows-editor/components/workflow-editor-panel.component.tsx @@ -55,11 +55,8 @@ const WorkflowEditorPanelComponent = () => { fetchForagePieceById, setFormsForageData, removeFormsForageDataById, - removeForageUpstreamMapById, fetchForageWorkflowNodes, fetchForageWorkflowEdges, - getForageUpstreamMap, - setForageUpstreamMap, setForageWorkflowPieces, getForageWorkflowPieces, removeForageWorkflowPiecesById, @@ -71,10 +68,9 @@ const WorkflowEditorPanelComponent = () => { const onNodesDelete = useCallback(async (nodes: any) => { for (const node of nodes) { await removeFormsForageDataById(node.id) - await removeForageUpstreamMapById(node.id) await removeForageWorkflowPiecesById(node.id) } - }, [removeFormsForageDataById, removeForageUpstreamMapById, removeForageWorkflowPiecesById]) + }, [removeFormsForageDataById, removeForageWorkflowPiecesById]) // Node double click open drawer with forms @@ -150,7 +146,6 @@ const WorkflowEditorPanelComponent = () => { await setForageWorkflowPieces(newWorkflowPieces) // Set default data for upstream mapping - used in dags - var upstreamMap = await getForageUpstreamMap() var upstreamMapFormInfo: any = {} for (const key in defaultData) { const fromUpstream = false // TODO - If someday we allow default upstream true we should change this @@ -215,8 +210,6 @@ const WorkflowEditorPanelComponent = () => { ) ? null : defaultValues } } - upstreamMap[newNode.id] = upstreamMapFormInfo - await setForageUpstreamMap(upstreamMap) // TODO: refactor types here const defaultWorkflowPieceData = { @@ -237,8 +230,6 @@ const WorkflowEditorPanelComponent = () => { fetchForagePieceById, nodeDirection, setFormsForageData, - setForageUpstreamMap, - getForageUpstreamMap, reactFlowInstance, setNodes, setForageWorkflowPieces, From 5fea1109985e4151e967b1eb84a4d6fe8b38cda3 Mon Sep 17 00:00:00 2001 From: Vinicius Date: Tue, 18 Jul 2023 16:13:38 -0300 Subject: [PATCH 126/328] wip - refactoring workflow settings forms --- .../src/context/workflows/types/settings.ts | 34 +++ .../workflows-editor.context/index.tsx | 280 ++++++++++-------- .../provider-context-wrapper.tsx | 30 +- .../workflow-settings-data.context.tsx | 51 ++++ .../sidebar-settings-form.component.tsx | 250 +++++++++------- .../components/workflows-editor.component.tsx | 56 ++-- 6 files changed, 428 insertions(+), 273 deletions(-) create mode 100644 frontend/src/context/workflows/types/settings.ts create mode 100644 frontend/src/context/workflows/workflows-editor.context/workflow-settings-data.context.tsx diff --git a/frontend/src/context/workflows/types/settings.ts b/frontend/src/context/workflows/types/settings.ts new file mode 100644 index 00000000..cb1772dd --- /dev/null +++ b/frontend/src/context/workflows/types/settings.ts @@ -0,0 +1,34 @@ +export enum scheduleIntervals { + None = "None", + Once = "Once", + Hourly = "Hourly", + Daily = "Daily", + Weekly = "Weekly", + Monthly = "Monthly", + Yearly = "Yearly", +} + +export enum endDateTypes { + Never = "Never", + UserDefined = "User Defined", +} + +export enum storageSources { + None = "None", + AWSS3 = "AWS S3", +} + +export type storageSourceType = keyof typeof storageSources; +export type endDateTypeType = keyof typeof endDateTypes; +export type scheduleIntervalType = keyof typeof scheduleIntervals; + +export interface IWorkflowSettings { + name: string, + scheduleInterval: scheduleIntervalType, + startDate: string, + endDate?: string, + endDateType?: endDateTypeType | null, + storageSource: storageSourceType, + baseFolder: string, + bucket: string +} diff --git a/frontend/src/context/workflows/workflows-editor.context/index.tsx b/frontend/src/context/workflows/workflows-editor.context/index.tsx index 5121fa73..5bfa9578 100644 --- a/frontend/src/context/workflows/workflows-editor.context/index.tsx +++ b/frontend/src/context/workflows/workflows-editor.context/index.tsx @@ -16,8 +16,9 @@ import { useWorkflowsEdges, IWorkflowsEdgesContext } from './workflow-edges.cont import { useWorkflowsNodes, IWorkflowsNodesContext } from './workflow-nodes.context'; import { useWorkflowPiece, IWorkflowPieceContext } from './workflow-pieces.context'; import { useWorkflowPiecesData, IWorkflowPiecesDataContext } from './workflow-pieces-data.context'; +import { IWorkflowSettingsContext, useWorkflowSettings } from './workflow-settings-data.context'; -interface IWorkflowsEditorContext extends IFormsDataContext, IPiecesContext, IWorkflowsEdgesContext, IWorkflowsNodesContext, IWorkflowPieceContext, IWorkflowPiecesDataContext { +interface IWorkflowsEditorContext extends IFormsDataContext, IPiecesContext, IWorkflowsEdgesContext, IWorkflowSettingsContext, IWorkflowsNodesContext, IWorkflowPieceContext, IWorkflowPiecesDataContext { workflowsEditorBodyFromFlowchart: () => any // TODO add type handleCreateWorkflow: (params: IPostWorkflowParams) => Promise @@ -84,132 +85,172 @@ export const WorkflowsEditorProvider: FC<{ children?: React.ReactNode }> = ({ ch } = useWorkflowPiecesData() + const { + fetchWorkflowSettingsData, + setWorkflowSettingsData, + clearWorkflowSettingsData + } = useWorkflowSettings() + + const handleCreateWorkflow = useCallback(async (payload: IPostWorkflowParams) => { return postWorkflow({ ...payload, workspace_id: workspace?.id ?? '' }) }, [postWorkflow, workspace]) - const workflowsEditorBodyFromFlowchart = useCallback(async () => { - const dag_dict: any = {} - const tasks_dict: any = {} - const nodeId2taskName: any = {} - const taskName2nodeId: any = {} + const workflowsEditorBodyFromFlowchart = useCallback(async () => { - const ui_schema: any = { - "nodes": {}, - "edges": [] + const uiSchema: any = { + nodes: {}, + edges: [] } - const data = await fetchFormsForageData() + const settingsData = await fetchFormsForageData() const workflowPiecesData = await fetchForageWorkflowPiecesData() - const nodes = await fetchForageWorkflowNodes() - const edges = await fetchForageWorkflowEdges() - - const workflowFormData = 'workflowForm' in data ? data['workflowForm'] : null - dag_dict['workflow'] = workflowFormData?.config - const storageWorkflowData = workflowFormData?.storage - - const auxTaskDict: any = {} - for (let index = 0; index < nodes.length; index++) { - let element = nodes[index] - let taskIndex = 0 - let taskName = `task_${element.data.name}_${taskIndex}` - while (taskName in auxTaskDict) { - taskIndex += 1 - taskName = `task_${element.data.name}_${taskIndex}` - } - auxTaskDict[taskName] = true - nodeId2taskName[element.id] = taskName - taskName2nodeId[taskName] = element.id - } - - //var task_index = 1 - for (let index = 0; index < nodes.length; index++) { - const element = nodes[index] - const elementData = data[element.id] - - try { - var taskIndex = 0 - var taskName = `task_${element.data.name}_${taskIndex}` - while (taskName in tasks_dict) { - taskIndex += 1 - taskName = `task_${element.data.name}_${taskIndex}` - } - ui_schema['nodes'][taskName] = element - const taskDict: any = {} - - const { storageSource, baseFolder, ...providerOptions } = storageWorkflowData || {} - const storageDict: any = { - "source": storageSource || null, - "base_folder": baseFolder || null, - "mode": elementData?.storage?.storageAccessMode, - "provider_options": providerOptions || null - } - taskDict['workflow_shared_storage'] = storageDict - - const containerResources = { - requests: { - cpu: elementData?.containerResources?.cpu.min, - memory: elementData?.containerResources?.memory.min - }, - limits: { - cpu: elementData?.containerResources?.cpu.max, - memory: elementData?.containerResources?.memory.max - }, - use_gpu: elementData?.containerResources?.useGpu - } - taskDict['container_resources'] = containerResources - - const nodeId = element.id - taskDict['task_id'] = taskName - taskDict['piece'] = { - id: parseInt(nodeId.split('_')[0]), - name: element.data.name - } - const pieceInputKwargs: any = {} - if (nodeId in workflowPiecesData) { - for (const key in workflowPiecesData[nodeId]) { - pieceInputKwargs[key] = (workflowPiecesData[nodeId]as any)[key] - } - } - //console.log(pieceInputKwargs) - - taskDict['piece_input_kwargs'] = pieceInputKwargs - - tasks_dict[taskName] = taskDict - //task_index += 1 - } catch (err) { - console.log('Error', err) - } - - } - - // Organize dependencies - const dependencies_dict: any = {} - for (let index = 0; index < edges.length; index++) { - const edge: any = edges[index] - const source_task_name = nodeId2taskName[edge.source] - const target_task_name = nodeId2taskName[edge.target] - if (target_task_name in dependencies_dict) { - dependencies_dict[target_task_name].push(source_task_name) - } else { - dependencies_dict[target_task_name] = [source_task_name] - } - } - - // Fill in dependencies for each task - const keys = Object.keys(tasks_dict) - keys.forEach((key, index) => { - tasks_dict[key]['dependencies'] = dependencies_dict[key] ? dependencies_dict[key] : [] - }) - // Finalize dag dictionary - ui_schema['edges'] = edges - dag_dict['tasks'] = tasks_dict - dag_dict['ui_schema'] = ui_schema - - return dag_dict - }, [fetchFormsForageData, fetchForageWorkflowPiecesData, fetchForageWorkflowNodes, fetchForageWorkflowEdges]) + console.log('settingsData', settingsData) + + return {} + }, [fetchForageWorkflowPiecesData, fetchFormsForageData]) + + // const workflowsEditorBodyFromFlowchart = useCallback(async () => { + + // const dag_dict: any = {} + // const tasks_dict: any = {} + // const nodeId2taskName: any = {} + // const taskName2nodeId: any = {} + + // const ui_schema: any = { + // "nodes": {}, + // "edges": [] + // } + + // const data = await fetchFormsForageData() + // const workflowPiecesData = await fetchForageWorkflowPiecesData() + // const upstreamMap = await getForageUpstreamMap() + // const nodes = await fetchForageWorkflowNodes() + // const edges = await fetchForageWorkflowEdges() + + // const nodeId = element.id + // taskDict['task_id'] = taskName + // taskDict['piece'] = { + // id: parseInt(nodeId.split('_')[0]), + // name: element.data.name + // } + // const pieceInputKwargs: any = {} + // if (nodeId in workflowPiecesData) { + // for (const key in workflowPiecesData[nodeId]) { + // pieceInputKwargs[key] = (workflowPiecesData[nodeId]as any)[key] + // } + // } + //console.log(pieceInputKwargs) + + // const auxTaskDict: any = {} + // for (let index = 0; index < nodes.length; index++) { + // let element = nodes[index] + // let taskIndex = 0 + // let taskName = `task_${element.data.name}_${taskIndex}` + // while (taskName in auxTaskDict) { + // taskIndex += 1 + // taskName = `task_${element.data.name}_${taskIndex}` + // } + // auxTaskDict[taskName] = true + // nodeId2taskName[element.id] = taskName + // taskName2nodeId[taskName] = element.id + // } + + // //var task_index = 1 + // for (let index = 0; index < nodes.length; index++) { + // const element = nodes[index] + // const elementData = data[element.id] + + // try { + // var taskIndex = 0 + // var taskName = `task_${element.data.name}_${taskIndex}` + // while (taskName in tasks_dict) { + // taskIndex += 1 + // taskName = `task_${element.data.name}_${taskIndex}` + // } + // ui_schema['nodes'][taskName] = element + // const taskDict: any = {} + + // const { storageSource, baseFolder, ...providerOptions } = storageWorkflowData || {} + // const storageDict: any = { + // "source": storageSource || null, + // "base_folder": baseFolder || null, + // "mode": elementData?.storage?.storageAccessMode, + // "provider_options": providerOptions || null + // } + // taskDict['workflow_shared_storage'] = storageDict + + // const containerResources = { + // requests: { + // cpu: elementData?.containerResources?.cpu.min, + // memory: elementData?.containerResources?.memory.min + // }, + // limits: { + // cpu: elementData?.containerResources?.cpu.max, + // memory: elementData?.containerResources?.memory.max + // }, + // use_gpu: elementData?.containerResources?.useGpu + // } + // taskDict['container_resources'] = containerResources + + // const nodeId = element.id + // taskDict['task_id'] = taskName + // taskDict['piece'] = { + // id: parseInt(nodeId.split('_')[0]), + // name: element.data.name + // } + // const pieceInputKwargs: any = {} + // if (nodeId in upstreamMap) { + // for (const key in upstreamMap[nodeId]) { + // const value = upstreamMap[nodeId][key] + // const fromUpstream = value['fromUpstream'] + // pieceInputKwargs[key] = { + // fromUpstream: fromUpstream, + // upstreamTaskId: fromUpstream ? nodeId2taskName[value['upstreamId']] : null, + // upstreamArgument: fromUpstream ? value['upstreamArgument'] : null, + // value: value['value'] + // } + // } + // } + // //console.log(pieceInputKwargs) + + // taskDict['piece_input_kwargs'] = pieceInputKwargs + + // tasks_dict[taskName] = taskDict + // //task_index += 1 + // } catch (err) { + // console.log('Error', err) + // } + + // } + + // // Organize dependencies + // const dependencies_dict: any = {} + // for (let index = 0; index < edges.length; index++) { + // const edge: any = edges[index] + // const source_task_name = nodeId2taskName[edge.source] + // const target_task_name = nodeId2taskName[edge.target] + // if (target_task_name in dependencies_dict) { + // dependencies_dict[target_task_name].push(source_task_name) + // } else { + // dependencies_dict[target_task_name] = [source_task_name] + // } + // } + + // // Fill in dependencies for each task + // const keys = Object.keys(tasks_dict) + // keys.forEach((key, index) => { + // tasks_dict[key]['dependencies'] = dependencies_dict[key] ? dependencies_dict[key] : [] + // }) + // // Finalize dag dictionary + // ui_schema['edges'] = edges + // dag_dict['tasks'] = tasks_dict + // dag_dict['ui_schema'] = ui_schema + + // return dag_dict + // }, [fetchFormsForageData, getForageUpstreamMap, fetchForageWorkflowNodes, fetchForageWorkflowEdges]) const clearForageData = useCallback(async () => { await clearForageFormsData() @@ -261,7 +302,10 @@ export const WorkflowsEditorProvider: FC<{ children?: React.ReactNode }> = ({ ch clearForageWorkflowPiecesData, clearForageFormsData, clearForageCheckboxStates, - clearForageWorkflowPieces + clearForageWorkflowPieces, + fetchWorkflowSettingsData, + setWorkflowSettingsData, + clearWorkflowSettingsData } return ( diff --git a/frontend/src/context/workflows/workflows-editor.context/provider-context-wrapper.tsx b/frontend/src/context/workflows/workflows-editor.context/provider-context-wrapper.tsx index 9fe6a46f..5617db34 100644 --- a/frontend/src/context/workflows/workflows-editor.context/provider-context-wrapper.tsx +++ b/frontend/src/context/workflows/workflows-editor.context/provider-context-wrapper.tsx @@ -4,22 +4,26 @@ import WorkflowsEdgesProvider from "./workflow-edges.context"; import WorkflowsNodesProvider from "./workflow-nodes.context"; import WorkflowPiecesProvider from "./workflow-pieces.context"; import WorkflowPiecesDataProvider from "./workflow-pieces-data.context"; +import WorkflowSettingsDataProvider from "./workflow-settings-data.context"; const ProviderContextWrapper: React.FC<{ children: React.ReactNode }> = ({ children }) => { return ( - - - - - - - {children} - - - - - - + + + + + + + + + {children} + + + + + + + ); } diff --git a/frontend/src/context/workflows/workflows-editor.context/workflow-settings-data.context.tsx b/frontend/src/context/workflows/workflows-editor.context/workflow-settings-data.context.tsx new file mode 100644 index 00000000..5e44968e --- /dev/null +++ b/frontend/src/context/workflows/workflows-editor.context/workflow-settings-data.context.tsx @@ -0,0 +1,51 @@ +import React, { useCallback } from 'react'; +import localForage from 'services/config/local-forage.config'; +import { createCustomContext } from 'utils'; +import { IWorkflowSettings } from '../types/settings' + +export interface IWorkflowSettingsContext { + fetchWorkflowSettingsData: () => Promise + setWorkflowSettingsData: (data: any) => Promise + clearWorkflowSettingsData: () => Promise +} + +export const [WorkflowSettingsDataContext, useWorkflowSettings] = createCustomContext('WorkflowSettingsContext') + +const WorkflowSettingsDataProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => { + + // Forage forms data + const fetchWorkflowSettingsData = useCallback(async () => { + const data = await localForage.getItem('workflowSettingsData') + if (data === null) { + return {} + } + return data + }, []) + + const setWorkflowSettingsData = useCallback(async (data: any) => { + var currentData = await localForage.getItem('workflowSettingsData') + if (!currentData) { + currentData = {} + } + await localForage.setItem('workflowSettingsData', currentData) + }, []) + + const clearWorkflowSettingsData = useCallback(async () => { + await localForage.setItem('workflowSettingsData', {}) + }, []) + + + const value = { + fetchWorkflowSettingsData, + setWorkflowSettingsData, + clearWorkflowSettingsData + } + + return ( + + {children} + + ); +} + +export default WorkflowSettingsDataProvider; \ No newline at end of file diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-settings-form.component.tsx b/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-settings-form.component.tsx index 1a5a302b..784e6463 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-settings-form.component.tsx +++ b/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-settings-form.component.tsx @@ -5,10 +5,8 @@ import { FormControl, TextField, InputLabel, - FormControlLabel, Select, MenuItem, - Checkbox, } from '@mui/material' import dayjs from 'dayjs'; import { DemoContainer } from '@mui/x-date-pickers/internals/demo'; @@ -19,29 +17,32 @@ import { DateTimePicker } from '@mui/x-date-pickers/DateTimePicker'; //import { JsonForms } from '@jsonforms/react' import { useCallback, useEffect, useState } from 'react' import { useWorkflowsEditor } from 'context/workflows/workflows-editor.context' -import { set } from 'react-hook-form'; +import { IWorkflowSettings } from 'context/workflows/types/settings'; +import { endDateTypeType, scheduleIntervalType, storageSourceType } from 'context/workflows/types/settings'; +import { Controller, useFormContext, useForm } from 'react-hook-form'; + interface ISidebarSettingsFormProps { open: boolean, onClose: (event: any) => void } -const defaultConfigData = { +const defaultSettingsData: IWorkflowSettings = { name: '', - scheduleInterval: 'none', - startDateTime: '', - selectEndDateTime: 'never', - endDateTime: '', -} - -const defaultStorageData = { - storageSource: 'None', + scheduleInterval: "None", + startDate: '', + endDate: '', + endDateType: "Never", + storageSource: "None", baseFolder: '', bucket: '' } -const formId = 'workflowForm' + +// TODO - Refactor this to use react-hook-form +// TODO - must save data in workflowSettings forageKey + const SidebarSettingsForm = (props: ISidebarSettingsFormProps) => { const { open, @@ -53,95 +54,114 @@ const SidebarSettingsForm = (props: ISidebarSettingsFormProps) => { ] : [ "None", "AWS S3" ] - const [configFormData, setConfigFormData] = useState(defaultConfigData); - const [storageFormData, setStorageFormData] = useState(defaultStorageData); + const [configFormData, setConfigFormData] = useState(defaultSettingsData); const [isEndDateTimeDisabled, setIsEndDateTimeDisabled] = useState(true); const { - setFormsForageData, - fetchForageDataById, + fetchWorkflowSettingsData, + setWorkflowSettingsData, + clearWorkflowSettingsData } = useWorkflowsEditor() - const handleOnChangeStorage = useCallback(async (event: any) => { - const { name, value, type, checked } = event.target; - const fieldValue = type === 'checkbox' ? checked : value; + // const methods = useForm({ + // defaultValues, + // resolver, + // mode: "onChange" + // }) + + const {register} = useForm() + + //const data = methods.watch() - const newStorageFormData = { - ...storageFormData, - [name]: fieldValue, - } + //console.log('data', data) + console.log('aq') - const currentData = await fetchForageDataById(formId) - const outputData = { - ...currentData, - storage: newStorageFormData - } - await setFormsForageData(formId, outputData); - setStorageFormData(newStorageFormData); + //const { register, formState, control } = useFormContext(); - }, [fetchForageDataById, setFormsForageData, storageFormData]) + // const handleOnChangeStorage = useCallback(async (event: any) => { + // const { name, value, type, checked } = event.target; + // const fieldValue = type === 'checkbox' ? checked : value; - const handleChangeConfig = useCallback(async (event: any, source: string) => { - let name = event?.target?.name || ""; - let fieldValue = event?.target?.value || ""; - if (source === 'endDateTime' || source === 'startDateTime') { - const newDate = event; - fieldValue = new Date(newDate).toISOString(); - name = source; - } else { - const { name, value, type, checked } = event.target; - fieldValue = type === 'checkbox' ? checked : value; - } + // const newStorageFormData = { + // ...storageFormData, + // [name]: fieldValue, + // } - const newFormData = { - ...configFormData, - [name]: fieldValue, - } + // const currentData = await fetchWorkflowSettingsData() - // changes the disable state of the selectEndDateTime - if (name === 'selectEndDateTime') { - setIsEndDateTimeDisabled(fieldValue === 'never') - newFormData.endDateTime = '' - } + // // //const currentData = await fetchForageDataById(formId) + // // const outputData = { + // // ...currentData, + // // storage: newStorageFormData + // // } + // // await setFormsForageData(formId, outputData); + // // setStorageFormData(newStorageFormData); - const currentData = await fetchForageDataById(formId) - const outputData = { - ...currentData, - config: newFormData - } - await setFormsForageData(formId, outputData) - setConfigFormData(newFormData); + // }, [storageFormData]) - }, [configFormData, fetchForageDataById, setFormsForageData]) + // const handleChangeConfig = useCallback(async (event: any, source: string) => { + // // console.log('aqui', event?.target?.value) + // // console.log('aqui', event?.target?.name) + // // let name = event?.target?.name || ""; + // // let fieldValue = event?.target?.value || ""; + // // if (source === 'endDateTime' || source === 'startDateTime') { + // // const newDate = event; + // // fieldValue = new Date(newDate).toISOString(); + // // name = source; + // // } else { + // // const { name, value, type, checked } = event.target; + // // fieldValue = type === 'checkbox' ? checked : value; + // // } - // On load fetch data from forage and set it to the form data - // If data is not present then set default data to the forage - useEffect(() => { - if (!open) return + // // const newFormData = { + // // ...configFormData, + // // [name]: fieldValue, + // // } - const fetchData = async () => { - var data = await fetchForageDataById(formId) - if (data === undefined || data === null) { - data = {} - } - const newData: any = {} - if ('config' in data) { - newData['config'] = data.config - } else { - newData['config'] = defaultConfigData - } - if ('storage' in data) { - newData['storage'] = data.storage - } else { - newData['storage'] = defaultStorageData - } - await setFormsForageData(formId, newData) - setConfigFormData(newData.config) - setStorageFormData(newData.storage) - } - fetchData() - }, [fetchForageDataById, setFormsForageData, open]) + // // // // changes the disable state of the selectEndDateTime + // // if (name === 'endDateType') { + // // setIsEndDateTimeDisabled(fieldValue === 'never') + // // newFormData.endDateType = null + // // } + // // // const currentData = await fetchForageDataById(formId) + // // // const outputData = { + // // // ...currentData, + // // // config: newFormData + // // // } + // // // await setFormsForageData(formId, outputData) + // // setConfigFormData(newFormData); + // }, [configFormData]) + + // // On load fetch data from forage and set it to the form data + // // If data is not present then set default data to the forage + // useEffect(() => { + // if (!open) return + + // const fetchData = async () => { + // // let data = await fetchWorkflowSettingsData() + // // if (data === undefined || data === null){ + // // data = {} + // // } + // // const newData: any = {} + // // if ('config' in data) { + // // newData['config'] = data.config + // // } else { + // // newData['config'] = defaultSettingsData + // // } + // // if ('storage' in data) { + // // newData['storage'] = data.storage + // // } else { + // // newData['storage'] = defaultStorageData + // // } + // // await setWorkflowSettingsData(newData) + // // setConfigFormData(newData.config) + // // setStorageFormData(newData.storage) + // } + // fetchData() + // }, [open, fetchWorkflowSettingsData, setWorkflowSettingsData]) + + console.log("AQUI") return ( { handleChangeConfig(event, "workflowName")} required fullWidth + {...register("name")} /> Schedule Interval - + field.onChange(event.target.value as scheduleIntervalType) + } + > + None + Once + Hourly + Daily + Weekly + Monthly + Yearly + + )} > - None - Once - Hourly - Daily - Weekly - Monthly - Yearly - + + */} @@ -192,8 +220,7 @@ const SidebarSettingsForm = (props: ISidebarSettingsFormProps) => { handleChangeConfig(event, "startDateTime")} + value={dayjs(configFormData.startDate)} ampm={false} format='DD/MM/YYYY HH:mm' sx={{ width: "100%" }} @@ -206,9 +233,8 @@ const SidebarSettingsForm = (props: ISidebarSettingsFormProps) => { End Date/Time { @@ -258,14 +282,13 @@ const SidebarSettingsForm = (props: ISidebarSettingsFormProps) => { { - storageFormData.storageSource === 'AWS S3' ? ( + configFormData.storageSource === 'AWSS3' ? ( <> @@ -274,8 +297,7 @@ const SidebarSettingsForm = (props: ISidebarSettingsFormProps) => { diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/workflows-editor.component.tsx b/frontend/src/pages/private/workflows/workflows-editor/components/workflows-editor.component.tsx index ea2b806d..16fac452 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/components/workflows-editor.component.tsx +++ b/frontend/src/pages/private/workflows/workflows-editor/components/workflows-editor.component.tsx @@ -92,38 +92,38 @@ export const WorkflowsEditorComponent: React.FC = () => { const handleSaveWorkflow = useCallback(async () => { try { - setBackdropIsOpen(true) + //setBackdropIsOpen(true) const payload = await workflowsEditorBodyFromFlowchart() console.log('payload', payload) - if ((!payload.tasks)) { - setBackdropIsOpen(false) - return toast.error('Please add tasks to the workflow') - } - try { - await validateWorkflowForms(payload) - await validateTasksForms(payload) - } - catch (err: any) { - setBackdropIsOpen(false) - return toast.error(err.message) - } + // if ((!payload.tasks)) { + // setBackdropIsOpen(false) + // return toast.error('Please add tasks to the workflow') + // } + // // try { + // // await validateWorkflowForms(payload) + // // await validateTasksForms(payload) + // // } + // // catch (err: any) { + // // setBackdropIsOpen(false) + // // return toast.error(err.message) + // // } - handleCreateWorkflow(payload) - .then((response) => { - toast.success('Workflow created successfully.') - setBackdropIsOpen(false) - }) - .catch((err) => { - if (err.response?.status === 422) { - setBackdropIsOpen(false) - console.log('response', err.response) - toast.error('Error while creating workflow, check your workflow settings and tasks.') - return - } - setBackdropIsOpen(false) - toast.error(err.response.data.detail) - }) + // handleCreateWorkflow(payload) + // .then((response) => { + // toast.success('Workflow created successfully.') + // setBackdropIsOpen(false) + // }) + // .catch((err) => { + // if (err.response?.status === 422) { + // setBackdropIsOpen(false) + // console.log('response', err.response) + // toast.error('Error while creating workflow, check your workflow settings and tasks.') + // return + // } + // setBackdropIsOpen(false) + // toast.error(err.response.data.detail) + // }) } catch (err) { setBackdropIsOpen(false) console.log(err) From d93c6ce4a7f38c9336bb638c232ef47a3ad7282f Mon Sep 17 00:00:00 2001 From: Vinicius Date: Wed, 19 Jul 2023 07:37:26 -0300 Subject: [PATCH 127/328] rest requirements --- rest/requirements.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/rest/requirements.txt b/rest/requirements.txt index da5c935a..3b0ebce6 100644 --- a/rest/requirements.txt +++ b/rest/requirements.txt @@ -20,4 +20,5 @@ passlib==1.7.4 tomli==2.0.1 tomli_w==1.0.0 cryptography==39.0.1 -aiohttp==3.8.3 \ No newline at end of file +aiohttp==3.8.3 +fastapi==0.88.0 \ No newline at end of file From dbbb8ba4bb63f24de4c8219a60893a006f8cb7d8 Mon Sep 17 00:00:00 2001 From: Vinicius Date: Wed, 19 Jul 2023 10:37:05 -0300 Subject: [PATCH 128/328] settings sidebar with hook form --- .../src/context/workflows/types/settings.ts | 8 +- .../workflows-editor.context/index.tsx | 6 +- .../workflow-settings-data.context.tsx | 6 +- .../sidebar-settings-form.component.tsx | 304 ++++++++---------- .../components/workflows-editor.component.tsx | 1 - 5 files changed, 151 insertions(+), 174 deletions(-) diff --git a/frontend/src/context/workflows/types/settings.ts b/frontend/src/context/workflows/types/settings.ts index cb1772dd..8e9dfc35 100644 --- a/frontend/src/context/workflows/types/settings.ts +++ b/frontend/src/context/workflows/types/settings.ts @@ -1,3 +1,5 @@ +import { Dayjs } from "dayjs"; + export enum scheduleIntervals { None = "None", Once = "Once", @@ -25,9 +27,9 @@ export type scheduleIntervalType = keyof typeof scheduleIntervals; export interface IWorkflowSettings { name: string, scheduleInterval: scheduleIntervalType, - startDate: string, - endDate?: string, - endDateType?: endDateTypeType | null, + startDate: Dayjs | string, + endDate?: Dayjs | string, + endDateType: endDateTypeType, storageSource: storageSourceType, baseFolder: string, bucket: string diff --git a/frontend/src/context/workflows/workflows-editor.context/index.tsx b/frontend/src/context/workflows/workflows-editor.context/index.tsx index 5bfa9578..58f419ae 100644 --- a/frontend/src/context/workflows/workflows-editor.context/index.tsx +++ b/frontend/src/context/workflows/workflows-editor.context/index.tsx @@ -253,13 +253,13 @@ export const WorkflowsEditorProvider: FC<{ children?: React.ReactNode }> = ({ ch // }, [fetchFormsForageData, getForageUpstreamMap, fetchForageWorkflowNodes, fetchForageWorkflowEdges]) const clearForageData = useCallback(async () => { - await clearForageFormsData() - + // TODO remove old clear methods await clearForageCheckboxStates() await clearForageWorkflowPieces() await clearForageWorkflowPiecesData() - }, [clearForageCheckboxStates, clearForageWorkflowPieces, clearForageFormsData, clearForageWorkflowPiecesData]) + clearWorkflowSettingsData() + }, [clearForageCheckboxStates, clearForageWorkflowPieces, clearForageWorkflowPiecesData, clearWorkflowSettingsData]) const value: IWorkflowsEditorContext = { repositories, diff --git a/frontend/src/context/workflows/workflows-editor.context/workflow-settings-data.context.tsx b/frontend/src/context/workflows/workflows-editor.context/workflow-settings-data.context.tsx index 5e44968e..fda8d06b 100644 --- a/frontend/src/context/workflows/workflows-editor.context/workflow-settings-data.context.tsx +++ b/frontend/src/context/workflows/workflows-editor.context/workflow-settings-data.context.tsx @@ -23,11 +23,7 @@ const WorkflowSettingsDataProvider: React.FC<{ children: React.ReactNode }> = ({ }, []) const setWorkflowSettingsData = useCallback(async (data: any) => { - var currentData = await localForage.getItem('workflowSettingsData') - if (!currentData) { - currentData = {} - } - await localForage.setItem('workflowSettingsData', currentData) + await localForage.setItem('workflowSettingsData', data) }, []) const clearWorkflowSettingsData = useCallback(async () => { diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-settings-form.component.tsx b/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-settings-form.component.tsx index 784e6463..98294464 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-settings-form.component.tsx +++ b/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-settings-form.component.tsx @@ -15,12 +15,13 @@ import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import { DateTimePicker } from '@mui/x-date-pickers/DateTimePicker'; //import { materialCells, materialRenderers } from '@jsonforms/material-renderers' //import { JsonForms } from '@jsonforms/react' -import { useCallback, useEffect, useState } from 'react' +import { useCallback, useEffect } from 'react' import { useWorkflowsEditor } from 'context/workflows/workflows-editor.context' -import { IWorkflowSettings } from 'context/workflows/types/settings'; +import { IWorkflowSettings, endDateTypes, scheduleIntervals } from 'context/workflows/types/settings'; import { endDateTypeType, scheduleIntervalType, storageSourceType } from 'context/workflows/types/settings'; -import { Controller, useFormContext, useForm } from 'react-hook-form'; - +import { Controller, useForm } from 'react-hook-form'; +import * as yup from "yup"; +import useYupValidationResolver from 'utils/validationResolver'; interface ISidebarSettingsFormProps { open: boolean, @@ -30,18 +31,44 @@ interface ISidebarSettingsFormProps { const defaultSettingsData: IWorkflowSettings = { name: '', scheduleInterval: "None", - startDate: '', - endDate: '', + startDate: "", + endDate: "", endDateType: "Never", storageSource: "None", baseFolder: '', bucket: '' } +const storageSourceOptions = process.env.REACT_APP_DOMINO_DEPLOY_MODE === "local-compose" ? [ + { + "label": "None", + "value": "None" + }, + { + "label": "Local", + "value": "Local" + } +] : [ + { + "label": "None", + "value": "None" + }, + { + "label": "AWS S3", + "value": "AWSS3" + } +] - -// TODO - Refactor this to use react-hook-form -// TODO - must save data in workflowSettings forageKey +// TODO check yup validation +export const WorkflowSettingsFormSchema = yup.object().shape({ + name: yup.string().required(), + scheduleInterval: yup.mixed().oneOf(Object.values(scheduleIntervals)).required(), + startDate: yup.date().required(), + endDate: yup.date(), + endDateType: yup.mixed().oneOf(Object.values(endDateTypes)).required(), + storageSource: yup.string(), + baseFolder: yup.string(), +}); const SidebarSettingsForm = (props: ISidebarSettingsFormProps) => { const { @@ -49,119 +76,42 @@ const SidebarSettingsForm = (props: ISidebarSettingsFormProps) => { onClose, } = props - const storageSourceOptions = process.env.REACT_APP_DOMINO_DEPLOY_MODE === "local-compose" ? [ - "None", "Local" - ] : [ - "None", "AWS S3" - ] - const [configFormData, setConfigFormData] = useState(defaultSettingsData); - const [isEndDateTimeDisabled, setIsEndDateTimeDisabled] = useState(true); + const { fetchWorkflowSettingsData, setWorkflowSettingsData, - clearWorkflowSettingsData } = useWorkflowsEditor() - // const methods = useForm({ - // defaultValues, - // resolver, - // mode: "onChange" - // }) - - const {register} = useForm() - - //const data = methods.watch() - - //console.log('data', data) - console.log('aq') - - //const { register, formState, control } = useFormContext(); - - // const handleOnChangeStorage = useCallback(async (event: any) => { - // const { name, value, type, checked } = event.target; - // const fieldValue = type === 'checkbox' ? checked : value; - - // const newStorageFormData = { - // ...storageFormData, - // [name]: fieldValue, - // } + const resolver = useYupValidationResolver(WorkflowSettingsFormSchema); + const { register, watch, control, reset } = useForm({ mode: "onChange", resolver }) + const formData = watch() - // const currentData = await fetchWorkflowSettingsData() - // // //const currentData = await fetchForageDataById(formId) - // // const outputData = { - // // ...currentData, - // // storage: newStorageFormData - // // } - // // await setFormsForageData(formId, outputData); - // // setStorageFormData(newStorageFormData); + const loadData = useCallback(async () => { + const data = await fetchWorkflowSettingsData() + if (Object.keys(data).length === 0) { + reset(defaultSettingsData) + }else{ + reset(data) + } + }, [reset, fetchWorkflowSettingsData]) - // }, [storageFormData]) + const saveData = useCallback(async () => { + if (open){ + await setWorkflowSettingsData(formData) + } + }, [formData, open, setWorkflowSettingsData]) - // const handleChangeConfig = useCallback(async (event: any, source: string) => { - // // console.log('aqui', event?.target?.value) - // // console.log('aqui', event?.target?.name) - // // let name = event?.target?.name || ""; - // // let fieldValue = event?.target?.value || ""; - // // if (source === 'endDateTime' || source === 'startDateTime') { - // // const newDate = event; - // // fieldValue = new Date(newDate).toISOString(); - // // name = source; - // // } else { - // // const { name, value, type, checked } = event.target; - // // fieldValue = type === 'checkbox' ? checked : value; - // // } + useEffect(() => { + if (open) { + loadData() + } + }, [open, loadData]) - // // const newFormData = { - // // ...configFormData, - // // [name]: fieldValue, - // // } + useEffect(() => { + saveData() + }, [saveData]) - // // // // changes the disable state of the selectEndDateTime - // // if (name === 'endDateType') { - // // setIsEndDateTimeDisabled(fieldValue === 'never') - // // newFormData.endDateType = null - // // } - - // // // const currentData = await fetchForageDataById(formId) - // // // const outputData = { - // // // ...currentData, - // // // config: newFormData - // // // } - // // // await setFormsForageData(formId, outputData) - // // setConfigFormData(newFormData); - - // }, [configFormData]) - - // // On load fetch data from forage and set it to the form data - // // If data is not present then set default data to the forage - // useEffect(() => { - // if (!open) return - - // const fetchData = async () => { - // // let data = await fetchWorkflowSettingsData() - // // if (data === undefined || data === null){ - // // data = {} - // // } - // // const newData: any = {} - // // if ('config' in data) { - // // newData['config'] = data.config - // // } else { - // // newData['config'] = defaultSettingsData - // // } - // // if ('storage' in data) { - // // newData['storage'] = data.storage - // // } else { - // // newData['storage'] = defaultStorageData - // // } - // // await setWorkflowSettingsData(newData) - // // setConfigFormData(newData.config) - // // setStorageFormData(newData.storage) - // } - // fetchData() - // }, [open, fetchWorkflowSettingsData, setWorkflowSettingsData]) - - console.log("AQUI") return ( { { Schedule Interval - {/* { Yearly )} - > - - */} + /> - - - - - + ( + + + { onChange(dayjs(e).format('YYYY-MM-DD HH:mm')) }} + {...rest} + /> + + + )} + /> End Date/Time - + control={control} + defaultValue={defaultSettingsData.endDateType} + render={({ field }) => ( + + )} + /> - - - - - + ( + + + { onChange(dayjs(e).format('YYYY-MM-DD HH:mm')) }} + sx={{ width: "100%" }} + {...rest} + /> + + + )} + /> @@ -267,43 +240,50 @@ const SidebarSettingsForm = (props: ISidebarSettingsFormProps) => { - Schedule Interval - + control={control} + defaultValue={defaultSettingsData.storageSource} + render={({ field }) => ( + + )} + /> { - configFormData.storageSource === 'AWSS3' ? ( + formData.storageSource === 'AWSS3' ? ( <> - ) : null } diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/workflows-editor.component.tsx b/frontend/src/pages/private/workflows/workflows-editor/components/workflows-editor.component.tsx index 16fac452..384424fa 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/components/workflows-editor.component.tsx +++ b/frontend/src/pages/private/workflows/workflows-editor/components/workflows-editor.component.tsx @@ -249,7 +249,6 @@ export const WorkflowsEditorComponent: React.FC = () => { handleClose={() => setMenuOpen(!menuOpen)} /> - {/* */} Date: Wed, 19 Jul 2023 11:05:21 -0300 Subject: [PATCH 129/328] update form data schema --- .../src/context/workflows/types/settings.ts | 10 ++- .../sidebar-settings-form.component.tsx | 80 +++++++++++-------- 2 files changed, 56 insertions(+), 34 deletions(-) diff --git a/frontend/src/context/workflows/types/settings.ts b/frontend/src/context/workflows/types/settings.ts index 8e9dfc35..39964e2d 100644 --- a/frontend/src/context/workflows/types/settings.ts +++ b/frontend/src/context/workflows/types/settings.ts @@ -24,13 +24,21 @@ export type storageSourceType = keyof typeof storageSources; export type endDateTypeType = keyof typeof endDateTypes; export type scheduleIntervalType = keyof typeof scheduleIntervals; -export interface IWorkflowSettings { + +export interface IWorkflowSettingsConfig { name: string, scheduleInterval: scheduleIntervalType, startDate: Dayjs | string, endDate?: Dayjs | string, endDateType: endDateTypeType, +} + +export interface IWorkflowSettingsStorage { storageSource: storageSourceType, baseFolder: string, bucket: string } +export interface IWorkflowSettings { + config: IWorkflowSettingsConfig + storage: IWorkflowSettingsStorage +} diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-settings-form.component.tsx b/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-settings-form.component.tsx index 98294464..02de282c 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-settings-form.component.tsx +++ b/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-settings-form.component.tsx @@ -17,7 +17,7 @@ import { DateTimePicker } from '@mui/x-date-pickers/DateTimePicker'; //import { JsonForms } from '@jsonforms/react' import { useCallback, useEffect } from 'react' import { useWorkflowsEditor } from 'context/workflows/workflows-editor.context' -import { IWorkflowSettings, endDateTypes, scheduleIntervals } from 'context/workflows/types/settings'; +import { IWorkflowSettings, endDateTypes, scheduleIntervals, storageSources } from 'context/workflows/types/settings'; import { endDateTypeType, scheduleIntervalType, storageSourceType } from 'context/workflows/types/settings'; import { Controller, useForm } from 'react-hook-form'; import * as yup from "yup"; @@ -29,14 +29,18 @@ interface ISidebarSettingsFormProps { } const defaultSettingsData: IWorkflowSettings = { - name: '', - scheduleInterval: "None", - startDate: "", - endDate: "", - endDateType: "Never", - storageSource: "None", - baseFolder: '', - bucket: '' + config: { + name: '', + scheduleInterval: "None", + startDate: "", + endDate: "", + endDateType: "Never", + }, + storage: { + storageSource: "None", + baseFolder: '', + bucket: '' + } } const storageSourceOptions = process.env.REACT_APP_DOMINO_DEPLOY_MODE === "local-compose" ? [ @@ -61,13 +65,18 @@ const storageSourceOptions = process.env.REACT_APP_DOMINO_DEPLOY_MODE === "local // TODO check yup validation export const WorkflowSettingsFormSchema = yup.object().shape({ - name: yup.string().required(), - scheduleInterval: yup.mixed().oneOf(Object.values(scheduleIntervals)).required(), - startDate: yup.date().required(), - endDate: yup.date(), - endDateType: yup.mixed().oneOf(Object.values(endDateTypes)).required(), - storageSource: yup.string(), - baseFolder: yup.string(), + config: yup.object().shape({ + name: yup.string().required(), + scheduleInterval: yup.mixed().oneOf(Object.values(scheduleIntervals)).required(), + startDate: yup.date().required(), + endDate: yup.date(), + endDateType: yup.mixed().oneOf(Object.values(endDateTypes)).required(), + }), + storage: yup.object().shape({ + storageSource: yup.mixed().oneOf(Object.values(storageSources)).required(), + baseFolder: yup.string(), + bucket: yup.string(), + }) }); const SidebarSettingsForm = (props: ISidebarSettingsFormProps) => { @@ -98,6 +107,7 @@ const SidebarSettingsForm = (props: ISidebarSettingsFormProps) => { const saveData = useCallback(async () => { if (open){ + console.log(formData) await setWorkflowSettingsData(formData) } }, [formData, open, setWorkflowSettingsData]) @@ -113,6 +123,10 @@ const SidebarSettingsForm = (props: ISidebarSettingsFormProps) => { }, [saveData]) + if (Object.keys(formData).length === 0) { + return null + } + return ( { Schedule Interval ( { ( @@ -242,9 +256,9 @@ const SidebarSettingsForm = (props: ISidebarSettingsFormProps) => { Storage Source ( + + {error?.message} + ); } diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/piece-form-item.component/select-upstream-input.tsx b/frontend/src/pages/private/workflows/workflows-editor/components/piece-form-item.component/select-upstream-input.tsx index 3567a9ad..360fda10 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/components/piece-form-item.component/select-upstream-input.tsx +++ b/frontend/src/pages/private/workflows/workflows-editor/components/piece-form-item.component/select-upstream-input.tsx @@ -1,8 +1,9 @@ -import { FormControl, InputLabel, MenuItem, Select, SelectChangeEvent } from '@mui/material'; +import { FormControl, FormHelperText, InputLabel, MenuItem, Select, SelectChangeEvent } from '@mui/material'; import React, { useCallback } from 'react'; import { Controller, useFormContext } from 'react-hook-form'; import { Option } from '../piece-form.component/upstream-options'; import { IWorkflowPieceData } from 'context/workflows/types'; +import fetchFromObject from 'utils/fetch-from-object'; type ObjectName = `inputs.${string}.value.${number}.upstreamValue.${string}` type Name = `inputs.${string}` @@ -19,7 +20,7 @@ type Props = { } const SelectUpstreamInput: React.FC = ({ options, label, name, object }) => { - const { setValue, control } = useFormContext() + const { setValue, control, formState: { errors } } = useFormContext() const handleSelectChange = useCallback((event: SelectChangeEvent, onChange: (e: any) => void) => { const value = event.target.value @@ -41,6 +42,7 @@ const SelectUpstreamInput: React.FC = ({ options, label, name, object }) onChange(event) }, [name, object, options, setValue]); + const error = fetchFromObject(errors, name) return ( @@ -70,6 +72,9 @@ const SelectUpstreamInput: React.FC = ({ options, label, name, object }) )} /> + + {error?.message} + ); } diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/piece-form-item.component/text-input.tsx b/frontend/src/pages/private/workflows/workflows-editor/components/piece-form-item.component/text-input.tsx index 0e4309c9..5534ea91 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/components/piece-form-item.component/text-input.tsx +++ b/frontend/src/pages/private/workflows/workflows-editor/components/piece-form-item.component/text-input.tsx @@ -2,6 +2,7 @@ import { TextField } from '@mui/material'; import { IWorkflowPieceData } from 'context/workflows/types'; import React from 'react'; import { useFormContext } from 'react-hook-form'; +import fetchFromObject from 'utils/fetch-from-object'; interface Props { label: string @@ -10,7 +11,9 @@ interface Props { } const TextInput: React.FC = ({ name, label, defaultValue = "" }) => { - const { register } = useFormContext() + const { register, formState:{errors} } = useFormContext() + + const error = fetchFromObject(errors,name) return ( = ({ name, label, defaultValue = "" }) => { variant="outlined" label={label} defaultValue={defaultValue} + error={!!error?.message} + helperText={error?.message} {...register(name)} />); } diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/piece-form.component/upstream-options.ts b/frontend/src/pages/private/workflows/workflows-editor/components/piece-form.component/upstream-options.ts index eff9de4c..135c4b1a 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/components/piece-form.component/upstream-options.ts +++ b/frontend/src/pages/private/workflows/workflows-editor/components/piece-form.component/upstream-options.ts @@ -75,9 +75,6 @@ export const getUpstreamOptions = (formId: string, schema: any, workflowPieces: const itemsType = getInputType(itemsSchema) - - console.log("itemsType",itemsType) - const array = getOptions(upstreamPieces, currentType) const items = getOptions(upstreamPieces, itemsType) diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/workflow-editor-panel.component.tsx b/frontend/src/pages/private/workflows/workflows-editor/components/workflow-editor-panel.component.tsx index 323cdbea..1b358579 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/components/workflow-editor-panel.component.tsx +++ b/frontend/src/pages/private/workflows/workflows-editor/components/workflow-editor-panel.component.tsx @@ -199,8 +199,8 @@ const WorkflowEditorPanelComponent = () => { } upstreamMapFormInfo[key] = { fromUpstream, - upstreamId, - upstreamArgument: null, + upstreamId: upstreamId ?? "", + upstreamArgument: "", upstreamValue: "", value: ( defaultValues === null || defaultValues === undefined diff --git a/frontend/src/utils/fetch-from-object.ts b/frontend/src/utils/fetch-from-object.ts new file mode 100644 index 00000000..216a48e7 --- /dev/null +++ b/frontend/src/utils/fetch-from-object.ts @@ -0,0 +1,17 @@ +function fetchFromObject(obj: any, prop: string): any { + + if (typeof obj === 'undefined') { + return; + } + + var _index = prop.indexOf('.') + if (_index > -1) { + const newObj = obj[prop.substring(0, _index)] + + return fetchFromObject(newObj, prop.substr(_index + 1)); + } + + return obj[prop]; +} + +export default fetchFromObject diff --git a/frontend/src/utils/validationResolver.ts b/frontend/src/utils/validationResolver.ts index 334e7479..ecf9ac4b 100644 --- a/frontend/src/utils/validationResolver.ts +++ b/frontend/src/utils/validationResolver.ts @@ -2,7 +2,7 @@ import { useCallback } from 'react'; import { ObjectSchema, ValidationError } from 'yup'; const useYupValidationResolver = ( - validationSchema: ObjectSchema> + validationSchema: ObjectSchema> ) => useCallback( async (data: any) => { @@ -16,20 +16,26 @@ const useYupValidationResolver = ( errors: {}, }; } catch (errors) { - if (errors instanceof ValidationError) + if (errors instanceof ValidationError) { return { values: {}, errors: errors.inner.reduce( - (allErrors, currentError) => ({ - ...allErrors, - [currentError.path!]: { - type: currentError.type ?? 'validation', - message: currentError.message, - }, - }), + (allErrors, currentError) => { + const path = (currentError.path as string) + ?.replaceAll("[", ".") + .replaceAll("]", "") + return { + ...allErrors, + [path]: { + type: currentError.type ?? 'validation', + message: currentError.message, + }, + } + }, {} ), }; + } throw new Error('Error trying to validate form schema'); } @@ -37,4 +43,4 @@ const useYupValidationResolver = ( [validationSchema] ); -export default useYupValidationResolver; \ No newline at end of file +export default useYupValidationResolver; From 86f6ed3ac253840aab73b4b4809b5ea1fc7ea744 Mon Sep 17 00:00:00 2001 From: Nathan Vieira Marcelino Date: Wed, 26 Jul 2023 14:28:17 -0300 Subject: [PATCH 133/328] feat: improve yup validation on inputs --- .../components/piece-form.component/index.tsx | 36 +------- .../piece-form.component/validation.ts | 83 +++++++++++++++++++ .../sidebar-form.component/index.tsx | 3 +- 3 files changed, 87 insertions(+), 35 deletions(-) create mode 100644 frontend/src/pages/private/workflows/workflows-editor/components/piece-form.component/validation.ts diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/piece-form.component/index.tsx b/frontend/src/pages/private/workflows/workflows-editor/components/piece-form.component/index.tsx index 722d7b1f..16d438ec 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/components/piece-form.component/index.tsx +++ b/frontend/src/pages/private/workflows/workflows-editor/components/piece-form.component/index.tsx @@ -1,8 +1,8 @@ import React, { useCallback, useEffect, useMemo, useState } from 'react'; import PieceFormItem from '../piece-form-item.component'; -import { useFormContext, useWatch } from 'react-hook-form'; +import { useFormContext } from 'react-hook-form'; import { IWorkflowPieceData } from 'context/workflows/types'; -import * as yup from "yup" + import { useWorkflowsEditor } from 'context/workflows/workflows-editor.context'; import { UpstreamOptions, getUpstreamOptions } from './upstream-options'; @@ -11,38 +11,6 @@ interface PieceFormProps { schema: any; } -export const inputsSchema = yup.lazy((value) => { - if (!Object.keys(value).length) { - const validationObject = { - fromUpstream: yup.boolean().required(), //? allowed | never | always - upstreamArgument: yup.string().nullable().required(), - upstreamId: yup.string().nullable().required(), - value: yup.lazy(value => { - switch (typeof value) { - case 'object': - return yup.object().required(); - case 'string': - return yup.string().required(); - case 'number': - return yup.number().required(); - default: - return yup.mixed(); // decide what is the default - } - }) - } - const newEntries = Object.keys(value).reduce( - (acc, val) => ({ - ...acc, - [val]: yup.object(validationObject), - }), - {} - ) - - return yup.object().shape(newEntries) - } - return yup.mixed().notRequired() -}) - const PieceForm: React.FC = ({ formId, schema }) => { const { fetchForageWorkflowEdges, getForageWorkflowPieces } = useWorkflowsEditor() const { control } = useFormContext() diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/piece-form.component/validation.ts b/frontend/src/pages/private/workflows/workflows-editor/components/piece-form.component/validation.ts new file mode 100644 index 00000000..4736cf40 --- /dev/null +++ b/frontend/src/pages/private/workflows/workflows-editor/components/piece-form.component/validation.ts @@ -0,0 +1,83 @@ +import * as yup from "yup" + +export const inputsSchema = yup.lazy((value) => { + + if (Object.keys(value).length) { + const valueValidation = yup.lazy(value => { + switch (typeof value) { + case 'string': + return yup.string().required(); + case 'number': + return yup.number().required(); + default: + return yup.mixed(); // decide what is the default + } + }) + + const defaultValidation = { + fromUpstream: yup.boolean(), //? allowed | never | always + upstreamArgument: yup.string().nullable(), + upstreamId: yup.string().nullable(), + value: valueValidation + } + + const validationObject = { + fromUpstream: yup.lazy(obj=>{ + return yup.object().shape(Object.keys(obj).reduce((acc,val)=>({ + ...acc, + [val]: yup.boolean().required() + }),{})) + }), + upstreamArgument: yup.lazy(obj=>{ + return yup.object().shape(Object.keys(obj).reduce((acc,val)=>({ + ...acc, + [val]: yup.string().nullable() + }),{})) + }), + upstreamId: yup.lazy(obj=>{ + return yup.object().shape(Object.keys(obj).reduce((acc,val)=>({ + ...acc, + [val]: yup.string().nullable() + }),{})) + }), + value: yup.lazy(obj=>{ + return yup.object().shape(Object.keys(obj).reduce((acc,val)=>({ + ...acc, + [val]: valueValidation + }),{})) + }) + } + + const validationArray = { + fromUpstream: yup.boolean(), //? allowed | never | always + upstreamArgument: yup.string().nullable(), + upstreamId: yup.string().nullable(), + value: yup.array().of(yup.lazy(item=>{ + if(typeof item.value==="object"){ + return yup.object(validationObject) + } + return yup.object(defaultValidation) + })) + } + + const newEntries = Object.keys(value).reduce( + (acc, val) => { + if (Array.isArray(value[val].value)) { + return { + ...acc, + [val]: yup.object(validationArray) + } + } else { + return { + ...acc, + [val]: yup.object(defaultValidation), + } + } + }, + {} + ) + + return yup.object().shape(newEntries) + } + return yup.mixed().notRequired() +}) diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component/index.tsx b/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component/index.tsx index 5f66d1c9..f012efb9 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component/index.tsx +++ b/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component/index.tsx @@ -15,7 +15,8 @@ import * as yup from "yup" import { useWorkflowsEditor } from 'context/workflows/workflows-editor.context' -import PieceForm, { inputsSchema } from '../piece-form.component' +import PieceForm from '../piece-form.component' +import {inputsSchema} from '../piece-form.component/validation' import ContainerResourceForm, { ContainerResourceFormSchema, defaultContainerResources } from './container-resource-form.component'; From 9e868ef58db7999b29124e54ea45af51cb7c22cc Mon Sep 17 00:00:00 2001 From: Nathan Vieira Marcelino Date: Thu, 27 Jul 2023 10:19:14 -0300 Subject: [PATCH 134/328] feat: use schema to create validation --- .../piece-form.component/validation.ts | 262 +++++++++++++----- .../sidebar-form.component/index.tsx | 20 +- 2 files changed, 206 insertions(+), 76 deletions(-) diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/piece-form.component/validation.ts b/frontend/src/pages/private/workflows/workflows-editor/components/piece-form.component/validation.ts index 4736cf40..c3bccfc0 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/components/piece-form.component/validation.ts +++ b/frontend/src/pages/private/workflows/workflows-editor/components/piece-form.component/validation.ts @@ -1,83 +1,207 @@ import * as yup from "yup" -export const inputsSchema = yup.lazy((value) => { +const defaultValidation = { + fromUpstream: yup.boolean(), //? allowed | never | always + upstreamArgument: yup.string().when("fromUpstream", ([fromUpstream]) => { + if (fromUpstream) { + return yup.string().required() + } + return yup.string() + }), + upstreamId: yup.string().when("fromUpstream", ([fromUpstream]) => { + if (fromUpstream) { + return yup.string().required() + } + return yup.string() + }), + upstreamValue: yup.string().when("fromUpstream", ([fromUpstream]) => { + if (fromUpstream) { + return yup.string().required() + } + return yup.string() + }), +} - if (Object.keys(value).length) { - const valueValidation = yup.lazy(value => { - switch (typeof value) { - case 'string': - return yup.string().required(); - case 'number': - return yup.number().required(); - default: - return yup.mixed(); // decide what is the default - } - }) +const validationObject = { + fromUpstream: yup.lazy(obj => { + return yup.object().shape(Object.keys(obj).reduce((acc, val) => ({ + ...acc, + [val]: yup.boolean().required() + }), {})) + }), + upstreamArgument: yup.lazy(obj => { + return yup.object().shape(Object.keys(obj).reduce((acc, val) => ({ + ...acc, + [val]: yup.string().when("fromUpstream", ([fromUpstream]) => { + if (!fromUpstream) { + return yup.mixed().notRequired() + } + return yup.string().required() + }) + }), {})) + }), + upstreamId: yup.lazy(obj => { + return yup.object().shape(Object.keys(obj).reduce((acc, val) => ({ + ...acc, + [val]: yup.string().when("fromUpstream", ([fromUpstream]) => { + if (!fromUpstream) { + return yup.mixed().notRequired() + } + return yup.string().required() + }) + }), {})) + }), + value: yup.lazy(obj => { + return yup.object().shape(Object.keys(obj).reduce((acc, val) => { + console.log(obj) - const defaultValidation = { - fromUpstream: yup.boolean(), //? allowed | never | always - upstreamArgument: yup.string().nullable(), - upstreamId: yup.string().nullable(), - value: valueValidation - } + return ({ + ...acc, + [val]: yup.string().when("fromUpstream", ([fromUpstream]) => { + if (fromUpstream) { + return yup.mixed().notRequired() + } + return yup.string().required() + }) + }) + }, {})) + }), +} - const validationObject = { - fromUpstream: yup.lazy(obj=>{ - return yup.object().shape(Object.keys(obj).reduce((acc,val)=>({ - ...acc, - [val]: yup.boolean().required() - }),{})) - }), - upstreamArgument: yup.lazy(obj=>{ - return yup.object().shape(Object.keys(obj).reduce((acc,val)=>({ - ...acc, - [val]: yup.string().nullable() - }),{})) - }), - upstreamId: yup.lazy(obj=>{ - return yup.object().shape(Object.keys(obj).reduce((acc,val)=>({ - ...acc, - [val]: yup.string().nullable() - }),{})) - }), - value: yup.lazy(obj=>{ - return yup.object().shape(Object.keys(obj).reduce((acc,val)=>({ - ...acc, - [val]: valueValidation - }),{})) +function getValidationValueBySchemaType(schema: any) { + let inputSchema = {} + + if ((schema.type === 'number') && !schema.format) { + inputSchema = { + ...defaultValidation, + value: yup.number().when("fromUpstream", ([fromUpstream]) => { + if (fromUpstream) { + return yup.mixed().notRequired() + } + return yup.number().required() }) } - - const validationArray = { - fromUpstream: yup.boolean(), //? allowed | never | always - upstreamArgument: yup.string().nullable(), - upstreamId: yup.string().nullable(), - value: yup.array().of(yup.lazy(item=>{ - if(typeof item.value==="object"){ - return yup.object(validationObject) + } + else if (schema.type === 'integer' && !schema.format) { + inputSchema = { + ...defaultValidation, + value: yup.number().when("fromUpstream", ([fromUpstream]) => { + if (fromUpstream) { + return yup.mixed().notRequired() } - return yup.object(defaultValidation) - })) + return yup.number().integer().required() + }) } + } + else if (schema.type === 'boolean' && !schema.format) { + inputSchema = { + ...defaultValidation, + value: yup.boolean().when("fromUpstream", ([fromUpstream]) => { + if (fromUpstream) { + return yup.mixed().notRequired() + } + return yup.boolean().required() + }) + } + } + else if (schema.type === 'string' && schema.format === 'date') { + inputSchema = { + ...defaultValidation, + value: yup.string().when("fromUpstream", ([fromUpstream]) => { + if (fromUpstream) { + return yup.mixed().notRequired() + } + return yup.string().required() + }) + } + } + else if (schema.type === 'string' && schema?.format === 'time') { + inputSchema = { + ...defaultValidation, + value: yup.string().when("fromUpstream", ([fromUpstream]) => { + if (fromUpstream) { + return yup.mixed().notRequired() + } + return yup.string().required() + }) + } + } + else if (schema.type === 'string' && schema?.format === 'date-time') { + inputSchema = { + ...defaultValidation, + value: yup.string().when("fromUpstream", ([fromUpstream]) => { + if (fromUpstream) { + return yup.mixed().notRequired() + } + return yup.string().required() + }) + } + } + else if (schema.type === 'string' && schema?.widget === 'codeeditor') { + inputSchema = { + ...defaultValidation, + value: yup.string().when("fromUpstream", ([fromUpstream]) => { + if (fromUpstream) { + return yup.mixed().notRequired() + } + return yup.string() + }) + } + } + else if (schema.type === 'string' && !schema.format) { + inputSchema = { + ...defaultValidation, + value: yup.string().when("fromUpstream", ([fromUpstream]) => { + if (fromUpstream) { + return yup.mixed().notRequired() + } + return yup.string().required() + }) + } + } + else if (schema.type === 'object') { + inputSchema = validationObject + } + else { + inputSchema = {} + } + + return inputSchema +} + +export function createInputsSchemaValidation(schema: any) { + if (!schema?.properties) { + return yup.mixed().notRequired() + } - const newEntries = Object.keys(value).reduce( - (acc, val) => { - if (Array.isArray(value[val].value)) { - return { - ...acc, - [val]: yup.object(validationArray) + const validationSchema = yup.lazy(() => { + const validationSchema = + Object.entries(schema.properties).reduce((acc, cur: [string, any]) => { + const [key, subSchema] = cur + let inputSchema: any = {} + + if (subSchema.type === 'array') { + let subItemSchema: any = subSchema?.items; + if (subSchema?.items?.$ref) { + const subItemSchemaName = subSchema.items.$ref.split('/').pop(); + subItemSchema = schema.definitions?.[subItemSchemaName]; } - } else { - return { - ...acc, - [val]: yup.object(defaultValidation), + inputSchema = {} + inputSchema = { + ...defaultValidation, + value: yup.array().of( + yup.object(getValidationValueBySchemaType(subItemSchema)) + ) } + } else { + inputSchema = getValidationValueBySchemaType(subSchema) } - }, - {} - ) - return yup.object().shape(newEntries) - } - return yup.mixed().notRequired() -}) + return { ...acc, [key]: yup.object(inputSchema) } + }, {}) + + return yup.object().shape(validationSchema) + }) + + return validationSchema +} diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component/index.tsx b/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component/index.tsx index f012efb9..aa0c8633 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component/index.tsx +++ b/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component/index.tsx @@ -1,4 +1,4 @@ -import React, { useCallback, useEffect } from 'react' +import React, { useCallback, useEffect, useMemo } from 'react' import { Drawer, Grid, @@ -16,7 +16,7 @@ import { useWorkflowsEditor } from 'context/workflows/workflows-editor.context' import PieceForm from '../piece-form.component' -import {inputsSchema} from '../piece-form.component/validation' +import { createInputsSchemaValidation } from '../piece-form.component/validation' import ContainerResourceForm, { ContainerResourceFormSchema, defaultContainerResources } from './container-resource-form.component'; @@ -39,11 +39,7 @@ const defaultValues: IWorkflowPieceData = { inputs: {}, } -const SidebarPieceFormSchema = yup.object().shape({ - storage: storageFormSchema, - containerResources: ContainerResourceFormSchema, - inputs: inputsSchema, -}); + const SidebarPieceForm: React.FC = (props) => { const { @@ -59,6 +55,14 @@ const SidebarPieceForm: React.FC = (props) => { fetchForageWorkflowPiecesDataById, } = useWorkflowsEditor() + const SidebarPieceFormSchema = useMemo(() => { + return yup.object().shape({ + storage: storageFormSchema, + containerResources: ContainerResourceFormSchema, + inputs: createInputsSchemaValidation(schema), + }); + }, [schema]) + const resolver = useYupValidationResolver(SidebarPieceFormSchema); const methods = useForm({ defaultValues, @@ -67,6 +71,8 @@ const SidebarPieceForm: React.FC = (props) => { }) const data = methods.watch() + // console.log("ERRORS: ", methods.formState.errors) + const loadData = useCallback(async () => { const data = await fetchForageWorkflowPiecesDataById(formId) methods.reset(data) // put forage data on form if exist From 9f726bdfff367d37c4587dad7df4bda5a75caae4 Mon Sep 17 00:00:00 2001 From: Nathan Vieira Marcelino Date: Fri, 28 Jul 2023 15:07:51 -0300 Subject: [PATCH 135/328] feat: move to components inputs --- .../checkbox-input.tsx | 13 ++--- .../codeeditor-input.tsx | 13 +++-- .../datetime-input.tsx | 25 ++++---- .../number-input.tsx | 13 ++--- frontend/src/components/select-input.tsx | 58 +++++++++++++++++++ .../text-input.tsx | 15 +++-- .../piece-form-item.component/array-input.tsx | 16 ++--- .../piece-form-item.component/index.tsx | 39 +++++++------ .../object-input.tsx | 12 ++-- .../select-input.tsx | 41 ------------- 10 files changed, 133 insertions(+), 112 deletions(-) rename frontend/src/{pages/private/workflows/workflows-editor/components/piece-form-item.component => components}/checkbox-input.tsx (69%) rename frontend/src/{pages/private/workflows/workflows-editor/components/piece-form-item.component => components}/codeeditor-input.tsx (70%) rename frontend/src/{pages/private/workflows/workflows-editor/components/piece-form-item.component => components}/datetime-input.tsx (84%) rename frontend/src/{pages/private/workflows/workflows-editor/components/piece-form-item.component => components}/number-input.tsx (61%) create mode 100644 frontend/src/components/select-input.tsx rename frontend/src/{pages/private/workflows/workflows-editor/components/piece-form-item.component => components}/text-input.tsx (55%) delete mode 100644 frontend/src/pages/private/workflows/workflows-editor/components/piece-form-item.component/select-input.tsx diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/piece-form-item.component/checkbox-input.tsx b/frontend/src/components/checkbox-input.tsx similarity index 69% rename from frontend/src/pages/private/workflows/workflows-editor/components/piece-form-item.component/checkbox-input.tsx rename to frontend/src/components/checkbox-input.tsx index c507ec93..8ad3724d 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/components/piece-form-item.component/checkbox-input.tsx +++ b/frontend/src/components/checkbox-input.tsx @@ -1,18 +1,17 @@ import { Checkbox, FormControlLabel, FormHelperText } from '@mui/material'; -import { IWorkflowPieceData } from 'context/workflows/types'; import React from 'react'; -import { useFormContext, Controller } from 'react-hook-form'; +import { useFormContext, Controller, FieldValues, Path } from 'react-hook-form'; import fetchFromObject from 'utils/fetch-from-object'; -interface Props { - name: `inputs.${string}.value` | `inputs.${string}.fromUpstream` | `inputs.${string}.fromUpstream.${string}` +interface Props { + name: Path label?: string defaultChecked?: boolean disabled?: boolean } -const CheckboxInput: React.FC = ({ label, name, defaultChecked = false, disabled = false }) => { - const { control, formState: { errors } } = useFormContext() +function CheckboxInput({ label, name, defaultChecked = false, disabled = false }:Props) { + const { control, formState: { errors } } = useFormContext() const error = fetchFromObject(errors, name) @@ -55,4 +54,4 @@ const CheckboxInput: React.FC = ({ label, name, defaultChecked = false, d ); } -export default React.memo(CheckboxInput); +export default CheckboxInput; diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/piece-form-item.component/codeeditor-input.tsx b/frontend/src/components/codeeditor-input.tsx similarity index 70% rename from frontend/src/pages/private/workflows/workflows-editor/components/piece-form-item.component/codeeditor-input.tsx rename to frontend/src/components/codeeditor-input.tsx index 0aa1bb5d..9f7aeb21 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/components/piece-form-item.component/codeeditor-input.tsx +++ b/frontend/src/components/codeeditor-input.tsx @@ -1,7 +1,6 @@ import React from 'react'; import CodeEditor from '@uiw/react-textarea-code-editor'; -import { Controller, useFormContext } from 'react-hook-form'; -import { IWorkflowPieceData } from 'context/workflows/types'; +import { Controller, FieldValues, Path, useFormContext } from 'react-hook-form'; const CodeEditorItem = React.forwardRef(({ ...register }) => ( ( /> )) -const CodeEditorInput: React.FC<{ name: `inputs.${string}.value` }> = ({ name }) => { - const { control } = useFormContext() +interface Props { + name: Path +} + +function CodeEditorInput({ name }: Props) { + const { control } = useFormContext() return ( = ({ name }) />); } -export default React.memo(CodeEditorInput); +export default CodeEditorInput; diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/piece-form-item.component/datetime-input.tsx b/frontend/src/components/datetime-input.tsx similarity index 84% rename from frontend/src/pages/private/workflows/workflows-editor/components/piece-form-item.component/datetime-input.tsx rename to frontend/src/components/datetime-input.tsx index 31085f0e..4a1950dd 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/components/piece-form-item.component/datetime-input.tsx +++ b/frontend/src/components/datetime-input.tsx @@ -1,21 +1,20 @@ import React from 'react'; -import { Controller, useFormContext } from 'react-hook-form'; +import { Controller, FieldValues, Path, useFormContext } from 'react-hook-form'; import dayjs from 'dayjs'; import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; import { DatePicker, DateTimePicker, LocalizationProvider, TimePicker } from '@mui/x-date-pickers'; import { DemoContainer } from '@mui/x-date-pickers/internals/demo'; -import { IWorkflowPieceData } from 'context/workflows/types'; -interface Props { +interface Props { label: string - name: `inputs.${string}.value` + name: Path type?: "time" | "date" | "date-time" } -const DatetimeInput: React.FC = ({ label, name, type = "date" }) => { +function DatetimeInput({ label, name, type = "date" }: Props) { - const { control } = useFormContext() + const { control } = useFormContext() const defaultValue = new Date().toISOString() @@ -24,7 +23,7 @@ const DatetimeInput: React.FC = ({ label, name, type = "date" }) => { return ( @@ -33,7 +32,7 @@ const DatetimeInput: React.FC = ({ label, name, type = "date" }) => { ampm={false} format='DD/MM/YYYY HH:mm' value={dayjs(value as string, 'YYYY-MM-DD HH:mm')} - onChange={(e) => { onChange(dayjs(e).format('YYYY-MM-DD HH:mm')) }} + onChange={(e) => { onChange(dayjs(e).format('YYYY-MM-DD HH:mm') as any) }} {...rest} /> @@ -44,7 +43,7 @@ const DatetimeInput: React.FC = ({ label, name, type = "date" }) => { return ( @@ -54,7 +53,7 @@ const DatetimeInput: React.FC = ({ label, name, type = "date" }) => { format='HH:mm' sx={{ width: "100%" }} value={dayjs(value as string, 'HH:mm')} - onChange={(e) => { onChange(dayjs(e).format('HH:mm')) }} + onChange={(e) => { onChange(dayjs(e).format('HH:mm') as any) }} {...rest} /> @@ -66,7 +65,7 @@ const DatetimeInput: React.FC = ({ label, name, type = "date" }) => { return ( @@ -76,7 +75,7 @@ const DatetimeInput: React.FC = ({ label, name, type = "date" }) => { format="DD/MM/YYYY" sx={{ width: "100%" }} value={dayjs(value as string, 'YYYY-MM-DD')} - onChange={(e) => { onChange(dayjs(e).format('YYYY-MM-DD')) }} + onChange={(e) => { onChange(dayjs(e).format('YYYY-MM-DD') as any) }} {...rest} /> @@ -86,4 +85,4 @@ const DatetimeInput: React.FC = ({ label, name, type = "date" }) => { } } -export default React.memo(DatetimeInput); +export default DatetimeInput; diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/piece-form-item.component/number-input.tsx b/frontend/src/components/number-input.tsx similarity index 61% rename from frontend/src/pages/private/workflows/workflows-editor/components/piece-form-item.component/number-input.tsx rename to frontend/src/components/number-input.tsx index 2916cc08..0242b670 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/components/piece-form-item.component/number-input.tsx +++ b/frontend/src/components/number-input.tsx @@ -1,18 +1,17 @@ import { TextField } from '@mui/material'; -import { IWorkflowPieceData } from 'context/workflows/types'; import React from 'react'; -import { useFormContext } from 'react-hook-form'; +import { FieldValues, Path, useFormContext } from 'react-hook-form'; import fetchFromObject from 'utils/fetch-from-object'; -interface Props { +interface Props { label: string - name: `inputs.${string}.value` + name: Path defaultValue: number type: "float" | "int" } -const NumberInput: React.FC = ({ name, label, type = "int", defaultValue }) => { - const { register, formState:{errors} } = useFormContext() +function NumberInput({ name, label, type = "int", defaultValue }:Props) { + const { register, formState:{errors} } = useFormContext() const error = fetchFromObject(errors,name) @@ -34,4 +33,4 @@ const NumberInput: React.FC = ({ name, label, type = "int", defaultValue />); } -export default React.memo(NumberInput); +export default NumberInput; diff --git a/frontend/src/components/select-input.tsx b/frontend/src/components/select-input.tsx new file mode 100644 index 00000000..0652966c --- /dev/null +++ b/frontend/src/components/select-input.tsx @@ -0,0 +1,58 @@ +import React from 'react'; +import { FormControl, FormHelperText, InputLabel, MenuItem, Select } from '@mui/material'; +import { FieldValues, Path, useFormContext } from 'react-hook-form'; +import fetchFromObject from 'utils/fetch-from-object'; + +type Props = { + name: Path + label: string + options: string[] | {label:string,value:string}[] + + emptyValue: true + defaultValue?: string +} | { + name: Path + label: string + options: string[] | {label:string,value:string}[] + + emptyValue?: boolean + defaultValue: string +} + +function SelectInput({ options, label, name, defaultValue, emptyValue }:Props) { + const { register, formState:{errors} } = useFormContext() + + const error = fetchFromObject(errors,name) + + return ( + + {label} + + + {error?.message} + + ); +} + +export default SelectInput; diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/piece-form-item.component/text-input.tsx b/frontend/src/components/text-input.tsx similarity index 55% rename from frontend/src/pages/private/workflows/workflows-editor/components/piece-form-item.component/text-input.tsx rename to frontend/src/components/text-input.tsx index 5534ea91..cddc185d 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/components/piece-form-item.component/text-input.tsx +++ b/frontend/src/components/text-input.tsx @@ -1,17 +1,16 @@ -import { TextField } from '@mui/material'; -import { IWorkflowPieceData } from 'context/workflows/types'; import React from 'react'; -import { useFormContext } from 'react-hook-form'; +import { TextField } from '@mui/material'; +import { FieldValues, Path, useFormContext } from 'react-hook-form'; import fetchFromObject from 'utils/fetch-from-object'; -interface Props { +interface Props { label: string - name: `inputs.${string}` + name: Path defaultValue?: string } -const TextInput: React.FC = ({ name, label, defaultValue = "" }) => { - const { register, formState:{errors} } = useFormContext() +function TextInput({ name, label, defaultValue = "" }:Props) { + const { register, formState:{errors} } = useFormContext() const error = fetchFromObject(errors,name) @@ -27,4 +26,4 @@ const TextInput: React.FC = ({ name, label, defaultValue = "" }) => { />); } -export default React.memo(TextInput); +export default TextInput; diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/piece-form-item.component/array-input.tsx b/frontend/src/pages/private/workflows/workflows-editor/components/piece-form-item.component/array-input.tsx index 92bd5981..dc0b703e 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/components/piece-form-item.component/array-input.tsx +++ b/frontend/src/pages/private/workflows/workflows-editor/components/piece-form-item.component/array-input.tsx @@ -6,15 +6,17 @@ import AddIcon from '@mui/icons-material/Add'; import DeleteIcon from '@mui/icons-material/Delete'; import { IWorkflowPieceData, InputArray } from 'context/workflows/types'; -import { ArrayOption } from '../piece-form.component/upstream-options'; -import TextInput from './text-input'; -import SelectInput from './select-input'; -import NumberInput from './number-input'; -import CheckboxInput from './checkbox-input'; -import DatetimeInput from './datetime-input'; -import CodeEditorInput from './codeeditor-input'; + +import TextInput from 'components/text-input'; +import SelectInput from 'components/select-input'; +import NumberInput from 'components/number-input'; +import CheckboxInput from 'components/checkbox-input'; +import DatetimeInput from 'components/datetime-input'; +import CodeEditorInput from 'components/codeeditor-input'; + import SelectUpstreamInput from './select-upstream-input'; import ObjectInputComponent from './object-input'; +import { ArrayOption } from '../piece-form.component/upstream-options'; interface ArrayInputItemProps { inputKey: string diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/piece-form-item.component/index.tsx b/frontend/src/pages/private/workflows/workflows-editor/components/piece-form-item.component/index.tsx index 8aaf473e..195657ec 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/components/piece-form-item.component/index.tsx +++ b/frontend/src/pages/private/workflows/workflows-editor/components/piece-form-item.component/index.tsx @@ -3,19 +3,20 @@ import { Box, Grid, } from '@mui/material'; -import { UseFormRegister, Control, useFormContext } from 'react-hook-form'; +import { Control, useFormContext } from 'react-hook-form'; -import { Input, IWorkflowPieceData, InputArray } from 'context/workflows/types'; +import { IWorkflowPieceData } from 'context/workflows/types'; -import SelectUpstreamInput from './select-upstream-input'; -import NumberInput from './number-input'; -import CheckboxInput from './checkbox-input'; -import SelectInput from './select-input'; -import DatetimeInput from './datetime-input'; -import CodeEditorInput from './codeeditor-input'; -import TextInput from './text-input'; +import NumberInput from 'components/number-input'; +import CheckboxInput from 'components/checkbox-input'; +import SelectInput from 'components/select-input'; +import DatetimeInput from 'components/datetime-input'; +import CodeEditorInput from 'components/codeeditor-input'; +import TextInput from 'components/text-input'; +import SelectUpstreamInput from './select-upstream-input'; import ArrayInput from './array-input'; + import { ArrayOption, Option } from '../piece-form.component/upstream-options'; interface PieceFormItemProps { @@ -55,7 +56,7 @@ const PieceFormItem: React.FC = ({ upstreamOptions, itemKey, return [defaultChecked, editable] }, [schema, upstreamOptions]) - const { watch } = useFormContext() + const { watch } = useFormContext() const data = watch() const checkedFromUpstream = data.inputs[itemKey]?.fromUpstream @@ -79,7 +80,7 @@ const PieceFormItem: React.FC = ({ upstreamOptions, itemKey, const typeClass = schema.allOf[0]['$ref'].split("/").pop(); const valuesOptions: Array = definitions?.[typeClass].enum; inputElement = - label={itemKey} defaultValue={schema?.default} name={`inputs.${itemKey}.value`} @@ -87,7 +88,7 @@ const PieceFormItem: React.FC = ({ upstreamOptions, itemKey, /> } else if ((schema.type === 'number') && !schema.format) { inputElement = - name={`inputs.${itemKey}.value`} type="float" label={schema.title} @@ -95,14 +96,14 @@ const PieceFormItem: React.FC = ({ upstreamOptions, itemKey, /> } else if (schema.type === 'integer' && !schema.format) { inputElement = - name={`inputs.${itemKey}.value`} type="int" label={schema.title} defaultValue={schema?.default ?? 10} /> } else if (schema.type === 'boolean' && !schema.format) { - inputElement = name={`inputs.${itemKey}.value`} label={schema.title} /> @@ -117,33 +118,33 @@ const PieceFormItem: React.FC = ({ upstreamOptions, itemKey, /> } else if (schema.type === 'string' && schema.format === 'date') { inputElement = - name={`inputs.${itemKey}.value`} label={schema.title} type="date" />; } else if (schema.type === 'string' && schema?.format === 'time') { inputElement = - name={`inputs.${itemKey}.value`} label={schema.title} type="time" />; } else if (schema.type === 'string' && schema?.format === 'date-time') { inputElement = - name={`inputs.${itemKey}.value`} label={schema.title} type="date-time" />; } else if (schema.type === 'string' && schema?.widget === 'codeeditor') { inputElement = - name={`inputs.${itemKey}.value`} /> } else if (schema.type === 'string' && !schema.format) { inputElement = - name={`inputs.${itemKey}.value`} label={schema.title} />; diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/piece-form-item.component/object-input.tsx b/frontend/src/pages/private/workflows/workflows-editor/components/piece-form-item.component/object-input.tsx index fcf419b9..ea980eac 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/components/piece-form-item.component/object-input.tsx +++ b/frontend/src/pages/private/workflows/workflows-editor/components/piece-form-item.component/object-input.tsx @@ -1,10 +1,12 @@ import React, { useCallback, useMemo } from 'react'; -import { Option } from '../piece-form.component/upstream-options'; -import TextInput from './text-input'; -import SelectUpstreamInput from './select-upstream-input'; -import { Box, Container, Grid } from '@mui/material'; -import CheckboxInput from './checkbox-input'; import { useWatch } from 'react-hook-form'; +import { Grid } from '@mui/material'; + +import TextInput from 'components/text-input'; +import CheckboxInput from 'components/checkbox-input'; + +import SelectUpstreamInput from './select-upstream-input'; +import { Option } from '../piece-form.component/upstream-options'; interface Prop { name: `inputs.${string}.value.${number}` diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/piece-form-item.component/select-input.tsx b/frontend/src/pages/private/workflows/workflows-editor/components/piece-form-item.component/select-input.tsx deleted file mode 100644 index cd5f75d1..00000000 --- a/frontend/src/pages/private/workflows/workflows-editor/components/piece-form-item.component/select-input.tsx +++ /dev/null @@ -1,41 +0,0 @@ -import { FormControl, FormHelperText, InputLabel, MenuItem, Select } from '@mui/material'; -import React from 'react'; -import { useFormContext } from 'react-hook-form'; -import { IWorkflowPieceData } from 'context/workflows/types'; -import fetchFromObject from 'utils/fetch-from-object'; - -interface Props { - label: string - name: `inputs.${string}.value` - defaultValue: string - options: string[] -} - -const SelectInput: React.FC = ({ options, label, name, defaultValue }) => { - const { register, formState:{errors} } = useFormContext() - - const error = fetchFromObject(errors,name) - - return ( - - {label} - - - {error?.message} - - ); -} - -export default React.memo(SelectInput); From 7355d28a69b746d5b2e66bcd04d54a87ddcc9d5c Mon Sep 17 00:00:00 2001 From: Nathan Vieira Marcelino Date: Mon, 31 Jul 2023 14:13:38 -0300 Subject: [PATCH 136/328] fix: improve types and refactor validation --- .../workflows/types/container-resources.ts | 12 +- .../src/context/workflows/types/settings.ts | 8 +- .../piece-form-item.component/array-input.tsx | 2 +- .../piece-form.component/validation.ts | 7 +- .../container-resource-form.component.tsx | 57 ++--- .../sidebar-form.component/index.tsx | 14 +- .../storage-form.component.tsx | 6 +- .../sidebar-settings-form.component.tsx | 196 ++++++------------ .../workflow-editor-panel.component.tsx | 22 +- frontend/src/utils/validationResolver.ts | 144 +++++++++---- 10 files changed, 235 insertions(+), 233 deletions(-) diff --git a/frontend/src/context/workflows/types/container-resources.ts b/frontend/src/context/workflows/types/container-resources.ts index 5ac34428..0eb2bb4b 100644 --- a/frontend/src/context/workflows/types/container-resources.ts +++ b/frontend/src/context/workflows/types/container-resources.ts @@ -1,7 +1,11 @@ export interface IContainerResourceFormData { useGpu: boolean, - cpuMin: number, - cpuMax: number - memoryMin: number, - memoryMax: number + cpu:{ + min:number, + max: number, + }, + memory:{ + min:number, + max: number, + } } diff --git a/frontend/src/context/workflows/types/settings.ts b/frontend/src/context/workflows/types/settings.ts index 39964e2d..24819e8e 100644 --- a/frontend/src/context/workflows/types/settings.ts +++ b/frontend/src/context/workflows/types/settings.ts @@ -12,12 +12,12 @@ export enum scheduleIntervals { export enum endDateTypes { Never = "Never", - UserDefined = "User Defined", + UserDefined = "UserDefined", } export enum storageSources { None = "None", - AWSS3 = "AWS S3", + AWSS3 = "AWSS3", } export type storageSourceType = keyof typeof storageSources; @@ -35,8 +35,8 @@ export interface IWorkflowSettingsConfig { export interface IWorkflowSettingsStorage { storageSource: storageSourceType, - baseFolder: string, - bucket: string + baseFolder?: string, + bucket?: string } export interface IWorkflowSettings { config: IWorkflowSettingsConfig diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/piece-form-item.component/array-input.tsx b/frontend/src/pages/private/workflows/workflows-editor/components/piece-form-item.component/array-input.tsx index dc0b703e..64d14ede 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/components/piece-form-item.component/array-input.tsx +++ b/frontend/src/pages/private/workflows/workflows-editor/components/piece-form-item.component/array-input.tsx @@ -1,7 +1,7 @@ import React, { useCallback, useMemo, useState } from 'react'; import { Control, FieldArrayWithId, useFieldArray, useFormContext } from 'react-hook-form'; -import { Card, CardContent, IconButton, Box, Grid } from '@mui/material'; +import { Card, CardContent, IconButton, Grid } from '@mui/material'; import AddIcon from '@mui/icons-material/Add'; import DeleteIcon from '@mui/icons-material/Delete'; diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/piece-form.component/validation.ts b/frontend/src/pages/private/workflows/workflows-editor/components/piece-form.component/validation.ts index c3bccfc0..758ce0cf 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/components/piece-form.component/validation.ts +++ b/frontend/src/pages/private/workflows/workflows-editor/components/piece-form.component/validation.ts @@ -52,10 +52,7 @@ const validationObject = { }), {})) }), value: yup.lazy(obj => { - return yup.object().shape(Object.keys(obj).reduce((acc, val) => { - console.log(obj) - - return ({ + return yup.object().shape(Object.keys(obj).reduce((acc, val) => ({ ...acc, [val]: yup.string().when("fromUpstream", ([fromUpstream]) => { if (fromUpstream) { @@ -64,7 +61,7 @@ const validationObject = { return yup.string().required() }) }) - }, {})) + , {})) }), } diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component/container-resource-form.component.tsx b/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component/container-resource-form.component.tsx index 5ffbea5e..8db3d92d 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component/container-resource-form.component.tsx +++ b/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component/container-resource-form.component.tsx @@ -9,7 +9,7 @@ import { import * as yup from "yup"; import { useFormContext } from "react-hook-form"; -import { IWorkflowPieceData } from "context/workflows/types"; +import { IContainerResourceFormData, IWorkflowPieceData } from "context/workflows/types"; // TODO check if these values make sense const minAcceptedMemory = 128 @@ -17,19 +17,28 @@ const minAcceptedCpu = 100 const maxAcceptedMemory = 12800 const maxAcceptedCpu = 10000 -export const defaultContainerResources = { +export const defaultContainerResources: IContainerResourceFormData = { useGpu: false, - memoryMin: 128, - memoryMax: 128, - cpuMin: 100, - cpuMax: 100 + memory: { + min: 128, + max: 128, + }, + cpu: { + min: 100, + max: 100 + } } -export const ContainerResourceFormSchema = yup.object().shape({ - cpuMin: yup.number().integer().max(maxAcceptedCpu).min(minAcceptedCpu).required(), - cpuMax: yup.number().integer().max(maxAcceptedCpu).min(minAcceptedCpu).required(), - memoryMin: yup.number().integer().max(maxAcceptedMemory).min(minAcceptedMemory).required(), - memoryMax: yup.number().integer().max(maxAcceptedMemory).min(minAcceptedMemory).required(), +export const ContainerResourceFormSchema: yup.ObjectSchema = yup.object().shape({ + cpu: yup.object().shape({ + min: yup.number().integer().max(maxAcceptedCpu).min(minAcceptedCpu).required(), + max: yup.number().integer().max(maxAcceptedCpu).min(minAcceptedCpu).required() + }), + memory: yup.object().shape({ + min: yup.number().integer().max(maxAcceptedMemory).min(minAcceptedMemory).required(), + max: yup.number().integer().max(maxAcceptedMemory).min(minAcceptedMemory).required() + }), + useGpu: yup.boolean().required(), }); const ContainerResourceForm: React.FC = () => { @@ -50,9 +59,9 @@ const ContainerResourceForm: React.FC = () => { min: minAcceptedCpu, max: maxAcceptedCpu }} - error={!!formState.errors.containerResources?.cpuMin?.message} - helperText={formState.errors.containerResources?.cpuMin?.message} - {...register("containerResources.cpuMin")} + error={!!formState.errors.containerResources?.cpu?.min?.message} + helperText={formState.errors.containerResources?.cpu?.min?.message} + {...register("containerResources.cpu.min")} /> @@ -65,9 +74,9 @@ const ContainerResourceForm: React.FC = () => { min: minAcceptedCpu, max: maxAcceptedCpu }} - error={!!formState.errors.containerResources?.cpuMax?.message} - helperText={formState.errors.containerResources?.cpuMax?.message} - {...register(`containerResources.${"cpuMax"}`)} + error={!!formState.errors.containerResources?.cpu?.max?.message} + helperText={formState.errors.containerResources?.cpu?.max?.message} + {...register(`containerResources.cpu.max`)} /> @@ -80,9 +89,9 @@ const ContainerResourceForm: React.FC = () => { min: minAcceptedMemory, max: maxAcceptedMemory }} - error={!!formState.errors.containerResources?.memoryMin?.message} - helperText={formState.errors.containerResources?.memoryMin?.message} - {...register("containerResources.memoryMin")} + error={!!formState.errors.containerResources?.memory?.min?.message} + helperText={formState.errors.containerResources?.memory?.min?.message} + {...register("containerResources.memory.min")} /> @@ -95,9 +104,9 @@ const ContainerResourceForm: React.FC = () => { min: minAcceptedMemory, max: maxAcceptedMemory }} - error={!!formState.errors.containerResources?.memoryMax?.message} - helperText={formState.errors.containerResources?.memoryMax?.message} - {...register("containerResources.memoryMax")} + error={!!formState.errors.containerResources?.memory?.max?.message} + helperText={formState.errors.containerResources?.memory?.max?.message} + {...register("containerResources.memory.max")} /> @@ -114,4 +123,4 @@ const ContainerResourceForm: React.FC = () => { ) } -export default ContainerResourceForm; \ No newline at end of file +export default ContainerResourceForm; diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component/index.tsx b/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component/index.tsx index aa0c8633..59639fda 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component/index.tsx +++ b/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component/index.tsx @@ -1,4 +1,4 @@ -import React, { useCallback, useEffect, useMemo } from 'react' +import React, { useCallback, useEffect, useMemo, useState } from 'react' import { Drawer, Grid, @@ -9,7 +9,6 @@ import { } from '@mui/material' import ExpandMoreIcon from '@mui/icons-material/ExpandMore'; import { FormProvider, useForm } from 'react-hook-form'; - import * as yup from "yup" import { useWorkflowsEditor } from 'context/workflows/workflows-editor.context' @@ -39,8 +38,6 @@ const defaultValues: IWorkflowPieceData = { inputs: {}, } - - const SidebarPieceForm: React.FC = (props) => { const { schema, @@ -71,11 +68,12 @@ const SidebarPieceForm: React.FC = (props) => { }) const data = methods.watch() - // console.log("ERRORS: ", methods.formState.errors) + const [loaded,setLoaded] = useState(false) const loadData = useCallback(async () => { const data = await fetchForageWorkflowPiecesDataById(formId) methods.reset(data) // put forage data on form if exist + setLoaded(true) }, [formId, methods.reset]) const saveData = useCallback(async () => { @@ -84,6 +82,12 @@ const SidebarPieceForm: React.FC = (props) => { } }, [formId, open, data]) + const validate = useCallback(()=>{ + if(loaded) + methods.trigger() + },[loaded,methods.trigger]) + + useEffect(()=>{validate()},[validate]) //load forage useEffect(() => { diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component/storage-form.component.tsx b/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component/storage-form.component.tsx index ab6ac0fc..9c1c641a 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component/storage-form.component.tsx +++ b/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component/storage-form.component.tsx @@ -2,13 +2,13 @@ import React from 'react'; import { Controller, useFormContext } from 'react-hook-form'; import * as yup from 'yup' import { FormControl, FormHelperText, Grid, InputLabel, MenuItem, Select, Typography } from '@mui/material'; -import { IWorkflowPieceData, storageAccessModeType, storageAccessModes } from 'context/workflows/types'; +import { IStorageFormData, IWorkflowPieceData, storageAccessModeType, storageAccessModes } from 'context/workflows/types'; export const storageFormSchema = yup.object().shape({ storageAccessMode: yup.mixed().oneOf(Object.values(storageAccessModes)).required(), }); -export const defaultStorage = { +export const defaultStorage: IStorageFormData = { storageAccessMode: storageAccessModes.None as storageAccessModeType } @@ -51,4 +51,4 @@ const StorageForm: React.FC = () => { ); } -export default StorageForm; \ No newline at end of file +export default StorageForm; diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-settings-form.component.tsx b/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-settings-form.component.tsx index 02de282c..95730e62 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-settings-form.component.tsx +++ b/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-settings-form.component.tsx @@ -1,28 +1,22 @@ +import { useCallback, useEffect, useState } from 'react' +import { FormProvider, useForm } from 'react-hook-form'; +import * as yup from "yup"; import { Drawer, Grid, Typography, - FormControl, TextField, - InputLabel, - Select, - MenuItem, } from '@mui/material' -import dayjs from 'dayjs'; -import { DemoContainer } from '@mui/x-date-pickers/internals/demo'; -import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; -import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; -import { DateTimePicker } from '@mui/x-date-pickers/DateTimePicker'; -//import { materialCells, materialRenderers } from '@jsonforms/material-renderers' -//import { JsonForms } from '@jsonforms/react' -import { useCallback, useEffect } from 'react' + import { useWorkflowsEditor } from 'context/workflows/workflows-editor.context' import { IWorkflowSettings, endDateTypes, scheduleIntervals, storageSources } from 'context/workflows/types/settings'; -import { endDateTypeType, scheduleIntervalType, storageSourceType } from 'context/workflows/types/settings'; -import { Controller, useForm } from 'react-hook-form'; -import * as yup from "yup"; + import useYupValidationResolver from 'utils/validationResolver'; +import TextInput from 'components/text-input'; +import SelectInput from 'components/select-input'; +import DatetimeInput from 'components/datetime-input'; + interface ISidebarSettingsFormProps { open: boolean, onClose: (event: any) => void @@ -63,19 +57,21 @@ const storageSourceOptions = process.env.REACT_APP_DOMINO_DEPLOY_MODE === "local } ] +type ValidationSchema = yup.ObjectSchema + // TODO check yup validation -export const WorkflowSettingsFormSchema = yup.object().shape({ +export const WorkflowSettingsFormSchema: ValidationSchema = yup.object().shape({ config: yup.object().shape({ name: yup.string().required(), - scheduleInterval: yup.mixed().oneOf(Object.values(scheduleIntervals)).required(), - startDate: yup.date().required(), - endDate: yup.date(), - endDateType: yup.mixed().oneOf(Object.values(endDateTypes)).required(), + scheduleInterval: yup.mixed().oneOf(Object.values(scheduleIntervals)).required(), + startDate: yup.string().required(), + endDate: yup.string(), + endDateType: yup.mixed().oneOf(Object.values(endDateTypes)).required(), }), storage: yup.object().shape({ - storageSource: yup.mixed().oneOf(Object.values(storageSources)).required(), + storageSource: yup.mixed().oneOf(Object.values(storageSources)).required(), baseFolder: yup.string(), - bucket: yup.string(), + bucket: yup.string() }) }); @@ -85,28 +81,38 @@ const SidebarSettingsForm = (props: ISidebarSettingsFormProps) => { onClose, } = props - + const { fetchWorkflowSettingsData, setWorkflowSettingsData, } = useWorkflowsEditor() const resolver = useYupValidationResolver(WorkflowSettingsFormSchema); - const { register, watch, control, reset } = useForm({ mode: "onChange", resolver }) + const methods = useForm({ mode: "onChange", resolver }) + const { register, watch, reset, trigger } = methods const formData = watch() + const [loaded, setLoaded] = useState(false) + + const validate = useCallback(() => { + if (loaded) + trigger() + }, [loaded, trigger]) + + useEffect(() => { validate() }, [validate]) const loadData = useCallback(async () => { const data = await fetchWorkflowSettingsData() if (Object.keys(data).length === 0) { reset(defaultSettingsData) - }else{ + } else { reset(data) } + setLoaded(true) }, [reset, fetchWorkflowSettingsData]) const saveData = useCallback(async () => { - if (open){ + if (open) { console.log(formData) await setWorkflowSettingsData(formData) } @@ -140,141 +146,63 @@ const SidebarSettingsForm = (props: ISidebarSettingsFormProps) => { Settings -
+ - - - Schedule Interval - ( - - )} - /> - + - ( - - - { onChange(dayjs(e).format('YYYY-MM-DD HH:mm')) }} - {...rest} - /> - - - )} + label="Start Date/Time" + type='date-time' /> - - End Date/Time - ( - - )} - /> - + - ( - - - { onChange(dayjs(e).format('YYYY-MM-DD HH:mm')) }} - sx={{ width: "100%" }} - {...rest} - /> - - - )} + label="End Date/Time" + type='date-time' /> - +
Storage -
+ - - Storage Source - ( - - )} - /> - + { formData.storage.storageSource === 'AWSS3' ? ( @@ -301,7 +229,7 @@ const SidebarSettingsForm = (props: ISidebarSettingsFormProps) => { ) : null } - +
diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/workflow-editor-panel.component.tsx b/frontend/src/pages/private/workflows/workflows-editor/components/workflow-editor-panel.component.tsx index 1b358579..2d46f5f4 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/components/workflow-editor-panel.component.tsx +++ b/frontend/src/pages/private/workflows/workflows-editor/components/workflow-editor-panel.component.tsx @@ -133,7 +133,7 @@ const WorkflowEditorPanelComponent = () => { const piece = await fetchForagePieceById(data.id) const inputSchema = piece?.input_schema const defaultData: any = extractDefaultValues(inputSchema) - const containerResourcesDefaultData: unknown = extractDefaultValues(containerResourcesSchema) + const defaultContainerResources: unknown = extractDefaultValues(containerResourcesSchema) const currentWorkflowPieces = await getForageWorkflowPieces() const newWorkflowPieces = { @@ -143,7 +143,7 @@ const WorkflowEditorPanelComponent = () => { await setForageWorkflowPieces(newWorkflowPieces) // Set default data for upstream mapping - used in dags - var upstreamMapFormInfo: any = {} + const defaultInputs: any = {} for (const key in defaultData) { const fromUpstream = false // TODO - If someday we allow default upstream true we should change this const upstreamId = null @@ -164,7 +164,7 @@ const WorkflowEditorPanelComponent = () => { for (const [_key, _value] of Object.entries(element)) { newValue.fromUpstream = { ...newValue.fromUpstream, - [_key]: "" + [_key]: fromUpstream } newValue.upstreamId = { ...newValue.upstreamId, @@ -187,8 +187,8 @@ const WorkflowEditorPanelComponent = () => { } else { newValue = { fromUpstream: fromUpstream, - upstreamId: upstreamId, - upstreamArgument: null, + upstreamId: upstreamId ?? "", + upstreamArgument: "", upstreamValue: "", value: element } @@ -197,7 +197,7 @@ const WorkflowEditorPanelComponent = () => { } defaultValues = auxDefaultValues } - upstreamMapFormInfo[key] = { + defaultInputs[key] = { fromUpstream, upstreamId: upstreamId ?? "", upstreamArgument: "", @@ -211,17 +211,11 @@ const WorkflowEditorPanelComponent = () => { // TODO: refactor types here const defaultWorkflowPieceData = { storage: { storageAccessMode: storageAccessModes.ReadWrite }, - containerResources: containerResourcesDefaultData, - inputs: upstreamMapFormInfo + containerResources: defaultContainerResources, + inputs: defaultInputs } as unknown as IWorkflowPieceData await setForageWorkflowPiecesData(newNode.id, defaultWorkflowPieceData) - - defaultData['storage'] = { - "storageAccessMode": 'Read/Write', - } - defaultData['containerResources'] = containerResourcesDefaultData - // Set default data for the node form - used in json-forms }, [ fetchForagePieceById, nodeDirection, diff --git a/frontend/src/utils/validationResolver.ts b/frontend/src/utils/validationResolver.ts index ecf9ac4b..e5a4afe4 100644 --- a/frontend/src/utils/validationResolver.ts +++ b/frontend/src/utils/validationResolver.ts @@ -1,46 +1,112 @@ -import { useCallback } from 'react'; +import { FieldErrors, FieldValues } from 'react-hook-form'; import { ObjectSchema, ValidationError } from 'yup'; +const isNullOrUndefined = (value: unknown): value is null | undefined => value == null + +const isObjectType = (value: unknown) => typeof value === 'object'; + +const isDateObject = (value: unknown): value is Date => value instanceof Date; + +const isObject = (value: unknown): value is T => + !isNullOrUndefined(value) && + !Array.isArray(value) && + isObjectType(value) && + !isDateObject(value); + +function compact(value: TValue[]) { + return Array.isArray(value) ? value.filter(Boolean) : []; +} + +function stringToPath(input: string): string[] { + return compact(input.replace(/["|']|\]/g, '').split(/\.|\[/)); +} + +function isKey(value: string) { + return /^\w*$/.test(value); +} + +function set( + object: FieldValues, + path: string, + value?: unknown, +) { + let index = -1; + const tempPath = isKey(path) ? [path] : stringToPath(path); + const length = tempPath.length; + const lastIndex = length - 1; + + while (++index < length) { + const key = tempPath[index]; + let newValue = value; + + if (index !== lastIndex) { + const objValue = object[key]; + newValue = + isObject(objValue) || Array.isArray(objValue) + ? objValue + : !isNaN(+tempPath[index + 1]) + ? [] + : {}; + } + object[key] = newValue; + object = object[key]; + } + return object; +} + +export const toNestError = ( + errors: FieldErrors, +): FieldErrors => { + const fieldErrors = {} as FieldErrors; + for (const path in errors) { + set( + fieldErrors, + path, + Object.assign(errors[path] || {}), + ); + } + + return fieldErrors; +}; + const useYupValidationResolver = ( validationSchema: ObjectSchema> -) => - useCallback( - async (data: any) => { - try { - const values = await validationSchema.validate(data, { - abortEarly: false, - }); - - return { - values, - errors: {}, - }; - } catch (errors) { - if (errors instanceof ValidationError) { +) => async (data: any) => { + try { + const values = await validationSchema.validate(data, { + abortEarly: false, + }); + + return { + values, + errors: {}, + }; + } catch (e) { + if (e instanceof ValidationError) { + const errors = e.inner.reduce( + (allErrors, currentError) => { + const path = (currentError.path as string) + ?.replaceAll("[", ".") + .replaceAll("]", "") return { - values: {}, - errors: errors.inner.reduce( - (allErrors, currentError) => { - const path = (currentError.path as string) - ?.replaceAll("[", ".") - .replaceAll("]", "") - return { - ...allErrors, - [path]: { - type: currentError.type ?? 'validation', - message: currentError.message, - }, - } - }, - {} - ), - }; - } - - throw new Error('Error trying to validate form schema'); - } - }, - [validationSchema] - ); + ...allErrors, + [path]: { + type: currentError.type ?? 'validation', + message: currentError.message, + }, + } + }, + {} + ) + + return { + values: {}, + errors: toNestError(errors), + }; + } + + throw new Error('Error trying to validate form schema'); + } +} export default useYupValidationResolver; From 0e7930ba1d94985fcf29f52016586f6d86ca1964 Mon Sep 17 00:00:00 2001 From: Nathan Vieira Marcelino Date: Wed, 2 Aug 2023 15:14:28 -0300 Subject: [PATCH 137/328] feat: improve inputs components --- frontend/src/components/number-input.tsx | 31 +++++++++++++++++------- frontend/src/components/select-input.tsx | 15 +++++++----- frontend/src/components/text-input.tsx | 12 +++++---- 3 files changed, 38 insertions(+), 20 deletions(-) diff --git a/frontend/src/components/number-input.tsx b/frontend/src/components/number-input.tsx index 0242b670..59b8b875 100644 --- a/frontend/src/components/number-input.tsx +++ b/frontend/src/components/number-input.tsx @@ -1,20 +1,33 @@ -import { TextField } from '@mui/material'; -import React from 'react'; -import { FieldValues, Path, useFormContext } from 'react-hook-form'; +import { TextField, TextFieldProps } from '@mui/material'; +import React, { useMemo } from 'react'; +import { FieldValues, Path, RegisterOptions, useFormContext } from 'react-hook-form'; import fetchFromObject from 'utils/fetch-from-object'; -interface Props { +type Props = Omit & { label: string name: Path - defaultValue: number + defaultValue?: number type: "float" | "int" + registerOptions?: RegisterOptions } -function NumberInput({ name, label, type = "int", defaultValue }:Props) { +function NumberInput({ name, label, type = "int", defaultValue = 0, inputProps, registerOptions , ...rest }:Props) { const { register, formState:{errors} } = useFormContext() const error = fetchFromObject(errors,name) + const options = useMemo>(()=>{ + if(registerOptions){ + return { + ...registerOptions, + valueAsNumber: true + } as RegisterOptions + } + return { + valueAsNumber: true + } + },[registerOptions]) + return ( ({ name, label, type = "int", default error={!!error?.message} helperText={error?.message} inputProps={{ + ...inputProps, step: type === "int" ? 1 : 0.1, }} - {...register(name, { - valueAsNumber: true - })} + {...rest} + {...register(name, options)} />); } diff --git a/frontend/src/components/select-input.tsx b/frontend/src/components/select-input.tsx index 0652966c..0dc87323 100644 --- a/frontend/src/components/select-input.tsx +++ b/frontend/src/components/select-input.tsx @@ -1,25 +1,27 @@ import React from 'react'; -import { FormControl, FormHelperText, InputLabel, MenuItem, Select } from '@mui/material'; -import { FieldValues, Path, useFormContext } from 'react-hook-form'; +import { FormControl, FormHelperText, InputLabel, MenuItem, Select, SelectProps } from '@mui/material'; +import { FieldValues, Path, RegisterOptions, useFormContext } from 'react-hook-form'; import fetchFromObject from 'utils/fetch-from-object'; -type Props = { +type Props = SelectProps & { name: Path label: string options: string[] | {label:string,value:string}[] emptyValue: true defaultValue?: string -} | { + registerOptions?: RegisterOptions> | undefined +} | SelectProps & { name: Path label: string options: string[] | {label:string,value:string}[] emptyValue?: boolean defaultValue: string + registerOptions?: RegisterOptions } -function SelectInput({ options, label, name, defaultValue, emptyValue }:Props) { +function SelectInput({ options, label, name, defaultValue, emptyValue, registerOptions, ...rest }:Props) { const { register, formState:{errors} } = useFormContext() const error = fetchFromObject(errors,name) @@ -29,7 +31,8 @@ function SelectInput({ options, label, name, defaultValue {label} {emptyValue && None } {options.map((option) => { - if(typeof option === "object"){ + if (typeof option === "object") { return ( {option.label} diff --git a/frontend/src/components/text-input.tsx b/frontend/src/components/text-input.tsx index 38cb13fa..d7a9b17e 100644 --- a/frontend/src/components/text-input.tsx +++ b/frontend/src/components/text-input.tsx @@ -1,7 +1,7 @@ import React from 'react'; import { TextField, TextFieldProps } from '@mui/material'; import { FieldValues, Path, RegisterOptions, useFormContext } from 'react-hook-form'; -import fetchFromObject from 'utils/fetch-from-object'; +import { fetchFromObject } from 'utils'; type Props = Omit & { label: string diff --git a/frontend/src/context/workflows/workflows-editor.context/index.tsx b/frontend/src/context/workflows/workflows-editor.context/index.tsx index 315f044f..2840c5dd 100644 --- a/frontend/src/context/workflows/workflows-editor.context/index.tsx +++ b/frontend/src/context/workflows/workflows-editor.context/index.tsx @@ -8,7 +8,7 @@ import { import { useWorkspaces } from 'context/workspaces/workspaces.context'; -import { createCustomContext } from 'utils' +import { createCustomContext, getIdSlice, getUuidSlice } from 'utils' import { usesPieces, IPiecesContext } from './pieces.context'; import { useWorkflowsEdges, IWorkflowsEdgesContext } from './workflow-edges.context'; diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/piece-form-item.component/select-upstream-input.tsx b/frontend/src/pages/private/workflows/workflows-editor/components/piece-form-item.component/select-upstream-input.tsx index 360fda10..e29c5bd5 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/components/piece-form-item.component/select-upstream-input.tsx +++ b/frontend/src/pages/private/workflows/workflows-editor/components/piece-form-item.component/select-upstream-input.tsx @@ -3,7 +3,7 @@ import React, { useCallback } from 'react'; import { Controller, useFormContext } from 'react-hook-form'; import { Option } from '../piece-form.component/upstream-options'; import { IWorkflowPieceData } from 'context/workflows/types'; -import fetchFromObject from 'utils/fetch-from-object'; +import { fetchFromObject } from 'utils'; type ObjectName = `inputs.${string}.value.${number}.upstreamValue.${string}` type Name = `inputs.${string}` diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component/index.tsx b/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component/index.tsx index d6d2a692..27271998 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component/index.tsx +++ b/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component/index.tsx @@ -22,7 +22,7 @@ import ContainerResourceForm, { ContainerResourceFormSchema, defaultContainerRes import StorageForm, { defaultStorage, storageFormSchema } from './storage-form.component'; import { IWorkflowPieceData } from 'context/workflows/types'; -import yupResolver from 'utils/validationResolver'; +import { yupResolver } from 'utils'; interface ISidebarPieceFormProps { formId: string, diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-settings-form.component.tsx b/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-settings-form.component.tsx index b20b44e4..adf5ab1d 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-settings-form.component.tsx +++ b/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-settings-form.component.tsx @@ -11,7 +11,7 @@ import { import { useWorkflowsEditor } from 'context/workflows/workflows-editor.context' import { IWorkflowSettings, endDateTypes, scheduleIntervals, storageSources } from 'context/workflows/types/settings'; -import yupResolver from 'utils/validationResolver'; +import { yupResolver } from 'utils'; import TextInput from 'components/text-input'; import SelectInput from 'components/select-input'; diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/workflows-editor.component.tsx b/frontend/src/pages/private/workflows/workflows-editor/components/workflows-editor.component.tsx index 3525ae46..c7ec9046 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/components/workflows-editor.component.tsx +++ b/frontend/src/pages/private/workflows/workflows-editor/components/workflows-editor.component.tsx @@ -18,7 +18,7 @@ import { toast } from "react-toastify" import * as yup from "yup" import { createInputsSchemaValidation } from './piece-form.component/validation'; -import yupResolver from 'utils/validationResolver'; +import { yupResolver } from 'utils'; import { storageFormSchema } from './sidebar-form.component/storage-form.component'; import { ContainerResourceFormSchema } from './sidebar-form.component/container-resource-form.component'; import { IWorkflowElement } from 'services/requests/workflow'; diff --git a/frontend/src/utils/dateUtils.js b/frontend/src/utils/dateUtils.js deleted file mode 100644 index 11f7567a..00000000 --- a/frontend/src/utils/dateUtils.js +++ /dev/null @@ -1,26 +0,0 @@ -export const stringIsDate = (date) => { - return (new Date(date) !== "Invalid Date") && !isNaN(new Date(date)); -} - - -export const formatIsoDatetime = (dateString, dateSeparator = "-", useTime = true, useTimezone = true) => { - var date = dateString.substring(0, 10).replace("-", dateSeparator); - var time = dateString.substring(11, 19) - var timezone = dateString.split("+")[1] - - var outputDate = date - - if (useTime) outputDate = `${outputDate} ${time}` - if (useTimezone) outputDate = `${outputDate} ${timezone}` - - return outputDate - -} - -export const parseIsoDatetime = (dateString, dateSeparator = "-", useTime = true, useTimezone = true) => { - var isDate = stringIsDate(dateString); - if (!isDate) return isDate; - - return formatIsoDatetime(dateString, dateSeparator, useTime, useTimezone) -} - diff --git a/frontend/src/utils/fetch-from-object.ts b/frontend/src/utils/fetch-from-object.ts index 216a48e7..71f9de9e 100644 --- a/frontend/src/utils/fetch-from-object.ts +++ b/frontend/src/utils/fetch-from-object.ts @@ -1,4 +1,4 @@ -function fetchFromObject(obj: any, prop: string): any { +export function fetchFromObject(obj: any, prop: string): any { if (typeof obj === 'undefined') { return; @@ -13,5 +13,3 @@ function fetchFromObject(obj: any, prop: string): any { return obj[prop]; } - -export default fetchFromObject diff --git a/frontend/src/utils/getUuidSlice.ts b/frontend/src/utils/getUuidSlice.ts new file mode 100644 index 00000000..e249d00b --- /dev/null +++ b/frontend/src/utils/getUuidSlice.ts @@ -0,0 +1,9 @@ +type WorkflowPieceID = `${number}_${string}-${string}-${string}-${string}-${string}` | string + +export function getUuidSlice(workflowPieceID: WorkflowPieceID){ + return workflowPieceID.split("_")[1].split("-")[0] +} + +export function getIdSlice(workflowPieceID: WorkflowPieceID){ + return parseInt(workflowPieceID.split("_")[0]) +} diff --git a/frontend/src/utils/index.ts b/frontend/src/utils/index.ts index b5bb18c7..beac8f8a 100644 --- a/frontend/src/utils/index.ts +++ b/frontend/src/utils/index.ts @@ -1,4 +1,5 @@ export { extractDefaultValues } from './jsonSchema' -export { validateForms } from './validator' -export { parseIsoDatetime } from './dateUtils' export { createCustomContext } from './create-custom-context.function' +export { fetchFromObject } from "./fetch-from-object" +export { yupResolver } from "./validationResolver" +export { getIdSlice, getUuidSlice } from "./getUuidSlice" diff --git a/frontend/src/utils/jsonSchema.js b/frontend/src/utils/jsonSchema.ts similarity index 70% rename from frontend/src/utils/jsonSchema.js rename to frontend/src/utils/jsonSchema.ts index aa854ac9..da75255a 100644 --- a/frontend/src/utils/jsonSchema.js +++ b/frontend/src/utils/jsonSchema.ts @@ -1,10 +1,10 @@ // Extract default values from Schema -export const extractDefaultValues = (schema, output = null) => { +export const extractDefaultValues = (schema: any, output: any | null = null) => { output = output === null ? {} : output if (schema) { const properties = schema['properties'] - for (const [key, value] of Object.entries(properties)) { + for (const [key, value] of Object.entries(properties)) { if ('default' in value) { output[key] = value['default'] } else if ('properties' in value) { @@ -14,4 +14,4 @@ export const extractDefaultValues = (schema, output = null) => { } return output -} \ No newline at end of file +} diff --git a/frontend/src/utils/validationResolver.ts b/frontend/src/utils/validationResolver.ts index 9a2f977d..20b2ae67 100644 --- a/frontend/src/utils/validationResolver.ts +++ b/frontend/src/utils/validationResolver.ts @@ -54,7 +54,7 @@ function set( return object; } -export const toNestError = ( +const toNestError = ( errors: FieldErrors, ): FieldErrors => { const fieldErrors = {} as FieldErrors; @@ -69,7 +69,7 @@ export const toNestError = ( return fieldErrors; }; -const yupResolver = ( +export const yupResolver = ( validationSchema: ObjectSchema> ) => async (data: any) => { try { @@ -108,5 +108,3 @@ const yupResolver = ( throw new Error('Error trying to validate form schema'); } } - -export default yupResolver; diff --git a/frontend/src/utils/validator.js b/frontend/src/utils/validator.js deleted file mode 100644 index 13508ebd..00000000 --- a/frontend/src/utils/validator.js +++ /dev/null @@ -1,29 +0,0 @@ -import Ajv from "ajv" - -const ajv = new Ajv() - -const capitalize = (str) => { - return str.charAt(0).toUpperCase() + str.slice(1); -} - -export const validateForms = (schemas, data) => { - - for (const [dataKey, dataValue] of Object.entries(data)) { - var rawKey = dataKey.split('_', 2)[0] - const schema = schemas[rawKey] - const validate = ajv.compile(schema) - const valid = validate(dataValue) - - if (!valid) { - return { - "status": valid, - "message": capitalize(validate.errors[0].message) - } - } - } - return { - "status": true, - "message": "Form valid" - } - -} \ No newline at end of file From 285562bf400da6ae4d46217f45e8177922b50335 Mon Sep 17 00:00:00 2001 From: Nathan Vieira Marcelino Date: Mon, 7 Aug 2023 17:43:17 -0300 Subject: [PATCH 144/328] fix: validator field alias --- rest/schemas/requests/workflow.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/rest/schemas/requests/workflow.py b/rest/schemas/requests/workflow.py index e3a705e9..8efc8c13 100644 --- a/rest/schemas/requests/workflow.py +++ b/rest/schemas/requests/workflow.py @@ -79,6 +79,9 @@ def end_date_validator(cls, v, values): return converted_end_date.isoformat() except ValueError: raise ValueError(f"Invalid end date: {v}") + + class Config: + allow_population_by_field_name = True storage_default_piece_model_map = { @@ -134,7 +137,7 @@ class TasksDataModel(BaseModel): class CreateWorkflowRequest(BaseModel): workflow: WorkflowBaseSettings tasks: Dict[ - str, + str, # str === TasksDataModel['task_id'] TasksDataModel ] ui_schema: UiSchema From 555a2c3188b5b1f5cd1840519aedf9ed29b2056a Mon Sep 17 00:00:00 2001 From: Nathan Vieira Marcelino Date: Mon, 7 Aug 2023 17:53:06 -0300 Subject: [PATCH 145/328] chore: fix type and inputs --- frontend/src/components/datetime-input.tsx | 23 ++++--- frontend/src/context/workflows/types/input.ts | 10 +-- .../src/context/workflows/types/settings.ts | 48 ++++++++------ .../src/context/workflows/types/storage.ts | 10 +-- .../workflows/types/workflow-piece-data.ts | 64 ++++++++++++++++++- .../sidebar-settings-form.component.tsx | 61 ++++++++++++------ 6 files changed, 150 insertions(+), 66 deletions(-) diff --git a/frontend/src/components/datetime-input.tsx b/frontend/src/components/datetime-input.tsx index 4a1950dd..9a5ca334 100644 --- a/frontend/src/components/datetime-input.tsx +++ b/frontend/src/components/datetime-input.tsx @@ -10,20 +10,21 @@ interface Props { label: string name: Path type?: "time" | "date" | "date-time" + defaultValue?: Date } -function DatetimeInput({ label, name, type = "date" }: Props) { +function DatetimeInput({ label, name, type = "date", defaultValue=new Date() }: Props) { const { control } = useFormContext() - const defaultValue = new Date().toISOString() - switch (type) { case "date-time": + const defaultDateTime = dayjs(defaultValue ?? new Date(), 'YYYY-MM-DD HH:mm') + return ( @@ -31,8 +32,8 @@ function DatetimeInput({ label, name, type = "date" }: Pr label={label} ampm={false} format='DD/MM/YYYY HH:mm' - value={dayjs(value as string, 'YYYY-MM-DD HH:mm')} - onChange={(e) => { onChange(dayjs(e).format('YYYY-MM-DD HH:mm') as any) }} + value={dayjs(value)} + onChange={(e) => { onChange(dayjs(e).toISOString() as any) }} {...rest} /> @@ -40,10 +41,12 @@ function DatetimeInput({ label, name, type = "date" }: Pr )} />; case 'time': + const defaultTime = dayjs(defaultValue ?? new Date(), 'HH:mm') + return ( @@ -62,10 +65,12 @@ function DatetimeInput({ label, name, type = "date" }: Pr />; case 'date': default: + const defaultDate = dayjs(defaultValue ?? new Date(), 'YYYY-MM-DD') + return ( @@ -74,7 +79,7 @@ function DatetimeInput({ label, name, type = "date" }: Pr views={['day', 'month', 'year']} format="DD/MM/YYYY" sx={{ width: "100%" }} - value={dayjs(value as string, 'YYYY-MM-DD')} + value={dayjs(value as string)} onChange={(e) => { onChange(dayjs(e).format('YYYY-MM-DD') as any) }} {...rest} /> diff --git a/frontend/src/context/workflows/types/input.ts b/frontend/src/context/workflows/types/input.ts index 53626c35..d48b1829 100644 --- a/frontend/src/context/workflows/types/input.ts +++ b/frontend/src/context/workflows/types/input.ts @@ -1,11 +1,11 @@ import { Dayjs } from "dayjs"; -type Value = string | number | boolean | Dayjs | null +type Value = string | number | boolean | Dayjs interface BaseInput { fromUpstream: boolean, //? allowed | never | always - upstreamArgument: string | null, - upstreamId: string | null, - upstreamValue: string | null, + upstreamArgument: string, + upstreamId: string, + upstreamValue: string, value: Value } @@ -18,7 +18,7 @@ export interface ObjectInput { } export type InputArray = BaseInput & { - value: Record[] | Record[] + value: BaseInput[] | ObjectInput[] } export type Input = BaseInput diff --git a/frontend/src/context/workflows/types/settings.ts b/frontend/src/context/workflows/types/settings.ts index 24819e8e..271d9377 100644 --- a/frontend/src/context/workflows/types/settings.ts +++ b/frontend/src/context/workflows/types/settings.ts @@ -1,40 +1,46 @@ -import { Dayjs } from "dayjs"; - export enum scheduleIntervals { - None = "None", - Once = "Once", - Hourly = "Hourly", - Daily = "Daily", - Weekly = "Weekly", - Monthly = "Monthly", - Yearly = "Yearly", + None = "none", + Once = "once", + Hourly = "hourly", + Daily = "daily", + Weekly = "weekly", + Monthly = "monthly", + Yearly = "yearly", } +export type ScheduleIntervals = `${scheduleIntervals}` + export enum endDateTypes { - Never = "Never", - UserDefined = "UserDefined", + Never = "never", + UserDefined = "User defined", } -export enum storageSources { +export type EndDateTypes = `${endDateTypes}` + +export enum storageSourcesAWS { None = "None", - AWSS3 = "AWSS3", + AWSS3 = "AWS S3", } -export type storageSourceType = keyof typeof storageSources; -export type endDateTypeType = keyof typeof endDateTypes; -export type scheduleIntervalType = keyof typeof scheduleIntervals; +export type StorageSourcesAWS = `${storageSourcesAWS}` + +export enum storageSourcesLocal { + None = "None", + Local = "Local", +} +export type StorageSourcesLocal = `${storageSourcesLocal}` export interface IWorkflowSettingsConfig { name: string, - scheduleInterval: scheduleIntervalType, - startDate: Dayjs | string, - endDate?: Dayjs | string, - endDateType: endDateTypeType, + scheduleInterval: ScheduleIntervals, + startDate: string, + endDate?: string, + endDateType: EndDateTypes, } export interface IWorkflowSettingsStorage { - storageSource: storageSourceType, + storageSource: StorageSourcesAWS | StorageSourcesLocal, baseFolder?: string, bucket?: string } diff --git a/frontend/src/context/workflows/types/storage.ts b/frontend/src/context/workflows/types/storage.ts index a7520c2c..1e465618 100644 --- a/frontend/src/context/workflows/types/storage.ts +++ b/frontend/src/context/workflows/types/storage.ts @@ -3,13 +3,9 @@ export enum storageAccessModes { Read = "Read", ReadWrite = "Read/Write", } - -/** - * This is equivalent to: - * type storageAccessModeType = 'None' | 'Read' | 'Read/Write'; - */ -export type storageAccessModeType = keyof typeof storageAccessModes; +// Equivalent to type StorageAccessModes = "None" | "Read" | "Read/Write" +export type StorageAccessModes = `${storageAccessModes}` export interface IStorageFormData { - storageAccessMode: storageAccessModeType, + storageAccessMode: StorageAccessModes, } diff --git a/frontend/src/context/workflows/types/workflow-piece-data.ts b/frontend/src/context/workflows/types/workflow-piece-data.ts index 6372aa9c..acc7245a 100644 --- a/frontend/src/context/workflows/types/workflow-piece-data.ts +++ b/frontend/src/context/workflows/types/workflow-piece-data.ts @@ -1,10 +1,68 @@ +import { IWorkflowElement } from "services/requests/workflow" import { IContainerResourceFormData } from "./container-resources" import { InputArray, Input } from "./input" -import { IStorageFormData } from "./storage" +import { EndDateTypes, ScheduleIntervals, StorageSourcesAWS, StorageSourcesLocal } from "./settings" +import { IStorageFormData, StorageAccessModes } from "./storage" +import { Edge } from "reactflow" export type IWorkflowPieceData = { - storage:IStorageFormData, + storage: IStorageFormData, containerResources: IContainerResourceFormData, - inputs: Record + inputs: Record } + +interface WorkflowBaseSettings { + name: string + start_date: string // ISOFormat + select_end_date: EndDateTypes + schedule_interval: ScheduleIntervals + + end_date?: string // ISOFormat + catchup?: boolean + generate_report?: boolean + description?: string +} + +interface UiSchema { + nodes: Record + edges: Edge[] +} + +type WorkflowSharedStorageDataModel = { + source: StorageSourcesLocal | StorageSourcesAWS + base_folder?: string + mode: StorageAccessModes + provider_options?: Record +} + + +interface SystemRequirementsModel { + cpu: number + memory: number +} +interface ContainerResourcesDataModel { + requests: SystemRequirementsModel + limits: SystemRequirementsModel + use_gpu: boolean +} + +export interface TasksDataModel { + workflow_shared_storage: WorkflowSharedStorageDataModel + container_resources: ContainerResourcesDataModel + task_id: string + piece: { + id: number + name: string + } + piece_input_kwargs: Record + dependencies?: string[] +} + +type TasksDict = Record + +export type CreateWorkflowRequest = { + workflow: WorkflowBaseSettings, + tasks: TasksDict, + ui_schema: UiSchema, +} diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-settings-form.component.tsx b/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-settings-form.component.tsx index adf5ab1d..5dfd5e1a 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-settings-form.component.tsx +++ b/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-settings-form.component.tsx @@ -9,13 +9,14 @@ import { } from '@mui/material' import { useWorkflowsEditor } from 'context/workflows/workflows-editor.context' -import { IWorkflowSettings, endDateTypes, scheduleIntervals, storageSources } from 'context/workflows/types/settings'; +import { EndDateTypes, IWorkflowSettings, ScheduleIntervals, StorageSourcesAWS, StorageSourcesLocal, endDateTypes, scheduleIntervals, storageSourcesAWS, storageSourcesLocal } from 'context/workflows/types/settings'; import { yupResolver } from 'utils'; import TextInput from 'components/text-input'; import SelectInput from 'components/select-input'; import DatetimeInput from 'components/datetime-input'; +import dayjs from 'dayjs'; interface ISidebarSettingsFormProps { open: boolean, @@ -25,13 +26,12 @@ interface ISidebarSettingsFormProps { const defaultSettingsData: IWorkflowSettings = { config: { name: '', - scheduleInterval: "None", - startDate: "", - endDate: "", - endDateType: "Never", + scheduleInterval: scheduleIntervals.None, + startDate: dayjs(new Date()).toISOString(), + endDateType: endDateTypes.Never, }, storage: { - storageSource: "None", + storageSource: storageSourcesLocal.None, baseFolder: '', bucket: '' } @@ -62,14 +62,27 @@ type ValidationSchema = yup.ObjectSchema // TODO check yup validation export const WorkflowSettingsFormSchema: ValidationSchema = yup.object().shape({ config: yup.object().shape({ - name: yup.string().required(), - scheduleInterval: yup.mixed().oneOf(Object.values(scheduleIntervals)).required(), + name: yup.string().matches(/^[\w]*$/, 'Name can only have letters and numbers.').required(), + scheduleInterval: yup + .mixed() + .oneOf(Object.values(scheduleIntervals)) + .required(), startDate: yup.string().required(), endDate: yup.string(), - endDateType: yup.mixed().oneOf(Object.values(endDateTypes)).required(), + endDateType: yup + .mixed() + .oneOf(Object.values(endDateTypes)) + .required(), }), storage: yup.object().shape({ - storageSource: yup.mixed().oneOf(Object.values(storageSources)).required(), + storageSource: yup.lazy( + value => { + if (value === storageSourcesAWS.AWSS3) { + return yup.mixed().oneOf(Object.values(storageSourcesAWS)).required() + } + return yup.mixed().oneOf(Object.values(storageSourcesLocal)).required() + } + ), baseFolder: yup.string(), bucket: yup.string() }) @@ -89,7 +102,7 @@ const SidebarSettingsForm = (props: ISidebarSettingsFormProps) => { const resolver = yupResolver(WorkflowSettingsFormSchema); const methods = useForm({ mode: "onChange", resolver }) - const { register, watch, reset, trigger } = methods + const { register, watch, reset, trigger, getValues } = methods const formData = watch() const [loaded, setLoaded] = useState(false) @@ -113,7 +126,6 @@ const SidebarSettingsForm = (props: ISidebarSettingsFormProps) => { const saveData = useCallback(async () => { if (open) { - console.log(formData) await setWorkflowSettingsData(formData) } }, [formData, open, setWorkflowSettingsData]) @@ -170,7 +182,12 @@ const SidebarSettingsForm = (props: ISidebarSettingsFormProps) => { type='date-time' />
- + { defaultValue={defaultSettingsData.config.endDateType} /> - - - + {getValues().config.endDateType === endDateTypes.UserDefined && + + + + } @@ -205,7 +224,7 @@ const SidebarSettingsForm = (props: ISidebarSettingsFormProps) => { />
{ - formData.storage.storageSource === 'AWSS3' ? ( + formData.storage.storageSource === storageSourcesAWS.AWSS3 ? ( <> Date: Mon, 7 Aug 2023 17:53:27 -0300 Subject: [PATCH 146/328] chore: add error style on node --- .../workflows-editor/components/custom-node.component.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/custom-node.component.tsx b/frontend/src/pages/private/workflows/workflows-editor/components/custom-node.component.tsx index 9e29b2b6..f1f70605 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/components/custom-node.component.tsx +++ b/frontend/src/pages/private/workflows/workflows-editor/components/custom-node.component.tsx @@ -88,7 +88,7 @@ const CustomNode = memo((data: any) => { if(extendedData?.error){ console.log("erro no node", extendedData) - customStyle = Object.assign(customStyle, {backgroundColor:"red"}) + customStyle = Object.assign(customStyle, {backgroundColor:"#f44336",color:"#e6e6e6"}) } From 696442fc20f6bf3dc9de0ded483319b5e7d12829 Mon Sep 17 00:00:00 2001 From: Nathan Vieira Marcelino Date: Mon, 7 Aug 2023 17:54:50 -0300 Subject: [PATCH 147/328] refactor: improve forms --- .../piece-form.component/validation.ts | 4 +-- .../container-resource-form.component.tsx | 31 ++++++++++++++++--- .../storage-form.component.tsx | 10 +++--- 3 files changed, 34 insertions(+), 11 deletions(-) diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/piece-form.component/validation.ts b/frontend/src/pages/private/workflows/workflows-editor/components/piece-form.component/validation.ts index 758ce0cf..7e7a3fe6 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/components/piece-form.component/validation.ts +++ b/frontend/src/pages/private/workflows/workflows-editor/components/piece-form.component/validation.ts @@ -75,7 +75,7 @@ function getValidationValueBySchemaType(schema: any) { if (fromUpstream) { return yup.mixed().notRequired() } - return yup.number().required() + return yup.number().typeError('Must must be a number').required() }) } } @@ -86,7 +86,7 @@ function getValidationValueBySchemaType(schema: any) { if (fromUpstream) { return yup.mixed().notRequired() } - return yup.number().integer().required() + return yup.number().integer().typeError('Must must be a number').required() }) } } diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component/container-resource-form.component.tsx b/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component/container-resource-form.component.tsx index f9aef117..0298f66a 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component/container-resource-form.component.tsx +++ b/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component/container-resource-form.component.tsx @@ -30,12 +30,35 @@ export const defaultContainerResources: IContainerResourceFormData = { export const ContainerResourceFormSchema: yup.ObjectSchema = yup.object().shape({ cpu: yup.object().shape({ - min: yup.number().integer().max(maxAcceptedCpu).min(minAcceptedCpu).required(), - max: yup.number().integer().max(maxAcceptedCpu).when("min",([min],schema)=>schema.min(min)).required() + min: yup + .number() + .integer() + .typeError('Must must be a number') + .max(maxAcceptedCpu) + .min(minAcceptedCpu) + .required(), + max: yup + .number() + .integer() + .typeError('Must be a number') + .max(maxAcceptedCpu) + .when("min",([min],schema)=>schema.min(min)) + .required() }), memory: yup.object().shape({ - min: yup.number().integer().max(maxAcceptedMemory).min(minAcceptedMemory).required(), - max: yup.number().integer().max(maxAcceptedMemory).when("min",([min],schema)=>schema.min(min)).required() + min: yup + .number() + .integer() + .max(maxAcceptedMemory) + .min(minAcceptedMemory) + .required(), + max: yup + .number() + .integer() + .typeError('Must be a number') + .max(maxAcceptedMemory) + .when("min",([min],schema)=>schema.min(min)) + .required() }), useGpu: yup.boolean().required(), }); diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component/storage-form.component.tsx b/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component/storage-form.component.tsx index 9c1c641a..6dc4effe 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component/storage-form.component.tsx +++ b/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component/storage-form.component.tsx @@ -2,14 +2,14 @@ import React from 'react'; import { Controller, useFormContext } from 'react-hook-form'; import * as yup from 'yup' import { FormControl, FormHelperText, Grid, InputLabel, MenuItem, Select, Typography } from '@mui/material'; -import { IStorageFormData, IWorkflowPieceData, storageAccessModeType, storageAccessModes } from 'context/workflows/types'; +import { IStorageFormData, IWorkflowPieceData, StorageAccessModes, storageAccessModes } from 'context/workflows/types'; export const storageFormSchema = yup.object().shape({ - storageAccessMode: yup.mixed().oneOf(Object.values(storageAccessModes)).required(), + storageAccessMode: yup.mixed().oneOf(Object.values(storageAccessModes)).required(), }); export const defaultStorage: IStorageFormData = { - storageAccessMode: storageAccessModes.None as storageAccessModeType + storageAccessMode: storageAccessModes.None } const StorageForm: React.FC = () => { @@ -26,12 +26,12 @@ const StorageForm: React.FC = () => { ( - {emptyValue && - None - } - {options.map((option) => { - if (typeof option === "object") { - return ( - - {option.label} - - ) - } - return ( - - {option} - - ) - })} - + ( + + )} + /> + {error?.message} diff --git a/frontend/src/context/workflows/workflows-editor.context/index.tsx b/frontend/src/context/workflows/workflows-editor.context/index.tsx index 5c8bec62..34414898 100644 --- a/frontend/src/context/workflows/workflows-editor.context/index.tsx +++ b/frontend/src/context/workflows/workflows-editor.context/index.tsx @@ -60,8 +60,9 @@ export const WorkflowsEditorProvider: FC<{ children?: React.ReactNode }> = ({ ch } = useWorkflowsNodes() const { - fetchWorkflowPieceById, setForageWorkflowPieces, + setForageWorkflowPiecesOutputSchema, + fetchWorkflowPieceById, getForageWorkflowPieces, removeForageWorkflowPiecesById, clearForageWorkflowPieces, @@ -389,6 +390,7 @@ export const WorkflowsEditorProvider: FC<{ children?: React.ReactNode }> = ({ ch fetchForageWorkflowPiecesData, fetchForageWorkflowPiecesDataById, setForageWorkflowPiecesData, + setForageWorkflowPiecesOutputSchema, clearForageData, clearForageWorkflowPiecesData, diff --git a/frontend/src/context/workflows/workflows-editor.context/workflow-pieces.context.tsx b/frontend/src/context/workflows/workflows-editor.context/workflow-pieces.context.tsx index b7d43e16..a3bf502b 100644 --- a/frontend/src/context/workflows/workflows-editor.context/workflow-pieces.context.tsx +++ b/frontend/src/context/workflows/workflows-editor.context/workflow-pieces.context.tsx @@ -5,10 +5,11 @@ import { createCustomContext } from 'utils'; export interface IWorkflowPieceContext { setForageWorkflowPieces: (workflowPieces: any) => Promise // TODO add type - getForageWorkflowPieces: () => Promise // TODO add type + getForageWorkflowPieces: () => Promise> // TODO add type removeForageWorkflowPiecesById: (id: string) => Promise fetchWorkflowPieceById: (id: string) => Promise // TODO add type clearForageWorkflowPieces: () => Promise + setForageWorkflowPiecesOutputSchema: (id: string, properties: any) => Promise } export const [WorkflowPiecesContext, useWorkflowPiece] = @@ -20,6 +21,14 @@ const WorkflowPiecesProvider: React.FC<{ children: React.ReactNode }> = ({ child await localForage.setItem('workflowPieces', workflowPieces) }, []) + const setForageWorkflowPiecesOutputSchema = useCallback(async (id: any, properties: any) => { + const workflowPieces = await localForage.getItem("workflowPieces") + if (workflowPieces?.[id]) { + workflowPieces[id].output_schema.properties = properties + localForage.setItem('workflowPieces', workflowPieces) + } + }, []) + const clearForageWorkflowPieces = useCallback(async () => { await localForage.setItem('workflowPieces', {}) }, []) @@ -54,6 +63,7 @@ const WorkflowPiecesProvider: React.FC<{ children: React.ReactNode }> = ({ child removeForageWorkflowPiecesById, setForageWorkflowPieces, clearForageWorkflowPieces, + setForageWorkflowPiecesOutputSchema, } return ( @@ -63,4 +73,4 @@ const WorkflowPiecesProvider: React.FC<{ children: React.ReactNode }> = ({ child ); } -export default WorkflowPiecesProvider; \ No newline at end of file +export default WorkflowPiecesProvider; diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component/index.tsx b/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component/index.tsx index 948094b2..447c0c61 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component/index.tsx +++ b/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component/index.tsx @@ -62,7 +62,7 @@ const SidebarPieceForm: React.FC = (props) => { const resolver = yupResolver(SidebarPieceFormSchema); const methods = useForm({ - defaultValues, + defaultValues: async ()=>fetchForageWorkflowPiecesDataById(formId), resolver, mode: "onChange" }) diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component/piece-form.component/index.tsx b/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component/piece-form.component/index.tsx index d212d343..288aa0ac 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component/piece-form.component/index.tsx +++ b/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component/piece-form.component/index.tsx @@ -44,6 +44,7 @@ const PieceForm: React.FC = ({ formId, schema }) => { Object.keys(schema.properties).map(key => (
@@ -26,15 +29,17 @@ interface ArrayInputItemProps { upstreamOptions: ArrayOption } -const ArrayInput: React.FC = ({ inputKey, schema, upstreamOptions, definitions, control }) => { +const ArrayInput: React.FC = ({ formId, inputKey, schema, upstreamOptions, definitions, control }) => { + const name = `inputs.${inputKey}.value` as `inputs.${string}.value` const { fields: data, append, remove } = useFieldArray({ name, control, }) - const { watch } = useFormContext() - const formsData = watch() const fields = data as unknown as FieldArrayWithId[] + const formsData = useWatch({ name }) + + const { setForageWorkflowPiecesOutputSchema } = useWorkflowsEditor() const [enumOptions, setEnumOptions] = useState([]) @@ -47,23 +52,11 @@ const ArrayInput: React.FC = ({ inputKey, schema, upstreamO return subItemSchema }, [definitions, schema]) - const [checkedFromUpstreamDefault, checkedFromUpstreamEditable] = useMemo(() => { - // from_upstream condition, if "never" or "always" - let defaultChecked: boolean = true; - let editable: boolean = true; - if (subItemSchema?.from_upstream === "never") { - defaultChecked = false; - editable = false; - } else if (subItemSchema?.from_upstream === "always") { - defaultChecked = true; - editable = false; - } - return [defaultChecked, editable] - }, [subItemSchema]) + const [checkedUpstream, disableUpstream] = useUpstreamCheckboxOptions(subItemSchema, upstreamOptions) const getFromUpstream = useCallback((index: number) => { - return formsData?.inputs?.[inputKey]?.value?.[index]?.fromUpstream ?? false - }, [formsData?.inputs, inputKey]) + return formsData?.[index]?.fromUpstream ?? false + }, [formsData]) const elementType = useMemo(() => { if (subItemSchema?.allOf && subItemSchema.allOf.length > 0) { @@ -109,6 +102,50 @@ const ArrayInput: React.FC = ({ inputKey, schema, upstreamO append(defaultValue as any) }, [append]) + const updateOutputSchema = useCallback(async () => { + if (schema?.items?.["$ref"] === '#/definitions/OutputModifierModel' && formsData) { + const newProperties = formsData.reduce((acc: any, cur: { value: { type: string; name: string; description: any; }; }) => { + let defaultValue: any = "" + let newProperties = {} + + if (cur.value.type === "integer") { + defaultValue = 1 + } else if (cur.value.type === "float") { + defaultValue = 1.1 + } else if (cur.value.type === "boolean") { + defaultValue = false + } + + if (cur.value.type === "array") { + newProperties = { + [cur.value.name as string]: { + items: { + type: "string" + }, + description: cur.value.description, + title: cur.value.name, + type: cur.value.type, + } + } + } else { + newProperties = { + [cur.value.name as string]: { + default: defaultValue, + description: cur.value.description, + title: cur.value.name, + type: cur.value.type, + } + } + } + return { ...acc, ...newProperties } + }, {}) + + await setForageWorkflowPiecesOutputSchema(formId, newProperties) + } + }, [formsData, schema?.items, setForageWorkflowPiecesOutputSchema, formId]) + + useEffect(() => { updateOutputSchema() }, [updateOutputSchema]) + return (
@@ -281,8 +318,8 @@ const ArrayInput: React.FC = ({ inputKey, schema, upstreamO )} @@ -294,8 +331,8 @@ const ArrayInput: React.FC = ({ inputKey, schema, upstreamO schema={schema} definitions={definitions} upstreamOptions={upstreamOptions.items} - checkedFromUpstreamDefault={checkedFromUpstreamDefault} - checkedFromUpstreamEditable={checkedFromUpstreamEditable} + checkedFromUpstreamDefault={checkedUpstream} + checkedFromUpstreamEditable={disableUpstream} /> )} diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component/piece-form.component/piece-form-item.component/index.tsx b/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component/piece-form.component/piece-form-item.component/index.tsx index 26829332..54106ea7 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component/piece-form.component/piece-form-item.component/index.tsx +++ b/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component/piece-form.component/piece-form-item.component/index.tsx @@ -3,7 +3,7 @@ import { Box, Grid, } from '@mui/material'; -import { Control, useFormContext } from 'react-hook-form'; +import { Control, useFormContext, useWatch } from 'react-hook-form'; import { IWorkflowPieceData } from 'context/workflows/types'; @@ -18,8 +18,10 @@ import SelectUpstreamInput from './select-upstream-input'; import ArrayInput from './array-input'; import { ArrayOption, Option } from '../../piece-form.component/upstream-options'; +import { useUpstreamCheckboxOptions } from './useUpstreamCheckboxOptions'; interface PieceFormItemProps { + formId: string schema: any; itemKey: string; control: Control @@ -27,38 +29,10 @@ interface PieceFormItemProps { upstreamOptions: Option[] | ArrayOption } -const PieceFormItem: React.FC = ({ upstreamOptions, itemKey, schema, definitions, control }) => { - const [checkedFromUpstreamDefault, checkedFromUpstreamEditable] = useMemo(() => { - // from_upstream condition, if "never" or "always" - let defaultChecked: boolean = true; - let editable: boolean = true; - if (schema?.from_upstream === "never") { - defaultChecked = false; - editable = false; - } else if (schema?.from_upstream === "always") { - defaultChecked = true; - editable = false; - } - - if (schema?.allOf && schema.allOf.length > 0) { - defaultChecked = true; - editable = false; - } - - if (!(upstreamOptions as Option[])?.length) { - editable = false; - } - - if ((upstreamOptions as ArrayOption)?.array?.length) { - editable = true; - } - - return [defaultChecked, editable] - }, [schema, upstreamOptions]) +const PieceFormItem: React.FC = ({formId, upstreamOptions, itemKey, schema, definitions, control }) => { + const [checkedUpstream, disableUpstream] = useUpstreamCheckboxOptions(schema,upstreamOptions) - const { watch } = useFormContext() - const data = watch() - const checkedFromUpstream = data.inputs[itemKey]?.fromUpstream + const checkedFromUpstream = useWatch({name:`inputs.${itemKey}.fromUpstream`}) let inputElement: React.ReactNode = null @@ -110,6 +84,7 @@ const PieceFormItem: React.FC = ({ upstreamOptions, itemKey, } else if (schema.type === 'array') { inputElement = = ({ upstreamOptions, itemKey, diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component/piece-form.component/piece-form-item.component/object-input.tsx b/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component/piece-form.component/piece-form-item.component/object-input.tsx index f4a2be65..36165d1b 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component/piece-form.component/piece-form-item.component/object-input.tsx +++ b/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component/piece-form.component/piece-form-item.component/object-input.tsx @@ -1,4 +1,4 @@ -import React, { useCallback, useEffect, useMemo } from 'react'; +import React, { useCallback, useEffect, useMemo, useState } from 'react'; import { useWatch } from 'react-hook-form'; import { Grid } from '@mui/material'; @@ -7,6 +7,8 @@ import CheckboxInput from 'components/checkbox-input'; import SelectUpstreamInput from './select-upstream-input'; import { Option } from '../../piece-form.component/upstream-options'; +import { useUpstreamCheckboxOptions } from './useUpstreamCheckboxOptions'; +import SelectInput from 'components/select-input'; interface Prop { name: `inputs.${string}.value.${number}` @@ -17,8 +19,11 @@ interface Prop { checkedFromUpstreamEditable: boolean } -const ObjectInputComponent: React.FC = ({ schema, name, upstreamOptions, checkedFromUpstreamDefault, checkedFromUpstreamEditable,definitions }) => { +const ObjectInputComponent: React.FC = ({ schema, name, upstreamOptions, definitions }) => { const formsData = useWatch({ name }) + const [checkedUpstream, disableUpstream] = useUpstreamCheckboxOptions(schema, upstreamOptions) + + const [enumOptions, setEnumOptions] = useState([]) const getFromUpstream = useCallback((key: string) => { return (formsData?.fromUpstream[key] ?? false) as boolean @@ -30,13 +35,24 @@ const ObjectInputComponent: React.FC = ({ schema, name, upstreamOptions, c return (defaultValues ?? {}) as Record }, [schema]) - // useEffect(()=>{ - // if(schema.items["$ref"] === "#/definitions/OutputModifierModel"){ - // console.log("Aqui") - // // Alterar o output_schema - // } - // // Não fazer nada - // },[schema,definitions]) + const elementType = useMemo(() => { + const getElementType = function (key: string) { + if (schema?.items?.["$ref"] === '#/definitions/OutputModifierModel' && key === "type") { + const valuesOptions: Array = definitions?.["OutputModifierItemType"].enum; + setEnumOptions(valuesOptions) + return "SelectInput" + } else { + return "TextInput"; + } + } + + return Object.keys(defaultValues).reduce>((acc, cur) => { + acc[cur] = getElementType(cur) + return acc + }, {}) + + }, [schema?.items, defaultValues, definitions]) + return ( <> @@ -50,7 +66,7 @@ const ObjectInputComponent: React.FC = ({ schema, name, upstreamOptions, c direction="row" alignItems="center" justifyContent="space-between" - sx={{marginBottom:1}} + sx={{ marginBottom: 1 }} > {fromUpstream ? @@ -63,11 +79,20 @@ const ObjectInputComponent: React.FC = ({ schema, name, upstreamOptions, c : - + {elementType[key] === 'TextInput' && + + } + {elementType[key] === 'SelectInput' && + + } } = ({ schema, name, upstreamOptions, c > diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component/piece-form.component/piece-form-item.component/select-upstream-input.tsx b/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component/piece-form.component/piece-form-item.component/select-upstream-input.tsx index 18f7b116..94a46cd6 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component/piece-form.component/piece-form-item.component/select-upstream-input.tsx +++ b/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component/piece-form.component/piece-form-item.component/select-upstream-input.tsx @@ -46,7 +46,7 @@ const SelectUpstreamInput: React.FC = ({ options, label, name, object }) return ( - {label} + {label} = ({ options, label, name, object }) field.onChange(e.target.value as any)} diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component/index.tsx b/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component/index.tsx index 8256544c..cac0062f 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component/index.tsx +++ b/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component/index.tsx @@ -1,4 +1,4 @@ -import React, { useCallback, useEffect, useMemo } from 'react' +import React, { useCallback, useEffect, useMemo, useState } from 'react' import { Drawer, Grid, @@ -54,8 +54,10 @@ const SidebarPieceForm: React.FC = (props) => { }, [schema]) const resolver = yupResolver(SidebarPieceFormSchema); + + const [formLoaded, setFormLoaded] = useState(false) + const methods = useForm({ - defaultValues: async ()=>fetchForageWorkflowPiecesDataById(formId), resolver, mode: "onChange" }) @@ -63,14 +65,16 @@ const SidebarPieceForm: React.FC = (props) => { const data = methods.watch() const loadData = useCallback(async () => { + setFormLoaded(false) const data = await fetchForageWorkflowPiecesDataById(formId) - if(data){ + if (data) { reset(data) // put forage data on form if exist } else { reset() } trigger() - }, [formId,fetchForageWorkflowPiecesDataById, reset, trigger]) + setFormLoaded(true) + }, [formId, fetchForageWorkflowPiecesDataById, reset, trigger]) const saveData = useCallback(async () => { if (formId && open) { @@ -85,7 +89,7 @@ const SidebarPieceForm: React.FC = (props) => { } else { reset() } - }, [open,reset,loadData]) + }, [open, reset, loadData]) // save on forage useEffect(() => { @@ -123,37 +127,38 @@ const SidebarPieceForm: React.FC = (props) => { - - - - + {formLoaded && + + + + + + +
+ + + }> + + Advanced Options + + + + +
+ + + - -
- - - }> - - Advanced Options - - - - -
- - - - - - + + }
diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component/piece-form.component/piece-form-item.component/index.tsx b/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component/piece-form.component/piece-form-item.component/index.tsx index 32fd7658..d9c2f9a1 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component/piece-form.component/piece-form-item.component/index.tsx +++ b/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component/piece-form.component/piece-form-item.component/index.tsx @@ -62,7 +62,6 @@ const PieceFormItem: React.FC = ({ formId, upstreamOptions, label={itemKey} emptyValue - defaultValue={schema?.default} name={`inputs.${itemKey}.value`} options={enumOptions} /> From 86dd930833baaed7d9562f8845a2b0f3d84568a0 Mon Sep 17 00:00:00 2001 From: Nathan Vieira Marcelino Date: Mon, 28 Aug 2023 12:20:36 -0300 Subject: [PATCH 169/328] fix: OutputArg type downstreams --- frontend/src/@types/global.d.ts | 24 ++--- frontend/src/@types/properties.d.ts | 16 ++-- frontend/src/components/checkbox-input.tsx | 6 +- frontend/src/components/select-input.tsx | 16 +++- .../container-resource-form.component.tsx | 1 - .../sidebar-form.component/index.tsx | 60 ++++++++++++- .../piece-form-item.component/array-input.tsx | 58 +------------ ...xOptions.tsx => disableCheckboxOptions.ts} | 17 ++-- .../piece-form-item.component/index.tsx | 39 ++++++--- .../object-input.tsx | 30 ++++--- .../select-upstream-input.tsx | 11 ++- .../piece-form.component/upstream-options.ts | 2 +- .../workflow-editor-panel.component.tsx | 86 +++--------------- frontend/src/utils/getDefinition.ts | 13 +++ frontend/src/utils/getFromUpstream.ts | 53 +++++++++++ frontend/src/utils/index.ts | 4 +- frontend/src/utils/jsonSchema.ts | 87 ++++++++++++++++++- 17 files changed, 315 insertions(+), 208 deletions(-) rename frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component/piece-form.component/piece-form-item.component/{useUpstreamCheckboxOptions.tsx => disableCheckboxOptions.ts} (53%) create mode 100644 frontend/src/utils/getDefinition.ts create mode 100644 frontend/src/utils/getFromUpstream.ts diff --git a/frontend/src/@types/global.d.ts b/frontend/src/@types/global.d.ts index d33a2dee..f05ffa10 100644 --- a/frontend/src/@types/global.d.ts +++ b/frontend/src/@types/global.d.ts @@ -1,35 +1,29 @@ import { CSSProperties } from "react" -export { }; +export {}; declare global { - type InputSchemaProperties = import("./properties").InputSchemaProperties; type InputSchemaProperty = import("./properties").InputSchemaProperty; type ArrayObjectProperty = import("./properties").ArrayObjectProperty; - type SimpleInputSchemaProperties = import("./properties").SimpleInputSchemaProperties; type SimpleInputSchemaProperty = import("./properties").SimpleInputSchemaProperty; type FromUpstream = import("./properties").FromUpstream; - type ObjectDefinition = { - type: "object" - + type EnumDefinition = { title: string description: string - - properties: SimpleInputSchemaProperties - } - - type EnumDefinition = { type: "string" + enum: Array + } + type ObjectDefinition = { title: string description: string - - enum: Array + type: "object" + properties: Record } - type Definition = ObjectDefinition | EnumDefinition + type Definition = EnumDefinition | ObjectDefinition type Definitions = Record @@ -39,7 +33,7 @@ declare global { type: "object" - properties: InputSchemaProperties + properties: Record definitions: Definitions } diff --git a/frontend/src/@types/properties.d.ts b/frontend/src/@types/properties.d.ts index 790ef7ee..4f3df1b1 100644 --- a/frontend/src/@types/properties.d.ts +++ b/frontend/src/@types/properties.d.ts @@ -12,7 +12,7 @@ type BooleanProperty = DefaultPropertyProps & { default: boolean } type NumberProperty = DefaultPropertyProps & { - type: "number" | "integer" + type: "number" | "integer" | "float" default: number exclusiveMaximum?: number exclusiveMinimum?: number @@ -29,13 +29,6 @@ type EnumProperty = DefaultPropertyProps & { default: string } -export type SimpleInputSchemaProperty = - | BooleanProperty - | NumberProperty - | StringProperty - | EnumProperty - -export type SimpleInputSchemaProperties = Record type ArrayStringProperty = DefaultPropertyProps & { type: "array" @@ -70,10 +63,15 @@ type ArrayObjectProperty = DefaultPropertyProps & { items: Reference } +export type SimpleInputSchemaProperty = + | BooleanProperty + | NumberProperty + | StringProperty + | EnumProperty + export type InputSchemaProperty = SimpleInputSchemaProperty | ArrayStringProperty | ArrayNumberProperty | ArrayBooleanProperty | ArrayObjectProperty -export type InputSchemaProperties = Record diff --git a/frontend/src/components/checkbox-input.tsx b/frontend/src/components/checkbox-input.tsx index 63edcf6c..301ae12b 100644 --- a/frontend/src/components/checkbox-input.tsx +++ b/frontend/src/components/checkbox-input.tsx @@ -6,11 +6,10 @@ import { fetchFromObject } from 'utils'; interface Props { name: Path label?: string - defaultChecked?: boolean disabled?: boolean } -function CheckboxInput({ label, name, defaultChecked = false, disabled = false }: Props) { +function CheckboxInput({ label, name, disabled = false }: Props) { const { control, formState: { errors } } = useFormContext() const error = fetchFromObject(errors, name) @@ -30,7 +29,6 @@ function CheckboxInput({ label, name, defaultChecked = fa {...field} checked={!!field.value} disabled={disabled} - defaultChecked={defaultChecked} /> )} />} @@ -39,13 +37,11 @@ function CheckboxInput({ label, name, defaultChecked = fa ( )} /> diff --git a/frontend/src/components/select-input.tsx b/frontend/src/components/select-input.tsx index a1b11b62..eeeaf952 100644 --- a/frontend/src/components/select-input.tsx +++ b/frontend/src/components/select-input.tsx @@ -27,7 +27,7 @@ function SelectInput({ options, label, name, emptyValue, return ( - {label} + {label} ({ options, label, name, emptyValue, )} /> - - {error?.message} - - ); + {error?.message} + + ); } export default SelectInput; diff --git a/frontend/src/components/text-input.tsx b/frontend/src/components/text-input.tsx index 0ab8ae96..02d96b0c 100644 --- a/frontend/src/components/text-input.tsx +++ b/frontend/src/components/text-input.tsx @@ -1,19 +1,33 @@ -import React from 'react'; -import { TextField, TextFieldProps } from '@mui/material'; -import { FieldValues, Path, RegisterOptions, useFormContext } from 'react-hook-form'; -import { fetchFromObject } from 'utils'; +import { TextField, type TextFieldProps } from "@mui/material"; +import React from "react"; +import { + type FieldValues, + type Path, + type RegisterOptions, + useFormContext, +} from "react-hook-form"; +import { fetchFromObject } from "utils"; type Props = TextFieldProps & { - label: string - name: Path - defaultValue?: string - registerOptions?: RegisterOptions -} + label: string; + name: Path; + defaultValue?: string; + registerOptions?: RegisterOptions; +}; -function TextInput({ name, label, defaultValue = "",registerOptions, ...rest }:Props) { - const { register, formState:{errors} } = useFormContext() +function TextInput({ + name, + label, + defaultValue = "", + registerOptions, + ...rest +}: Props) { + const { + register, + formState: { errors }, + } = useFormContext(); - const error = fetchFromObject(errors,name) + const error = fetchFromObject(errors, name); return ( ({ name, label, defaultValue = "",regis error={!!error?.message} helperText={error?.message} {...rest} - {...register(name,registerOptions)} - />); + {...register(name, registerOptions)} + /> + ); } export default TextInput; diff --git a/frontend/src/constants/index.ts b/frontend/src/constants/index.ts index be40b75c..be5488ef 100644 --- a/frontend/src/constants/index.ts +++ b/frontend/src/constants/index.ts @@ -1,32 +1,27 @@ -export const workflowFormName: string = 'workflowForm' - export const taskStatesColorMap = { - 'success': '#02b120', - 'failed': '#ff0000', - 'upstream_failed': '#ff6600', - 'running': '#00bfff', - 'skipped': '#ffcc00', - 'up_for_retry': '#ffcc00', - 'up_for_reschedule': '#7b00b4', - 'queued': '#aaaaaa', - 'scheduled': '#00ffaa', - 'none': '#ffffff', - 'deferred': '#00ffaa', - 'removed': '#000000', - 'restarting': '#8ee7fd', - 'default': '#ffffff' -} + success: "#02b120", + failed: "#ff0000", + upstream_failed: "#ff6600", + running: "#00bfff", + skipped: "#ffcc00", + up_for_retry: "#ffcc00", + up_for_reschedule: "#7b00b4", + queued: "#aaaaaa", + scheduled: "#00ffaa", + none: "#ffffff", + deferred: "#00ffaa", + removed: "#000000", + restarting: "#8ee7fd", + default: "#ffffff", +}; export const storageOptions = [ - { - "name": "None", - "fields": [] - }, - { - "name": "AWS s3", - "fields": [ - "AWS Access Key ID", - - ] - } -] \ No newline at end of file + { + name: "None", + fields: [], + }, + { + name: "AWS s3", + fields: ["AWS Access Key ID"], + }, +]; diff --git a/frontend/src/context/authentication/authentication.context.tsx b/frontend/src/context/authentication/authentication.context.tsx index 2b42d7ff..73dd1604 100644 --- a/frontend/src/context/authentication/authentication.context.tsx +++ b/frontend/src/context/authentication/authentication.context.tsx @@ -1,122 +1,123 @@ +import { AxiosError } from "axios"; +import localforage from "localforage"; import React, { - ReactNode, + type ReactNode, useCallback, useEffect, useMemo, useRef, - useState -} from 'react' -import { useNavigate } from 'react-router-dom' -import { toast } from 'react-toastify' -import localforage from 'localforage' - -import { createCustomContext } from 'utils' + useState, +} from "react"; +import { useNavigate } from "react-router-dom"; +import { toast } from "react-toastify"; import { postAuthLogin, - postAuthRegister -} from 'services/requests/authentication' + postAuthRegister, +} from "services/requests/authentication"; +import { createCustomContext } from "utils"; import { - IAuthenticationContext, - IAuthenticationStore -} from './authentication.interface' -import { DOMINO_LOGOUT } from './authentication.logout' -import { AxiosError } from 'axios' - + type IAuthenticationContext, + type IAuthenticationStore, +} from "./authentication.interface"; +import { DOMINO_LOGOUT } from "./authentication.logout"; export const [AuthenticationContext, useAuthentication] = - createCustomContext('Authentication Context') + createCustomContext("Authentication Context"); /** * Authentication provider. * @todo refactor local storage implementation with Local Forage */ export const AuthenticationProvider: React.FC<{ children: ReactNode }> = ({ - children + children, }) => { - const navigate = useNavigate() - const [authLoading, setAuthLoading] = useState(false) + const navigate = useNavigate(); + const [authLoading, setAuthLoading] = useState(false); const [store, setStore] = useState({ - token: localStorage.getItem('auth_token'), - userId: localStorage.getItem('userId') - }) + token: localStorage.getItem("auth_token"), + userId: localStorage.getItem("userId"), + }); - const isLogged = useRef(!!store.token) + const isLogged = useRef(!!store.token); const login = useCallback( - (token: string, userId: string, redirect = '') => { - isLogged.current = true + (token: string, userId: string, redirect = "") => { + isLogged.current = true; setStore((store) => ({ ...store, token, - userId - })) - localStorage.setItem('auth_token', token) - localStorage.setItem('userId', userId as string) - navigate(redirect) + userId, + })); + localStorage.setItem("auth_token", token); + localStorage.setItem("userId", userId); + navigate(redirect); }, - [navigate] - ) + [navigate], + ); const logout = useCallback(() => { - localStorage.clear() - localforage.clear() - isLogged.current = false + localStorage.clear(); + void localforage.clear(); + isLogged.current = false; setStore((store) => ({ ...store, - token: null - })) - navigate('/sign-in') - }, [navigate]) + token: null, + })); + navigate("/sign-in"); + }, [navigate]); /** * @todo improve error handling */ const authenticate = useCallback( async (email: string, password: string) => { - setAuthLoading(true) + setAuthLoading(true); postAuthLogin({ email, password }) .then((res) => { if (res.status === 200) { - login(res.data.access_token, res.data.user_id as string) + login(res.data.access_token, res.data.user_id); } }) - .catch((e ) => { - if(e instanceof AxiosError){ - toast.error(e.response?.data?.detail ?? "Error on login, please review your inputs and try again") + .catch((e) => { + if (e instanceof AxiosError) { + toast.error( + e.response?.data?.detail ?? + "Error on login, please review your inputs and try again", + ); } }) .finally(() => { - setAuthLoading(false) - }) + setAuthLoading(false); + }); }, - [login] - ) + [login], + ); const register = useCallback( async (email: string, password: string) => { - setAuthLoading(true) + setAuthLoading(true); postAuthRegister({ email, password }) .then((res) => { if (res.status === 201) { - toast.success('E-mail and password registered successfully!') - authenticate(email, password) + toast.success("E-mail and password registered successfully!"); + void authenticate(email, password); } }) .catch((err) => { - console.log(err?.response?.status) + console.log(err?.response?.status); if (err?.response?.status === 409) { - toast.warning(`This e-mail is already registered`) + toast.warning(`This e-mail is already registered`); } else { - toast.error(err?.response?.data?.detail ?? `Error while register`) + toast.error(err?.response?.data?.detail ?? `Error while register`); } }) .finally(() => { - setAuthLoading(false) - }) + setAuthLoading(false); + }); }, - [authenticate] - ) + [authenticate], + ); const value = useMemo((): IAuthenticationContext => { return { @@ -125,23 +126,27 @@ export const AuthenticationProvider: React.FC<{ children: ReactNode }> = ({ authLoading, logout, authenticate, - register - } - }, [store, logout, authenticate, register, authLoading]) + register, + }; + }, [store, logout, authenticate, register, authLoading]); /** * Listen to "logout" event and handles it (ie. unauthorized request) */ useEffect(() => { - window.addEventListener(DOMINO_LOGOUT, () => logout()) + window.addEventListener(DOMINO_LOGOUT, () => { + logout(); + }); return () => { - window.removeEventListener(DOMINO_LOGOUT, () => logout()) - } - }, [logout]) + window.removeEventListener(DOMINO_LOGOUT, () => { + logout(); + }); + }; + }, [logout]); return ( {children} - ) -} + ); +}; diff --git a/frontend/src/context/authentication/authentication.interface.ts b/frontend/src/context/authentication/authentication.interface.ts index 3d0a20f8..5d8fd984 100644 --- a/frontend/src/context/authentication/authentication.interface.ts +++ b/frontend/src/context/authentication/authentication.interface.ts @@ -1,13 +1,13 @@ export interface IAuthenticationStore { - token: string | null - userId: string | null + token: string | null; + userId: string | null; } export interface IAuthenticationContext { - store: IAuthenticationStore - isLogged: boolean - authLoading: boolean - logout: () => void - authenticate: (email: string, password: string) => Promise - register: (email: string, password: string) => Promise + store: IAuthenticationStore; + isLogged: boolean; + authLoading: boolean; + logout: () => void; + authenticate: (email: string, password: string) => Promise; + register: (email: string, password: string) => Promise; } diff --git a/frontend/src/context/authentication/authentication.logout.ts b/frontend/src/context/authentication/authentication.logout.ts index 0ce4ac49..2e49ba74 100644 --- a/frontend/src/context/authentication/authentication.logout.ts +++ b/frontend/src/context/authentication/authentication.logout.ts @@ -1,13 +1,13 @@ -export const DOMINO_LOGOUT = 'DOMINO_LOGOUT' +export const DOMINO_LOGOUT = "DOMINO_LOGOUT"; const event = new CustomEvent(DOMINO_LOGOUT, { bubbles: true, cancelable: true, detail: { - message: 'Logout' - } -}) + message: "Logout", + }, +}); export const dispatchLogout = () => { - window.dispatchEvent(event) -} + window.dispatchEvent(event); +}; diff --git a/frontend/src/context/authentication/index.ts b/frontend/src/context/authentication/index.ts index 01826bf9..1f2b97be 100644 --- a/frontend/src/context/authentication/index.ts +++ b/frontend/src/context/authentication/index.ts @@ -1,2 +1,2 @@ -export * from './authentication.context' -export * from './authentication.logout' +export * from "./authentication.context"; +export * from "./authentication.logout"; diff --git a/frontend/src/context/workflows/types/container-resources.ts b/frontend/src/context/workflows/types/container-resources.ts index 0eb2bb4b..5a162d69 100644 --- a/frontend/src/context/workflows/types/container-resources.ts +++ b/frontend/src/context/workflows/types/container-resources.ts @@ -1,11 +1,11 @@ export interface IContainerResourceFormData { - useGpu: boolean, - cpu:{ - min:number, - max: number, - }, - memory:{ - min:number, - max: number, - } + useGpu: boolean; + cpu: { + min: number; + max: number; + }; + memory: { + min: number; + max: number; + }; } diff --git a/frontend/src/context/workflows/types/index.ts b/frontend/src/context/workflows/types/index.ts index aebc89a7..6ddb5a38 100644 --- a/frontend/src/context/workflows/types/index.ts +++ b/frontend/src/context/workflows/types/index.ts @@ -1,4 +1,4 @@ -export * from "./container-resources" -export * from "./storage" -export * from "./workflow-piece-data" -export * from "./input" +export * from "./container-resources"; +export * from "./storage"; +export * from "./workflow-piece-data"; +export * from "./input"; diff --git a/frontend/src/context/workflows/types/input.ts b/frontend/src/context/workflows/types/input.ts index d48b1829..2edb4035 100644 --- a/frontend/src/context/workflows/types/input.ts +++ b/frontend/src/context/workflows/types/input.ts @@ -1,24 +1,24 @@ -import { Dayjs } from "dayjs"; +import { type Dayjs } from "dayjs"; -type Value = string | number | boolean | Dayjs +type Value = string | number | boolean | Dayjs; interface BaseInput { - fromUpstream: boolean, //? allowed | never | always - upstreamArgument: string, - upstreamId: string, - upstreamValue: string, - value: Value + fromUpstream: boolean; // ? allowed | never | always + upstreamArgument: string; + upstreamId: string; + upstreamValue: string; + value: Value; } export interface ObjectInput { - fromUpstream: Record - upstreamArgument: Record, - upstreamId: Record, - upstreamValue: Record, - value: Record + fromUpstream: Record; + upstreamArgument: Record; + upstreamId: Record; + upstreamValue: Record; + value: Record; } export type InputArray = BaseInput & { - value: BaseInput[] | ObjectInput[] -} + value: BaseInput[] | ObjectInput[]; +}; -export type Input = BaseInput +export type Input = BaseInput; diff --git a/frontend/src/context/workflows/types/settings.ts b/frontend/src/context/workflows/types/settings.ts index 271d9377..0657c33b 100644 --- a/frontend/src/context/workflows/types/settings.ts +++ b/frontend/src/context/workflows/types/settings.ts @@ -1,50 +1,50 @@ export enum scheduleIntervals { - None = "none", - Once = "once", - Hourly = "hourly", - Daily = "daily", - Weekly = "weekly", - Monthly = "monthly", - Yearly = "yearly", + None = "none", + Once = "once", + Hourly = "hourly", + Daily = "daily", + Weekly = "weekly", + Monthly = "monthly", + Yearly = "yearly", } -export type ScheduleIntervals = `${scheduleIntervals}` +export type ScheduleIntervals = `${scheduleIntervals}`; export enum endDateTypes { - Never = "never", - UserDefined = "User defined", + Never = "never", + UserDefined = "User defined", } -export type EndDateTypes = `${endDateTypes}` +export type EndDateTypes = `${endDateTypes}`; export enum storageSourcesAWS { - None = "None", - AWSS3 = "AWS S3", + None = "None", + AWSS3 = "AWS S3", } -export type StorageSourcesAWS = `${storageSourcesAWS}` +export type StorageSourcesAWS = `${storageSourcesAWS}`; export enum storageSourcesLocal { - None = "None", - Local = "Local", + None = "None", + Local = "Local", } -export type StorageSourcesLocal = `${storageSourcesLocal}` +export type StorageSourcesLocal = `${storageSourcesLocal}`; export interface IWorkflowSettingsConfig { - name: string, - scheduleInterval: ScheduleIntervals, - startDate: string, - endDate?: string, - endDateType: EndDateTypes, + name: string; + scheduleInterval: ScheduleIntervals; + startDate: string; + endDate?: string; + endDateType: EndDateTypes; } export interface IWorkflowSettingsStorage { - storageSource: StorageSourcesAWS | StorageSourcesLocal, - baseFolder?: string, - bucket?: string + storageSource: StorageSourcesAWS | StorageSourcesLocal; + baseFolder?: string; + bucket?: string; } export interface IWorkflowSettings { - config: IWorkflowSettingsConfig - storage: IWorkflowSettingsStorage + config: IWorkflowSettingsConfig; + storage: IWorkflowSettingsStorage; } diff --git a/frontend/src/context/workflows/types/storage.ts b/frontend/src/context/workflows/types/storage.ts index 1e465618..88708693 100644 --- a/frontend/src/context/workflows/types/storage.ts +++ b/frontend/src/context/workflows/types/storage.ts @@ -4,8 +4,8 @@ export enum storageAccessModes { ReadWrite = "Read/Write", } // Equivalent to type StorageAccessModes = "None" | "Read" | "Read/Write" -export type StorageAccessModes = `${storageAccessModes}` +export type StorageAccessModes = `${storageAccessModes}`; export interface IStorageFormData { - storageAccessMode: StorageAccessModes, + storageAccessMode: StorageAccessModes; } diff --git a/frontend/src/context/workflows/types/workflow-piece-data.ts b/frontend/src/context/workflows/types/workflow-piece-data.ts index acc7245a..56136bc5 100644 --- a/frontend/src/context/workflows/types/workflow-piece-data.ts +++ b/frontend/src/context/workflows/types/workflow-piece-data.ts @@ -1,68 +1,72 @@ -import { IWorkflowElement } from "services/requests/workflow" -import { IContainerResourceFormData } from "./container-resources" -import { InputArray, Input } from "./input" -import { EndDateTypes, ScheduleIntervals, StorageSourcesAWS, StorageSourcesLocal } from "./settings" -import { IStorageFormData, StorageAccessModes } from "./storage" -import { Edge } from "reactflow" +import { type Edge } from "reactflow"; +import { type IWorkflowElement } from "services/requests/workflow"; -export type IWorkflowPieceData = { - storage: IStorageFormData, - containerResources: IContainerResourceFormData, - inputs: Record +import { type IContainerResourceFormData } from "./container-resources"; +import { type InputArray, type Input } from "./input"; +import { + type EndDateTypes, + type ScheduleIntervals, + type StorageSourcesAWS, + type StorageSourcesLocal, +} from "./settings"; +import { type IStorageFormData, type StorageAccessModes } from "./storage"; +export interface IWorkflowPieceData { + storage: IStorageFormData; + containerResources: IContainerResourceFormData; + inputs: Record; } interface WorkflowBaseSettings { - name: string - start_date: string // ISOFormat - select_end_date: EndDateTypes - schedule_interval: ScheduleIntervals + name: string; + start_date: string; // ISOFormat + select_end_date: EndDateTypes; + schedule_interval: ScheduleIntervals; - end_date?: string // ISOFormat - catchup?: boolean - generate_report?: boolean - description?: string + end_date?: string; // ISOFormat + catchup?: boolean; + generate_report?: boolean; + description?: string; } interface UiSchema { - nodes: Record - edges: Edge[] + nodes: Record; + edges: Edge[]; } -type WorkflowSharedStorageDataModel = { - source: StorageSourcesLocal | StorageSourcesAWS - base_folder?: string - mode: StorageAccessModes - provider_options?: Record +interface WorkflowSharedStorageDataModel { + source: StorageSourcesLocal | StorageSourcesAWS; + base_folder?: string; + mode: StorageAccessModes; + provider_options?: Record; } - interface SystemRequirementsModel { - cpu: number - memory: number + cpu: number; + memory: number; } interface ContainerResourcesDataModel { - requests: SystemRequirementsModel - limits: SystemRequirementsModel - use_gpu: boolean + requests: SystemRequirementsModel; + limits: SystemRequirementsModel; + use_gpu: boolean; } export interface TasksDataModel { - workflow_shared_storage: WorkflowSharedStorageDataModel - container_resources: ContainerResourcesDataModel - task_id: string + workflow_shared_storage: WorkflowSharedStorageDataModel; + container_resources: ContainerResourcesDataModel; + task_id: string; piece: { - id: number - name: string - } - piece_input_kwargs: Record - dependencies?: string[] + id: number; + name: string; + }; + piece_input_kwargs: Record; + dependencies?: string[]; } -type TasksDict = Record +type TasksDict = Record; -export type CreateWorkflowRequest = { - workflow: WorkflowBaseSettings, - tasks: TasksDict, - ui_schema: UiSchema, +export interface CreateWorkflowRequest { + workflow: WorkflowBaseSettings; + tasks: TasksDict; + ui_schema: UiSchema; } diff --git a/frontend/src/context/workflows/workflows-editor.context/index.tsx b/frontend/src/context/workflows/workflows-editor.context/index.tsx index 66f0aa1c..79103df5 100644 --- a/frontend/src/context/workflows/workflows-editor.context/index.tsx +++ b/frontend/src/context/workflows/workflows-editor.context/index.tsx @@ -1,37 +1,59 @@ -import React, { FC, useCallback } from 'react' - +import { useWorkspaces } from "context/workspaces/workspaces.context"; +import React, { type FC, useCallback } from "react"; import { - IPostWorkflowParams, + type IPostWorkflowParams, useAuthenticatedPostWorkflow, - IPostWorkflowResponseInterface, -} from 'services/requests/workflow' - -import { useWorkspaces } from 'context/workspaces/workspaces.context'; - -import { createCustomContext, generateTaskName, getIdSlice } from 'utils' + type IPostWorkflowResponseInterface, +} from "services/requests/workflow"; +import { createCustomContext, generateTaskName, getIdSlice } from "utils"; -import { usesPieces, IPiecesContext } from './pieces.context'; -import { useWorkflowsEdges, IWorkflowsEdgesContext } from './workflow-edges.context'; -import { useWorkflowsNodes, IWorkflowsNodesContext } from './workflow-nodes.context'; -import { useWorkflowPiece, IWorkflowPieceContext } from './workflow-pieces.context'; -import { useWorkflowPiecesData, IWorkflowPiecesDataContext } from './workflow-pieces-data.context'; -import { IWorkflowSettingsContext, useWorkflowSettings } from './workflow-settings-data.context'; -import { CreateWorkflowRequest, TasksDataModel } from '../types'; +import { type CreateWorkflowRequest, type TasksDataModel } from "../types"; -interface IWorkflowsEditorContext extends IPiecesContext, IWorkflowsEdgesContext, IWorkflowSettingsContext, IWorkflowsNodesContext, IWorkflowPieceContext, IWorkflowPiecesDataContext { - - fetchWorkflowForage: () => any // TODO add type - workflowsEditorBodyFromFlowchart: () => Promise // TODO add type - handleCreateWorkflow: (params: IPostWorkflowParams) => Promise - clearForageData: () => Promise +import { usesPieces, type IPiecesContext } from "./pieces.context"; +import { + useWorkflowsEdges, + type IWorkflowsEdgesContext, +} from "./workflow-edges.context"; +import { + useWorkflowsNodes, + type IWorkflowsNodesContext, +} from "./workflow-nodes.context"; +import { + useWorkflowPiecesData, + type IWorkflowPiecesDataContext, +} from "./workflow-pieces-data.context"; +import { + useWorkflowPiece, + type IWorkflowPieceContext, +} from "./workflow-pieces.context"; +import { + type IWorkflowSettingsContext, + useWorkflowSettings, +} from "./workflow-settings-data.context"; + +interface IWorkflowsEditorContext + extends IPiecesContext, + IWorkflowsEdgesContext, + IWorkflowSettingsContext, + IWorkflowsNodesContext, + IWorkflowPieceContext, + IWorkflowPiecesDataContext { + fetchWorkflowForage: () => any; // TODO add type + workflowsEditorBodyFromFlowchart: () => Promise; // TODO add type + handleCreateWorkflow: ( + params: IPostWorkflowParams, + ) => Promise; + clearForageData: () => Promise; } export const [WorkflowsEditorContext, useWorkflowsEditor] = - createCustomContext('WorkflowsEditor Context') + createCustomContext("WorkflowsEditor Context"); -export const WorkflowsEditorProvider: FC<{ children?: React.ReactNode }> = ({ children }) => { - const { workspace } = useWorkspaces() - const postWorkflow = useAuthenticatedPostWorkflow() +export const WorkflowsEditorProvider: FC<{ children?: React.ReactNode }> = ({ + children, +}) => { + const { workspace } = useWorkspaces(); + const postWorkflow = useAuthenticatedPostWorkflow(); const { repositories, @@ -42,13 +64,9 @@ export const WorkflowsEditorProvider: FC<{ children?: React.ReactNode }> = ({ ch fetchRepoById, search, handleSearch, - } = usesPieces() + } = usesPieces(); - const { - edges, - fetchForageWorkflowEdges, - setEdges, - } = useWorkflowsEdges() + const { edges, fetchForageWorkflowEdges, setEdges } = useWorkflowsEdges(); const { nodes, @@ -56,7 +74,7 @@ export const WorkflowsEditorProvider: FC<{ children?: React.ReactNode }> = ({ ch fetchForageWorkflowNodes, setNodes, toggleNodeDirection, - } = useWorkflowsNodes() + } = useWorkflowsNodes(); const { setForageWorkflowPieces, @@ -65,7 +83,7 @@ export const WorkflowsEditorProvider: FC<{ children?: React.ReactNode }> = ({ ch getForageWorkflowPieces, removeForageWorkflowPiecesById, clearForageWorkflowPieces, - } = useWorkflowPiece() + } = useWorkflowPiece(); const { fetchForageWorkflowPiecesData, @@ -74,111 +92,124 @@ export const WorkflowsEditorProvider: FC<{ children?: React.ReactNode }> = ({ ch clearForageWorkflowPiecesData, removeForageWorkflowPieceDataById, clearDownstreamDataById, - } = useWorkflowPiecesData() - + } = useWorkflowPiecesData(); const { fetchWorkflowSettingsData, setWorkflowSettingsData, - clearWorkflowSettingsData - } = useWorkflowSettings() - - - const handleCreateWorkflow = useCallback(async (payload: IPostWorkflowParams) => { - return postWorkflow({ ...payload, workspace_id: workspace?.id ?? '' }) - }, [postWorkflow, workspace]) - + clearWorkflowSettingsData, + } = useWorkflowSettings(); + + const handleCreateWorkflow = useCallback( + async (payload: IPostWorkflowParams) => { + return await postWorkflow({ + ...payload, + workspace_id: workspace?.id ?? "", + }); + }, + [postWorkflow, workspace], + ); const fetchWorkflowForage = useCallback(async () => { - const workflowPieces = await getForageWorkflowPieces() - const workflowPiecesData = await fetchForageWorkflowPiecesData() - const workflowSettingsData = await fetchWorkflowSettingsData() + const workflowPieces = await getForageWorkflowPieces(); + const workflowPiecesData = await fetchForageWorkflowPiecesData(); + const workflowSettingsData = await fetchWorkflowSettingsData(); return { workflowPieces, workflowPiecesData, workflowSettingsData, - } - }, [fetchForageWorkflowPiecesData, fetchWorkflowSettingsData, getForageWorkflowPieces]) + }; + }, [ + fetchForageWorkflowPiecesData, + fetchWorkflowSettingsData, + getForageWorkflowPieces, + ]); const workflowsEditorBodyFromFlowchart = useCallback(async () => { - const workflowPiecesData = await fetchForageWorkflowPiecesData() - const workflowSettingsData = await fetchWorkflowSettingsData() - const workflowNodes = await fetchForageWorkflowNodes() - const workflowEdges = await fetchForageWorkflowEdges() - + const workflowPiecesData = await fetchForageWorkflowPiecesData(); + const workflowSettingsData = await fetchWorkflowSettingsData(); + const workflowNodes = await fetchForageWorkflowNodes(); + const workflowEdges = await fetchForageWorkflowEdges(); - const workflow: CreateWorkflowRequest['workflow'] = { + const workflow: CreateWorkflowRequest["workflow"] = { name: workflowSettingsData.config.name, schedule_interval: workflowSettingsData.config.scheduleInterval, select_end_date: workflowSettingsData.config.endDateType, start_date: workflowSettingsData.config.startDate, end_date: workflowSettingsData.config.endDate, - } + }; - const ui_schema: CreateWorkflowRequest['ui_schema'] = { + const ui_schema: CreateWorkflowRequest["ui_schema"] = { nodes: {}, - edges: workflowEdges - } + edges: workflowEdges, + }; - const tasks: CreateWorkflowRequest['tasks'] = {} + const tasks: CreateWorkflowRequest["tasks"] = {}; for (const element of workflowNodes) { - const elementData = workflowPiecesData[element.id] + const elementData = workflowPiecesData[element.id]; - const numberId = getIdSlice(element.id) - const taskName = generateTaskName(element.data.name, element.id) + const numberId = getIdSlice(element.id); + const taskName = generateTaskName(element.data.name, element.id); - ui_schema['nodes'][taskName] = element + ui_schema.nodes[taskName] = element; const dependencies = workflowEdges.reduce((acc, edge) => { if (edge.target === element.id) { - const task = workflowNodes.find(n => n.id === edge.source) + const task = workflowNodes.find((n) => n.id === edge.source); if (task) { - const upTaskName = generateTaskName(task.data.name,task.id) - acc.push(upTaskName) + const upTaskName = generateTaskName(task.data.name, task.id); + acc.push(upTaskName); } } - return acc - }, []) + return acc; + }, []); - const { storageSource, baseFolder, ...providerOptions } = workflowSettingsData.storage || {} + const { storageSource, baseFolder, ...providerOptions } = + workflowSettingsData.storage || {}; - const pieceInputKwargs = Object.entries(elementData.inputs).reduce((acc, [key, value]) => { - if(Array.isArray(value.value)) { + const pieceInputKwargs = Object.entries(elementData.inputs).reduce< + Record + >((acc, [key, value]) => { + if (Array.isArray(value.value)) { acc[key] = { fromUpstream: value.fromUpstream, upstreamTaskId: value.fromUpstream ? value.upstreamId : null, - upstreamArgument: value.fromUpstream ? value.upstreamArgument : null, + upstreamArgument: value.fromUpstream + ? value.upstreamArgument + : null, value: value.value.map((value) => { return { fromUpstream: value.fromUpstream, upstreamTaskId: value.fromUpstream ? value.upstreamId : null, - upstreamArgument: value.fromUpstream ? value.upstreamArgument : null, - value: value.value - } - }) - } - - return acc + upstreamArgument: value.fromUpstream + ? value.upstreamArgument + : null, + value: value.value, + }; + }), + }; + + return acc; } acc[key] = { fromUpstream: value.fromUpstream, upstreamTaskId: value.fromUpstream ? value.upstreamId : null, upstreamArgument: value.fromUpstream ? value.upstreamArgument : null, - value: value.value - } + value: value.value, + }; - return acc - }, {} as Record) + return acc; + }, {}); const taskDataModel: TasksDataModel = { task_id: taskName, piece: { id: numberId, - name: element.data.name + name: element.data.name, }, dependencies, piece_input_kwargs: pieceInputKwargs, @@ -191,36 +222,42 @@ export const WorkflowsEditorProvider: FC<{ children?: React.ReactNode }> = ({ ch container_resources: { requests: { cpu: elementData.containerResources.cpu.min, - memory: elementData.containerResources.memory.min + memory: elementData.containerResources.memory.min, }, limits: { cpu: elementData.containerResources.cpu.max, - memory: elementData.containerResources.memory.max + memory: elementData.containerResources.memory.max, }, - use_gpu: elementData.containerResources.useGpu + use_gpu: elementData.containerResources.useGpu, }, - } + }; - tasks[taskName] = taskDataModel + tasks[taskName] = taskDataModel; } - - return { workflow, tasks, ui_schema, - } - - }, [fetchForageWorkflowEdges, fetchForageWorkflowNodes, fetchForageWorkflowPiecesData, fetchWorkflowSettingsData]) + }; + }, [ + fetchForageWorkflowEdges, + fetchForageWorkflowNodes, + fetchForageWorkflowPiecesData, + fetchWorkflowSettingsData, + ]); const clearForageData = useCallback(async () => { await Promise.allSettled([ clearForageWorkflowPieces(), clearForageWorkflowPiecesData(), clearWorkflowSettingsData(), - ]) - }, [clearForageWorkflowPieces, clearForageWorkflowPiecesData, clearWorkflowSettingsData]) + ]); + }, [ + clearForageWorkflowPieces, + clearForageWorkflowPiecesData, + clearWorkflowSettingsData, + ]); const value: IWorkflowsEditorContext = { repositories, @@ -261,13 +298,12 @@ export const WorkflowsEditorProvider: FC<{ children?: React.ReactNode }> = ({ ch clearForageWorkflowPieces, fetchWorkflowSettingsData, setWorkflowSettingsData, - clearWorkflowSettingsData - } + clearWorkflowSettingsData, + }; return ( {children} - ) -} - + ); +}; diff --git a/frontend/src/context/workflows/workflows-editor.context/pieces.context.tsx b/frontend/src/context/workflows/workflows-editor.context/pieces.context.tsx index 21d14323..2b8e9253 100644 --- a/frontend/src/context/workflows/workflows-editor.context/pieces.context.tsx +++ b/frontend/src/context/workflows/workflows-editor.context/pieces.context.tsx @@ -1,98 +1,107 @@ import React, { useCallback, useEffect, useMemo, useState } from "react"; import { toast } from "react-toastify"; import localForage from "services/config/local-forage.config"; -import { IGetRepoOperatorsResponseInterface, IOperator, IOperatorForageSchema, IOperatorRepository, IRepositoryOperators, useAuthenticatedGetOperatorRepositories } from "services/requests/piece"; +import { + type IGetRepoOperatorsResponseInterface, + type IOperator, + type IOperatorForageSchema, + type IOperatorRepository, + type IRepositoryOperators, + useAuthenticatedGetOperatorRepositories, +} from "services/requests/piece"; import { useFetchAuthenticatedGetRepoIdOperators } from "services/requests/piece/get-piece-repository-pieces.request"; import { createCustomContext } from "utils"; export interface IPiecesContext { - repositories: IOperatorRepository[] - repositoriesError: boolean - repositoriesLoading: boolean - repositoryOperators: IRepositoryOperators + repositories: IOperatorRepository[]; + repositoriesError: boolean; + repositoriesLoading: boolean; + repositoryOperators: IRepositoryOperators; - search: string - handleSearch: (word: string) => void + search: string; + handleSearch: (word: string) => void; fetchRepoById: (params: { - id: string - }) => Promise - fetchForagePieceById: (id: number) => Promise + id: string; + }) => Promise; + fetchForagePieceById: (id: number) => Promise; } export const [PiecesContext, usesPieces] = - createCustomContext('Pieces Context') + createCustomContext("Pieces Context"); -const PiecesProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => { +const PiecesProvider: React.FC<{ children: React.ReactNode }> = ({ + children, +}) => { + const [search, handleSearch] = useState(""); + const [repositoryOperators, setRepositoryOperatos] = + useState({}); - const [search, handleSearch] = useState('') - const [repositoryOperators, setRepositoryOperatos] = useState({}) - - const fetchRepoById = useFetchAuthenticatedGetRepoIdOperators() + const fetchRepoById = useFetchAuthenticatedGetRepoIdOperators(); const { data, error: repositoriesError, - isValidating: repositoriesLoading + isValidating: repositoriesLoading, // mutate: repositoriesRefresh - } = useAuthenticatedGetOperatorRepositories({}) + } = useAuthenticatedGetOperatorRepositories({}); const repositories: IOperatorRepository[] = useMemo( () => data?.data.filter((repo) => repo.name.includes(search)) ?? [], - [data, search] - ) + [data, search], + ); const fetchForagePieceById = useCallback(async (id: number) => { - const pieces = await localForage.getItem("pieces") + const pieces = await localForage.getItem("pieces"); if (pieces !== null) { - return pieces[id] + return pieces[id]; } - }, []) + }, []); useEffect(() => { const updateRepositoriesOperators = async () => { - var repositoyOperatorsAux: IRepositoryOperators = {} - var forageOperators: IOperatorForageSchema = {} + const repositoyOperatorsAux: IRepositoryOperators = {}; + const forageOperators: IOperatorForageSchema = {}; for (const repo of repositories) { fetchRepoById({ id: repo.id }) .then((pieces: any) => { - repositoyOperatorsAux[repo.id] = [] + repositoyOperatorsAux[repo.id] = []; for (const op of pieces) { - repositoyOperatorsAux[repo.id].push(op) - forageOperators[op.id] = op + repositoyOperatorsAux[repo.id].push(op); + forageOperators[op.id] = op; } - setRepositoryOperatos(repositoyOperatorsAux) - localForage.setItem("pieces", forageOperators) + setRepositoryOperatos(repositoyOperatorsAux); + void localForage.setItem("pieces", forageOperators); }) + .catch((e) => { + console.log(e); + }); // Set piece item to storage -> {piece_id: Operator} } - } - updateRepositoriesOperators() - }, [repositories, fetchRepoById]) + }; + void updateRepositoriesOperators(); + }, [repositories, fetchRepoById]); useEffect(() => { - if (!!repositoriesError) { - toast.error('Error loading repositories, try again later') + if (repositoriesError) { + toast.error("Error loading repositories, try again later"); } - }, [repositoriesError]) - + }, [repositoriesError]); const value: IPiecesContext = { fetchForagePieceById, fetchRepoById, handleSearch, - repositories, - repositoriesError, - repositoriesLoading, - repositoryOperators, + repositories, + repositoriesError, + repositoriesLoading, + repositoryOperators, search, - } + }; return ( - - {children} - - ) -} + {children} + ); +}; -export default PiecesProvider \ No newline at end of file +export default PiecesProvider; diff --git a/frontend/src/context/workflows/workflows-editor.context/provider-context-wrapper.tsx b/frontend/src/context/workflows/workflows-editor.context/provider-context-wrapper.tsx index 286c519f..1e866f94 100644 --- a/frontend/src/context/workflows/workflows-editor.context/provider-context-wrapper.tsx +++ b/frontend/src/context/workflows/workflows-editor.context/provider-context-wrapper.tsx @@ -1,11 +1,13 @@ import PiecesProvider from "./pieces.context"; import WorkflowsEdgesProvider from "./workflow-edges.context"; import WorkflowsNodesProvider from "./workflow-nodes.context"; -import WorkflowPiecesProvider from "./workflow-pieces.context"; import WorkflowPiecesDataProvider from "./workflow-pieces-data.context"; +import WorkflowPiecesProvider from "./workflow-pieces.context"; import WorkflowSettingsDataProvider from "./workflow-settings-data.context"; -const ProviderContextWrapper: React.FC<{ children: React.ReactNode }> = ({ children }) => { +const ProviderContextWrapper: React.FC<{ children: React.ReactNode }> = ({ + children, +}) => { return ( @@ -21,6 +23,6 @@ const ProviderContextWrapper: React.FC<{ children: React.ReactNode }> = ({ child ); -} +}; -export default ProviderContextWrapper +export default ProviderContextWrapper; diff --git a/frontend/src/context/workflows/workflows-editor.context/workflow-edges.context.tsx b/frontend/src/context/workflows/workflows-editor.context/workflow-edges.context.tsx index 4c1619e6..49640d68 100644 --- a/frontend/src/context/workflows/workflows-editor.context/workflow-edges.context.tsx +++ b/frontend/src/context/workflows/workflows-editor.context/workflow-edges.context.tsx @@ -1,61 +1,63 @@ import React, { useCallback, useEffect, useState } from "react"; -import { Edge } from "reactflow"; +import { type Edge } from "reactflow"; import localForage from "services/config/local-forage.config"; import { createCustomContext } from "utils"; export interface IWorkflowsEdgesContext { - edges: Edge[] - setEdges: React.Dispatch> - fetchForageWorkflowEdges: () => Promise + edges: Edge[]; + setEdges: React.Dispatch>; + fetchForageWorkflowEdges: () => Promise; } export const [WorkflowsEdgesContext, useWorkflowsEdges] = - createCustomContext('WorkflowsEdges Context') + createCustomContext("WorkflowsEdges Context"); + +const WorkflowsEdgesProvider: React.FC<{ children: React.ReactNode }> = ({ + children, +}) => { + const [edges, setEdges] = useState([]); + const [loadingEdges, setLoadingEdges] = useState(true); -const WorkflowsEdgesProvider: React.FC<{children:React.ReactNode}> = ({ children }) => { - const [edges, setEdges] = useState([]) - const [loadingEdges, setLoadingEdges] = useState(true) - const setForageWorkflowEdges = useCallback(async (edges: Edge[]) => { - await localForage.setItem('workflowEdges', edges) - }, []) + await localForage.setItem("workflowEdges", edges); + }, []); const fetchForageWorkflowEdges = useCallback(async () => { - var workflowEdges = await localForage.getItem("workflowEdges") - if ((!workflowEdges) || (workflowEdges.length === 0)) { - workflowEdges = [] + let workflowEdges = await localForage.getItem("workflowEdges"); + if (!workflowEdges || workflowEdges.length === 0) { + workflowEdges = []; } - return workflowEdges - }, []) + return workflowEdges; + }, []); useEffect(() => { - (async () => { - const forageEdges = await fetchForageWorkflowEdges() - await setForageWorkflowEdges(forageEdges) - setLoadingEdges(false) - })() - }, []) + void (async () => { + const forageEdges = await fetchForageWorkflowEdges(); + await setForageWorkflowEdges(forageEdges); + setLoadingEdges(false); + })(); + }, []); useEffect(() => { - (async () => { + void (async () => { if (loadingEdges) { - return + return; } - await setForageWorkflowEdges(edges) - })() - }, [edges, setForageWorkflowEdges, loadingEdges]) + await setForageWorkflowEdges(edges); + })(); + }, [edges, setForageWorkflowEdges, loadingEdges]); const value: IWorkflowsEdgesContext = { edges, - fetchForageWorkflowEdges: () => fetchForageWorkflowEdges(), + fetchForageWorkflowEdges: async () => await fetchForageWorkflowEdges(), setEdges, - } + }; return ( {children} - ) -} + ); +}; -export default WorkflowsEdgesProvider \ No newline at end of file +export default WorkflowsEdgesProvider; diff --git a/frontend/src/context/workflows/workflows-editor.context/workflow-nodes.context.tsx b/frontend/src/context/workflows/workflows-editor.context/workflow-nodes.context.tsx index d23e2777..be6603ef 100644 --- a/frontend/src/context/workflows/workflows-editor.context/workflow-nodes.context.tsx +++ b/frontend/src/context/workflows/workflows-editor.context/workflow-nodes.context.tsx @@ -1,71 +1,79 @@ import React, { useCallback, useEffect, useState } from "react"; -import { Node } from "reactflow"; +import { type Node } from "reactflow"; import localForage from "services/config/local-forage.config"; -import { IWorkflowElement } from "services/requests/workflow"; +import { type IWorkflowElement } from "services/requests/workflow"; import { createCustomContext } from "utils"; export interface IWorkflowsNodesContext { - nodes: IWorkflowElement[] | Node[] - setNodes: React.Dispatch> - fetchForageWorkflowNodes: () => Promise - nodeDirection: "horizontal" | "vertical" - toggleNodeDirection: () => void + nodes: IWorkflowElement[] | Node[]; + setNodes: React.Dispatch>; + fetchForageWorkflowNodes: () => Promise; + nodeDirection: "horizontal" | "vertical"; + toggleNodeDirection: () => void; } export const [WorkflowsNodesContext, useWorkflowsNodes] = - createCustomContext('WorkflowsNodes Context') + createCustomContext("WorkflowsNodes Context"); -const WorkflowsNodesProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => { - const [nodeDirection, setNodeDirection] = useState<'horizontal' | 'vertical'>('horizontal') - const [nodes, setNodes] = useState([]) - const [loadingNodes, setLoadingNodes] = useState(true) +const WorkflowsNodesProvider: React.FC<{ children: React.ReactNode }> = ({ + children, +}) => { + const [nodeDirection, setNodeDirection] = useState<"horizontal" | "vertical">( + "horizontal", + ); + const [nodes, setNodes] = useState([]); + const [loadingNodes, setLoadingNodes] = useState(true); - const setForageWorkflowNodes = useCallback(async (nodes: IWorkflowElement[]) => { - await localForage.setItem('workflowNodes', nodes) - }, []) + const setForageWorkflowNodes = useCallback( + async (nodes: IWorkflowElement[]) => { + await localForage.setItem("workflowNodes", nodes); + }, + [], + ); const fetchForageWorkflowNodes = useCallback(async () => { - var workflowNodes = await localForage.getItem("workflowNodes") - if ((!workflowNodes) || (workflowNodes.length === 0)) { - workflowNodes = [] + let workflowNodes = await localForage.getItem("workflowNodes"); + if (!workflowNodes || workflowNodes.length === 0) { + workflowNodes = []; } - return workflowNodes - }, []) + return workflowNodes; + }, []); useEffect(() => { - (async () => { - const forageNodes = await fetchForageWorkflowNodes() - await setForageWorkflowNodes(forageNodes) - setLoadingNodes(false) - })() - }, []) + void (async () => { + const forageNodes = await fetchForageWorkflowNodes(); + await setForageWorkflowNodes(forageNodes); + setLoadingNodes(false); + })(); + }, []); // Update nodes in forage if nodes array is updated useEffect(() => { - (async () => { + void (async () => { if (loadingNodes) { - return + return; } - await setForageWorkflowNodes(nodes) - })() - }, [nodes, setForageWorkflowNodes, loadingNodes]) + await setForageWorkflowNodes(nodes); + })(); + }, [nodes, setForageWorkflowNodes, loadingNodes]); const value = { nodes, setNodes, - fetchForageWorkflowNodes: () => fetchForageWorkflowNodes(), + fetchForageWorkflowNodes: async () => await fetchForageWorkflowNodes(), nodeDirection, - toggleNodeDirection: () => + toggleNodeDirection: () => { setNodeDirection((current: any) => - current === 'vertical' ? 'horizontal' : 'vertical' - ) - } + current === "vertical" ? "horizontal" : "vertical", + ); + }, + }; return ( {children} - ) -} + ); +}; -export default WorkflowsNodesProvider \ No newline at end of file +export default WorkflowsNodesProvider; diff --git a/frontend/src/context/workflows/workflows-editor.context/workflow-pieces-data.context.tsx b/frontend/src/context/workflows/workflows-editor.context/workflow-pieces-data.context.tsx index 148bcf3a..c3c8f258 100644 --- a/frontend/src/context/workflows/workflows-editor.context/workflow-pieces-data.context.tsx +++ b/frontend/src/context/workflows/workflows-editor.context/workflow-pieces-data.context.tsx @@ -1,101 +1,123 @@ import React, { useCallback } from "react"; import localForage from "services/config/local-forage.config"; import { createCustomContext, getUuid } from "utils"; -import { IWorkflowPieceData } from "../types"; -type ForagePiecesData = Record +import { type IWorkflowPieceData } from "../types"; + +type ForagePiecesData = Record; export interface IWorkflowPiecesDataContext { - setForageWorkflowPiecesData: (id: string, pieceData: IWorkflowPieceData) => Promise - fetchForageWorkflowPiecesData: () => Promise - fetchForageWorkflowPiecesDataById: (id: string) => Promise - removeForageWorkflowPieceDataById: (id: string) => Promise - clearForageWorkflowPiecesData: () => Promise - clearDownstreamDataById: (id:string) => Promise + setForageWorkflowPiecesData: ( + id: string, + pieceData: IWorkflowPieceData, + ) => Promise; + fetchForageWorkflowPiecesData: () => Promise; + fetchForageWorkflowPiecesDataById: ( + id: string, + ) => Promise; + removeForageWorkflowPieceDataById: (id: string) => Promise; + clearForageWorkflowPiecesData: () => Promise; + clearDownstreamDataById: (id: string) => Promise; } export const [WorkflowPiecesDataContext, useWorkflowPiecesData] = - createCustomContext('WorkflowPiecesData Context') - -const WorkflowPiecesDataProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => { - - const setForageWorkflowPiecesData = useCallback(async (id: string, pieceData: IWorkflowPieceData) => { - let currentData = await localForage.getItem('workflowPiecesData') - if (!currentData) { - currentData = {} - } - currentData[id] = pieceData - await localForage.setItem('workflowPiecesData', currentData) - }, []) + createCustomContext("WorkflowPiecesData Context"); + +const WorkflowPiecesDataProvider: React.FC<{ children: React.ReactNode }> = ({ + children, +}) => { + const setForageWorkflowPiecesData = useCallback( + async (id: string, pieceData: IWorkflowPieceData) => { + let currentData = + await localForage.getItem("workflowPiecesData"); + if (!currentData) { + currentData = {}; + } + currentData[id] = pieceData; + await localForage.setItem("workflowPiecesData", currentData); + }, + [], + ); const fetchForageWorkflowPiecesData = useCallback(async () => { - let workflowPiecesData = await localForage.getItem("workflowPiecesData") + const workflowPiecesData = + await localForage.getItem("workflowPiecesData"); - return workflowPiecesData ?? {} - }, []) + return workflowPiecesData ?? {}; + }, []); const fetchForageWorkflowPiecesDataById = useCallback(async (id: string) => { - let workflowPiecesData = await localForage.getItem("workflowPiecesData") + const workflowPiecesData = + await localForage.getItem("workflowPiecesData"); if (!workflowPiecesData?.[id]) { - return + return; } - return workflowPiecesData[id] - }, []) + return workflowPiecesData[id]; + }, []); - const clearDownstreamDataById = useCallback(async (id:string)=>{ - const hashId = getUuid(id).replaceAll('-', '') - let workflowPieceData = await localForage.getItem("workflowPiecesData") + const clearDownstreamDataById = useCallback(async (id: string) => { + const hashId = getUuid(id).replaceAll("-", ""); + const workflowPieceData = + await localForage.getItem("workflowPiecesData"); if (!workflowPieceData) { - return + return; } - Object.values(workflowPieceData).forEach(wpd => { - Object.values(wpd.inputs).forEach(input => { + Object.values(workflowPieceData).forEach((wpd) => { + Object.values(wpd.inputs).forEach((input) => { if (input.upstreamId.includes(hashId)) { - input.upstreamArgument = "" - input.upstreamId = "" - input.upstreamValue = "" + input.upstreamArgument = ""; + input.upstreamId = ""; + input.upstreamValue = ""; } else if (Array.isArray(input.value)) { - input.value.forEach(item => { - if (typeof item.upstreamId === "string" && item.upstreamId.includes(hashId)) { - item.upstreamArgument = "" - item.upstreamId = "" - item.upstreamValue = "" + input.value.forEach((item) => { + if ( + typeof item.upstreamId === "string" && + item.upstreamId.includes(hashId) + ) { + item.upstreamArgument = ""; + item.upstreamId = ""; + item.upstreamValue = ""; } else if (typeof item.upstreamId === "object") { - Object.keys(item.upstreamId).forEach(key => { - const obj = item as any + Object.keys(item.upstreamId).forEach((key) => { + const obj = item as any; if (obj.upstreamId[key].includes(hashId)) { - obj.upstreamArgument[key] = "" - obj.upstreamId[key] = "" - obj.upstreamValue[key] = "" + obj.upstreamArgument[key] = ""; + obj.upstreamId[key] = ""; + obj.upstreamValue[key] = ""; } - }) + }); } - }) + }); } - }) - }) - await localForage.setItem('workflowPiecesData', workflowPieceData) - },[]) - - const removeForageWorkflowPieceDataById = useCallback(async (id: string) => { - let workflowPieceData = await localForage.getItem("workflowPiecesData") - - if (!workflowPieceData) { - return - } - delete workflowPieceData[id] - await localForage.setItem('workflowPiecesData', workflowPieceData) - - await clearDownstreamDataById(id) - }, [clearDownstreamDataById]) + }); + }); + await localForage.setItem("workflowPiecesData", workflowPieceData); + }, []); + + const removeForageWorkflowPieceDataById = useCallback( + async (id: string) => { + const workflowPieceData = + await localForage.getItem("workflowPiecesData"); + + if (!workflowPieceData) { + return; + } + // eslint-disable-next-line @typescript-eslint/no-dynamic-delete + delete workflowPieceData[id]; + await localForage.setItem("workflowPiecesData", workflowPieceData); + + await clearDownstreamDataById(id); + }, + [clearDownstreamDataById], + ); const clearForageWorkflowPiecesData = useCallback(async () => { - await localForage.setItem('workflowPiecesData', {}) - }, []) + await localForage.setItem("workflowPiecesData", {}); + }, []); const value: IWorkflowPiecesDataContext = { setForageWorkflowPiecesData, @@ -104,13 +126,13 @@ const WorkflowPiecesDataProvider: React.FC<{ children: React.ReactNode }> = ({ c removeForageWorkflowPieceDataById, clearForageWorkflowPiecesData, clearDownstreamDataById, - } + }; return ( {children} - ) -} + ); +}; -export default WorkflowPiecesDataProvider +export default WorkflowPiecesDataProvider; diff --git a/frontend/src/context/workflows/workflows-editor.context/workflow-pieces.context.tsx b/frontend/src/context/workflows/workflows-editor.context/workflow-pieces.context.tsx index a3bf502b..3600b2b9 100644 --- a/frontend/src/context/workflows/workflows-editor.context/workflow-pieces.context.tsx +++ b/frontend/src/context/workflows/workflows-editor.context/workflow-pieces.context.tsx @@ -1,61 +1,69 @@ -import React, { useCallback } from 'react'; -import localForage from 'services/config/local-forage.config'; -import { IOperator } from 'services/requests/piece'; -import { createCustomContext } from 'utils'; +import React, { useCallback } from "react"; +import localForage from "services/config/local-forage.config"; +import { type IOperator } from "services/requests/piece"; +import { createCustomContext } from "utils"; export interface IWorkflowPieceContext { - setForageWorkflowPieces: (workflowPieces: any) => Promise // TODO add type - getForageWorkflowPieces: () => Promise> // TODO add type - removeForageWorkflowPiecesById: (id: string) => Promise - fetchWorkflowPieceById: (id: string) => Promise // TODO add type - clearForageWorkflowPieces: () => Promise - setForageWorkflowPiecesOutputSchema: (id: string, properties: any) => Promise + setForageWorkflowPieces: (workflowPieces: any) => Promise; // TODO add type + getForageWorkflowPieces: () => Promise>; // TODO add type + removeForageWorkflowPiecesById: (id: string) => Promise; + fetchWorkflowPieceById: (id: string) => Promise; // TODO add type + clearForageWorkflowPieces: () => Promise; + setForageWorkflowPiecesOutputSchema: ( + id: string, + properties: any, + ) => Promise; } export const [WorkflowPiecesContext, useWorkflowPiece] = - createCustomContext('WorkflowsPieces Context') - -const WorkflowPiecesProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => { + createCustomContext("WorkflowsPieces Context"); +const WorkflowPiecesProvider: React.FC<{ children: React.ReactNode }> = ({ + children, +}) => { const setForageWorkflowPieces = useCallback(async (workflowPieces: any) => { - await localForage.setItem('workflowPieces', workflowPieces) - }, []) + await localForage.setItem("workflowPieces", workflowPieces); + }, []); - const setForageWorkflowPiecesOutputSchema = useCallback(async (id: any, properties: any) => { - const workflowPieces = await localForage.getItem("workflowPieces") - if (workflowPieces?.[id]) { - workflowPieces[id].output_schema.properties = properties - localForage.setItem('workflowPieces', workflowPieces) - } - }, []) + const setForageWorkflowPiecesOutputSchema = useCallback( + async (id: any, properties: any) => { + const workflowPieces = await localForage.getItem("workflowPieces"); + if (workflowPieces?.[id]) { + workflowPieces[id].output_schema.properties = properties; + void localForage.setItem("workflowPieces", workflowPieces); + } + }, + [], + ); const clearForageWorkflowPieces = useCallback(async () => { - await localForage.setItem('workflowPieces', {}) - }, []) + await localForage.setItem("workflowPieces", {}); + }, []); const getForageWorkflowPieces = useCallback(async () => { - const workflowPieces = await localForage.getItem("workflowPieces") + const workflowPieces = await localForage.getItem("workflowPieces"); if (!workflowPieces) { - return {} + return {}; } - return workflowPieces - }, []) + return workflowPieces; + }, []); const removeForageWorkflowPiecesById = useCallback(async (id: string) => { - const workflowPieces = await localForage.getItem("workflowPieces") + const workflowPieces = await localForage.getItem("workflowPieces"); if (!workflowPieces) { - return + return; } - delete workflowPieces[id] - await localForage.setItem('workflowPieces', workflowPieces) - }, []) + // eslint-disable-next-line @typescript-eslint/no-dynamic-delete + delete workflowPieces[id]; + await localForage.setItem("workflowPieces", workflowPieces); + }, []); const fetchWorkflowPieceById = useCallback(async (id: string) => { - const workflowPieces = await localForage.getItem("workflowPieces") + const workflowPieces = await localForage.getItem("workflowPieces"); if (workflowPieces !== null) { - return workflowPieces[id] + return workflowPieces[id]; } - }, []) + }, []); const value: IWorkflowPieceContext = { fetchWorkflowPieceById, @@ -64,13 +72,13 @@ const WorkflowPiecesProvider: React.FC<{ children: React.ReactNode }> = ({ child setForageWorkflowPieces, clearForageWorkflowPieces, setForageWorkflowPiecesOutputSchema, - } + }; return ( {children} ); -} +}; export default WorkflowPiecesProvider; diff --git a/frontend/src/context/workflows/workflows-editor.context/workflow-settings-data.context.tsx b/frontend/src/context/workflows/workflows-editor.context/workflow-settings-data.context.tsx index fda8d06b..9d6a4f00 100644 --- a/frontend/src/context/workflows/workflows-editor.context/workflow-settings-data.context.tsx +++ b/frontend/src/context/workflows/workflows-editor.context/workflow-settings-data.context.tsx @@ -1,47 +1,49 @@ -import React, { useCallback } from 'react'; -import localForage from 'services/config/local-forage.config'; -import { createCustomContext } from 'utils'; -import { IWorkflowSettings } from '../types/settings' +import React, { useCallback } from "react"; +import localForage from "services/config/local-forage.config"; +import { createCustomContext } from "utils"; + +import { type IWorkflowSettings } from "../types/settings"; export interface IWorkflowSettingsContext { - fetchWorkflowSettingsData: () => Promise - setWorkflowSettingsData: (data: any) => Promise - clearWorkflowSettingsData: () => Promise + fetchWorkflowSettingsData: () => Promise; + setWorkflowSettingsData: (data: any) => Promise; + clearWorkflowSettingsData: () => Promise; } -export const [WorkflowSettingsDataContext, useWorkflowSettings] = createCustomContext('WorkflowSettingsContext') - -const WorkflowSettingsDataProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => { - - // Forage forms data - const fetchWorkflowSettingsData = useCallback(async () => { - const data = await localForage.getItem('workflowSettingsData') - if (data === null) { - return {} - } - return data - }, []) - - const setWorkflowSettingsData = useCallback(async (data: any) => { - await localForage.setItem('workflowSettingsData', data) - }, []) - - const clearWorkflowSettingsData = useCallback(async () => { - await localForage.setItem('workflowSettingsData', {}) - }, []) - - - const value = { - fetchWorkflowSettingsData, - setWorkflowSettingsData, - clearWorkflowSettingsData +export const [WorkflowSettingsDataContext, useWorkflowSettings] = + createCustomContext("WorkflowSettingsContext"); + +const WorkflowSettingsDataProvider: React.FC<{ children: React.ReactNode }> = ({ + children, +}) => { + // Forage forms data + const fetchWorkflowSettingsData = useCallback(async () => { + const data = await localForage.getItem("workflowSettingsData"); + if (data === null) { + return {}; } - - return ( - - {children} - - ); -} - -export default WorkflowSettingsDataProvider; \ No newline at end of file + return data; + }, []); + + const setWorkflowSettingsData = useCallback(async (data: any) => { + await localForage.setItem("workflowSettingsData", data); + }, []); + + const clearWorkflowSettingsData = useCallback(async () => { + await localForage.setItem("workflowSettingsData", {}); + }, []); + + const value = { + fetchWorkflowSettingsData, + setWorkflowSettingsData, + clearWorkflowSettingsData, + }; + + return ( + + {children} + + ); +}; + +export default WorkflowSettingsDataProvider; diff --git a/frontend/src/context/workflows/workflows.context.tsx b/frontend/src/context/workflows/workflows.context.tsx index cc7ba4f2..51a58d66 100644 --- a/frontend/src/context/workflows/workflows.context.tsx +++ b/frontend/src/context/workflows/workflows.context.tsx @@ -1,172 +1,214 @@ -import { FC, useCallback, useEffect, useMemo, useState } from 'react' -import { toast } from 'react-toastify' -import { - IWorkflow, - IGetWorkflowResponseInterface, - useAuthenticatedDeleteWorkflowId, - useAuthenticatedGetWorkflows, - useAuthenticatedPostWorkflowRunId, - useAuthenticatedGetWorkflowId -} from 'services/requests/workflow' - - +import { type FC, useCallback, useEffect, useMemo, useState } from "react"; +import { toast } from "react-toastify"; import { useAuthenticatedGetWorkflowRuns, - IGetWorkflowRunsResponseInterface, + type IGetWorkflowRunsResponseInterface, useAuthenticatedGetWorkflowRunTasks, useAuthenticatedGetWorkflowRunTaskLogs, useAuthenticatedGetWorkflowRunTaskResult, - IGetWorkflowRunTasksResponseInterface, -} from 'services/requests/runs' - -import { createCustomContext } from 'utils' + type IGetWorkflowRunTasksResponseInterface, +} from "services/requests/runs"; +import { + type IWorkflow, + type IGetWorkflowResponseInterface, + useAuthenticatedDeleteWorkflowId, + useAuthenticatedGetWorkflows, + useAuthenticatedPostWorkflowRunId, + useAuthenticatedGetWorkflowId, +} from "services/requests/workflow"; +import { createCustomContext } from "utils"; interface IWorkflowsContext { - workflows: IGetWorkflowResponseInterface - workflowsError: boolean - workflowsLoading: boolean - - handleDeleteWorkflow: (id: string) => Promise - handleRefreshWorkflows: () => void - handleFetchWorkflow: (id: string) => Promise - handleRunWorkflow: (id: string) => Promise - tablePage: number - setTablePage: (page: number) => void - tablePageSize: number - setTablePageSize: (pageSize: number) => void - runsTablePage: number - setRunsTablePage: (page: number) => void - runsTablePageSize: number - setRunsTablePageSize: (pageSize: number) => void - selectedWorkflow: IWorkflow | null - setSelectedWorkflow: (workflow: IWorkflow | null) => void - - workflowRuns: IGetWorkflowRunsResponseInterface - selectedWorkflowRunId: string | null - setSelectedWorkflowRunId: (workflowRunId: string | null) => void - - handleFetchWorkflowRunTasks: (page: number, pageSize: number) => Promise - handleRefreshWorkflowRuns: () => void - handleFetchWorkflowRunTaskLogs: (taskId: string, taskTryNumber: string) => Promise - handleFetchWorkflowRunTaskResult: (taskId: string, taskTryNumber: string) => Promise + workflows: IGetWorkflowResponseInterface; + workflowsError: boolean; + workflowsLoading: boolean; + + handleDeleteWorkflow: (id: string) => Promise; + handleRefreshWorkflows: () => void; + handleFetchWorkflow: (id: string) => Promise; + handleRunWorkflow: (id: string) => Promise; + tablePage: number; + setTablePage: (page: number) => void; + tablePageSize: number; + setTablePageSize: (pageSize: number) => void; + runsTablePage: number; + setRunsTablePage: (page: number) => void; + runsTablePageSize: number; + setRunsTablePageSize: (pageSize: number) => void; + selectedWorkflow: IWorkflow | null; + setSelectedWorkflow: (workflow: IWorkflow | null) => void; + + workflowRuns: IGetWorkflowRunsResponseInterface; + selectedWorkflowRunId: string | null; + setSelectedWorkflowRunId: (workflowRunId: string | null) => void; + handleFetchWorkflowRunTasks: ( + page: number, + pageSize: number, + ) => Promise; + handleRefreshWorkflowRuns: () => void; + handleFetchWorkflowRunTaskLogs: ( + taskId: string, + taskTryNumber: string, + ) => Promise; + handleFetchWorkflowRunTaskResult: ( + taskId: string, + taskTryNumber: string, + ) => Promise; } export const [WorkflowsContext, useWorkflows] = - createCustomContext('Workflows Context') + createCustomContext("Workflows Context"); interface IWorkflowsProviderProps { - children?: React.ReactNode + children?: React.ReactNode; } /** * Workflows provider. */ -export const WorkflowsProvider: FC = ({ children }) => { +export const WorkflowsProvider: FC = ({ + children, +}) => { // Workflows table settings const [tablePage, setTablePage] = useState(0); const [tablePageSize, setTablePageSize] = useState(10); // Workflow runs table settings - const [runsTablePage, setRunsTablePage] = useState(0) - const [runsTablePageSize, setRunsTablePageSize] = useState(10) + const [runsTablePage, setRunsTablePage] = useState(0); + const [runsTablePageSize, setRunsTablePageSize] = useState(10); // Store data of user interaction with table rows - const [selectedWorkflow, setSelectedWorkflow] = useState(null); - const [selectedWorkflowRunId, setSelectedWorkflowRunId] = useState(null); + const [selectedWorkflow, setSelectedWorkflow] = useState( + null, + ); + const [selectedWorkflowRunId, setSelectedWorkflowRunId] = useState< + string | null + >(null); // Requests Hooks const { data, error: workflowsError, isValidating: workflowsLoading, - mutate: workflowsRefresh - } = useAuthenticatedGetWorkflows(tablePage, tablePageSize) - + mutate: workflowsRefresh, + } = useAuthenticatedGetWorkflows(tablePage, tablePageSize); const { data: workflowRunsData, error: workflowRunError, - mutate: workflowRunsRefresh - } = useAuthenticatedGetWorkflowRuns({ workflowId: selectedWorkflow?.id.toString() || '', page: runsTablePage, pageSize: runsTablePageSize }) + mutate: workflowRunsRefresh, + } = useAuthenticatedGetWorkflowRuns({ + workflowId: selectedWorkflow?.id.toString() ?? "", + page: runsTablePage, + pageSize: runsTablePageSize, + }); - const deleteWorkflow = useAuthenticatedDeleteWorkflowId() - const fetchWorkflowById = useAuthenticatedGetWorkflowId() - const runWorkflowById = useAuthenticatedPostWorkflowRunId() - const fetchWorkflowRunTasks = useAuthenticatedGetWorkflowRunTasks() - const fetchWorkflowRunTaskLogs = useAuthenticatedGetWorkflowRunTaskLogs() - const fetchWorkflowRunTaskResult = useAuthenticatedGetWorkflowRunTaskResult() + const deleteWorkflow = useAuthenticatedDeleteWorkflowId(); + const fetchWorkflowById = useAuthenticatedGetWorkflowId(); + const runWorkflowById = useAuthenticatedPostWorkflowRunId(); + const fetchWorkflowRunTasks = useAuthenticatedGetWorkflowRunTasks(); + const fetchWorkflowRunTaskLogs = useAuthenticatedGetWorkflowRunTaskLogs(); + const fetchWorkflowRunTaskResult = useAuthenticatedGetWorkflowRunTaskResult(); useEffect(() => { - if (!!workflowsError) { - toast.error('Error loading workflows, try again later') + if (workflowsError) { + toast.error("Error loading workflows, try again later"); } - }, [workflowsError]) + }, [workflowsError]); useEffect(() => { - if (!!workflowRunError) { - toast.error('Error loading workflow runs, try again later') + if (workflowRunError) { + toast.error("Error loading workflow runs, try again later"); } - }, [workflowRunError]) - + }, [workflowRunError]); /** * Workflows data */ const workflows: IGetWorkflowResponseInterface = useMemo(() => { - return data ?? { - data: [], - metadata: { - page: 0, - last_page: 0, - records: 0, - total: 0 + return ( + data ?? { + data: [], + metadata: { + page: 0, + last_page: 0, + records: 0, + total: 0, + }, } - } - }, [data]) + ); + }, [data]); const workflowRuns: IGetWorkflowRunsResponseInterface = useMemo(() => { - return workflowRunsData ?? { - data: [], - metadata: { - page: 0, - last_page: 0, - records: 0, - total: 0 + return ( + workflowRunsData ?? { + data: [], + metadata: { + page: 0, + last_page: 0, + records: 0, + total: 0, + }, } - } - }, [workflowRunsData]) + ); + }, [workflowRunsData]); // Requests handlers - const handleFetchWorkflowRunTasks = useCallback(async (page: number = 0, pageSize: number = 100) => { - const workflowId = selectedWorkflow?.id.toString() || '' - const runId = selectedWorkflowRunId || '' - return fetchWorkflowRunTasks({ workflowId, runId, page, pageSize }) - }, [fetchWorkflowRunTasks, selectedWorkflow, selectedWorkflowRunId]) - - const handleFetchWorkflowRunTaskLogs = useCallback(async (taskId: string, taskTryNumber: string) => { - const workflowId = selectedWorkflow?.id.toString() || '' - const runId = selectedWorkflowRunId || '' - return fetchWorkflowRunTaskLogs({ workflowId, runId, taskId, taskTryNumber }) - }, [fetchWorkflowRunTaskLogs, selectedWorkflow, selectedWorkflowRunId]) + const handleFetchWorkflowRunTasks = useCallback( + async (page: number = 0, pageSize: number = 100) => { + const workflowId = selectedWorkflow?.id.toString() ?? ""; + const runId = selectedWorkflowRunId ?? ""; + return await fetchWorkflowRunTasks({ workflowId, runId, page, pageSize }); + }, + [fetchWorkflowRunTasks, selectedWorkflow, selectedWorkflowRunId], + ); - const handleFetchWorkflowRunTaskResult = useCallback(async (taskId: string, taskTryNumber: string) => { - const workflowId = selectedWorkflow?.id.toString() || '' - const runId = selectedWorkflowRunId || '' - return fetchWorkflowRunTaskResult({ workflowId, runId, taskId, taskTryNumber }) - }, [fetchWorkflowRunTaskResult, selectedWorkflow, selectedWorkflowRunId]) + const handleFetchWorkflowRunTaskLogs = useCallback( + async (taskId: string, taskTryNumber: string) => { + const workflowId = selectedWorkflow?.id.toString() ?? ""; + const runId = selectedWorkflowRunId ?? ""; + return await fetchWorkflowRunTaskLogs({ + workflowId, + runId, + taskId, + taskTryNumber, + }); + }, + [fetchWorkflowRunTaskLogs, selectedWorkflow, selectedWorkflowRunId], + ); + const handleFetchWorkflowRunTaskResult = useCallback( + async (taskId: string, taskTryNumber: string) => { + const workflowId = selectedWorkflow?.id.toString() ?? ""; + const runId = selectedWorkflowRunId ?? ""; + return await fetchWorkflowRunTaskResult({ + workflowId, + runId, + taskId, + taskTryNumber, + }); + }, + [fetchWorkflowRunTaskResult, selectedWorkflow, selectedWorkflowRunId], + ); const value: IWorkflowsContext = useMemo( () => ({ workflows, workflowsError: !!workflowsError, workflowsLoading, - handleDeleteWorkflow: (id: string) => deleteWorkflow({ id }), - handleRefreshWorkflows: () => workflowsRefresh(), - handleFetchWorkflow: (id: string) => fetchWorkflowById({ id }), - handleRunWorkflow: (id: string) => runWorkflowById({ id }), - handleFetchWorkflowRunTaskLogs: (taskId: string, taskTryNumber: string) => handleFetchWorkflowRunTaskLogs(taskId, taskTryNumber), - handleFetchWorkflowRunTaskResult: (taskId: string, taskTryNumber: string) => handleFetchWorkflowRunTaskResult(taskId, taskTryNumber), + handleDeleteWorkflow: async (id: string) => await deleteWorkflow({ id }), + handleRefreshWorkflows: async () => await workflowsRefresh(), + handleFetchWorkflow: async (id: string) => + await fetchWorkflowById({ id }), + handleRunWorkflow: async (id: string) => await runWorkflowById({ id }), + handleFetchWorkflowRunTaskLogs: async ( + taskId: string, + taskTryNumber: string, + ) => await handleFetchWorkflowRunTaskLogs(taskId, taskTryNumber), + handleFetchWorkflowRunTaskResult: async ( + taskId: string, + taskTryNumber: string, + ) => await handleFetchWorkflowRunTaskResult(taskId, taskTryNumber), tablePage, setTablePage, tablePageSize, @@ -180,8 +222,8 @@ export const WorkflowsProvider: FC = ({ children }) => workflowRuns, selectedWorkflowRunId, setSelectedWorkflowRunId, - handleRefreshWorkflowRuns: () => workflowRunsRefresh(), - handleFetchWorkflowRunTasks: handleFetchWorkflowRunTasks + handleRefreshWorkflowRuns: async () => await workflowRunsRefresh(), + handleFetchWorkflowRunTasks, }), [ workflows, @@ -207,13 +249,13 @@ export const WorkflowsProvider: FC = ({ children }) => workflowRunsRefresh, handleFetchWorkflowRunTasks, handleFetchWorkflowRunTaskLogs, - handleFetchWorkflowRunTaskResult - ] - ) + handleFetchWorkflowRunTaskResult, + ], + ); return ( {children} - ) -} + ); +}; diff --git a/frontend/src/context/workspaces/workspace-settings.context.tsx b/frontend/src/context/workspaces/workspace-settings.context.tsx index 09f7fb59..85c6e341 100644 --- a/frontend/src/context/workspaces/workspace-settings.context.tsx +++ b/frontend/src/context/workspaces/workspace-settings.context.tsx @@ -1,75 +1,77 @@ -import { FC, useCallback, useState } from 'react' -import { toast } from 'react-toastify' +import { type FC, useCallback, useState } from "react"; +import { toast } from "react-toastify"; import { - IGetOperatorsRepositoriesReleasesParams, - IGetOperatorsRepositoriesReleasesResponseInterface, - IOperatorRepository, - useAuthenticatedGetOperatorRepositories -} from 'services/requests/piece' -import { useAuthenticatedGetOperatorRepositoriesReleases } from 'services/requests/piece/get-operators-repositories-releases.request' -import { useAuthenticatedDeleteRepository } from 'services/requests/repository' - + type IGetOperatorsRepositoriesReleasesParams, + type IGetOperatorsRepositoriesReleasesResponseInterface, + type IOperatorRepository, + useAuthenticatedGetOperatorRepositories, +} from "services/requests/piece"; +import { useAuthenticatedGetOperatorRepositoriesReleases } from "services/requests/piece/get-operators-repositories-releases.request"; +import { useAuthenticatedDeleteRepository } from "services/requests/repository"; import { - IPostWorkspaceRepositoryPayload, - IPostWorkspaceRepositoryResponseInterface, - IWorkspaceSummary, + type IPostWorkspaceRepositoryPayload, + type IPostWorkspaceRepositoryResponseInterface, + type IWorkspaceSummary, useAuthenticatedGetWorkspace, - useAuthenticatedPostOperatorsRepository -} from 'services/requests/workspaces' -import { createCustomContext } from 'utils' + useAuthenticatedPostOperatorsRepository, +} from "services/requests/workspaces"; +import { createCustomContext } from "utils"; -import { useWorkspaces } from './workspaces.context' +import { useWorkspaces } from "./workspaces.context"; interface IWorkspaceSettingsContext { - workspace: IWorkspaceSummary | null + workspace: IWorkspaceSummary | null; - workspaceData: IWorkspaceSummary | undefined - workspaceDataError: boolean - workspaceDataLoading: boolean - handleRefreshWorkspaceData: () => void + workspaceData: IWorkspaceSummary | undefined; + workspaceDataError: boolean; + workspaceDataLoading: boolean; + handleRefreshWorkspaceData: () => void; - repositories: IOperatorRepository[] - repositoriesError: boolean - repositoriesLoading: boolean - handleRefreshRepositories: () => void + repositories: IOperatorRepository[]; + repositoriesError: boolean; + repositoriesLoading: boolean; + handleRefreshRepositories: () => void; handleAddRepository: ( - params: Omit - ) => Promise + params: Omit, + ) => Promise; handleFetchRepoReleases: ( - params: IGetOperatorsRepositoriesReleasesParams - ) => Promise - handleDeleteRepository: (id: string) => Promise - selectedRepositoryId: number | null - setSelectedRepositoryId: (id: number | null) => void - - defaultRepositories: IOperatorRepository[] - defaultRepositoriesError: boolean - defaultRepositoriesLoading: boolean - handleRefreshDefaultRepositories: () => void + params: IGetOperatorsRepositoriesReleasesParams, + ) => Promise; + handleDeleteRepository: (id: string) => Promise; + selectedRepositoryId: number | null; + setSelectedRepositoryId: (id: number | null) => void; + + defaultRepositories: IOperatorRepository[]; + defaultRepositoriesError: boolean; + defaultRepositoriesLoading: boolean; + handleRefreshDefaultRepositories: () => void; } export const [WorkspaceSettingsContext, useWorkspaceSettings] = - createCustomContext('Workspace Settings Context') - + createCustomContext("Workspace Settings Context"); interface IWorkspaceSettingsProviderProps { - children: React.ReactNode + children: React.ReactNode; } -export const WorkspaceSettingsProvider: FC = ({ children }) => { - const { workspace } = useWorkspaces() +export const WorkspaceSettingsProvider: FC = ({ + children, +}) => { + const { workspace } = useWorkspaces(); - const [selectedRepositoryId, setSelectedRepositoryId] = useState(null) + const [selectedRepositoryId, setSelectedRepositoryId] = useState< + number | null + >(null); // Requests hooks const { data: workspaceData, error: workspaceDataError, isValidating: workspaceDataLoading, - mutate: refreshWorkspaceData - } = useAuthenticatedGetWorkspace({ id: workspace?.id ?? '' }) - + mutate: refreshWorkspaceData, + } = useAuthenticatedGetWorkspace({ id: workspace?.id ?? "" }); + /** * @todo add pagination */ @@ -77,38 +79,43 @@ export const WorkspaceSettingsProvider: FC = ({ data: repositories, error: repositoriesError, isValidating: repositoriesLoading, - mutate: refreshRepositories - } = useAuthenticatedGetOperatorRepositories({}) + mutate: refreshRepositories, + } = useAuthenticatedGetOperatorRepositories({}); const { data: defaultRepositories, error: defaultRepositoriesError, isValidating: defaultRepositoriesLoading, - mutate: refreshDefaultRepositories - } = useAuthenticatedGetOperatorRepositories({ source: "default"}) - - const postRepository = useAuthenticatedPostOperatorsRepository({workspace: workspace?.id ?? ''}) - const handleFetchRepoReleases = useAuthenticatedGetOperatorRepositoriesReleases() - const handleDeleteRepository = useAuthenticatedDeleteRepository() - + mutate: refreshDefaultRepositories, + } = useAuthenticatedGetOperatorRepositories({ source: "default" }); + + const postRepository = useAuthenticatedPostOperatorsRepository({ + workspace: workspace?.id ?? "", + }); + const handleFetchRepoReleases = + useAuthenticatedGetOperatorRepositoriesReleases(); + const handleDeleteRepository = useAuthenticatedDeleteRepository(); + // Handlers const handleAddRepository = useCallback( - (payload: Omit) => - postRepository({ ...payload, workspace_id: workspace?.id ?? '' }) + async (payload: Omit) => + await postRepository({ ...payload, workspace_id: workspace?.id ?? "" }) .then((data) => { - toast.success(`Repository added successfully!`) - refreshWorkspaceData() - return data + toast.success(`Repository added successfully!`); + void refreshWorkspaceData(); + return data; }) .catch((e) => { - if (e.response?.status === 403){ - toast.error(`You don't have permission to add repositories to this workspace.`) - return + if (e.response?.status === 403) { + toast.error( + `You don't have permission to add repositories to this workspace.`, + ); + return; } - toast.error(`Error adding repository, try again later.`) + toast.error(`Error adding repository, try again later.`); }), - [postRepository, refreshWorkspaceData, workspace?.id] - ) + [postRepository, refreshWorkspaceData, workspace?.id], + ); return ( = ({ repositories: repositories?.data ?? [], repositoriesLoading, repositoriesError, - handleRefreshRepositories: () => refreshRepositories(), - handleRefreshWorkspaceData: () => refreshWorkspaceData(), + handleRefreshRepositories: async () => await refreshRepositories(), + handleRefreshWorkspaceData: async () => await refreshWorkspaceData(), handleAddRepository, handleFetchRepoReleases, selectedRepositoryId, @@ -130,10 +137,11 @@ export const WorkspaceSettingsProvider: FC = ({ defaultRepositories: defaultRepositories?.data ?? [], defaultRepositoriesError: !!defaultRepositoriesError, defaultRepositoriesLoading, - handleRefreshDefaultRepositories: () => refreshDefaultRepositories() + handleRefreshDefaultRepositories: async () => + await refreshDefaultRepositories(), }} > {children} - ) -} + ); +}; diff --git a/frontend/src/context/workspaces/workspaces.context.tsx b/frontend/src/context/workspaces/workspaces.context.tsx index 4b8c9153..c5dd826c 100644 --- a/frontend/src/context/workspaces/workspaces.context.tsx +++ b/frontend/src/context/workspaces/workspaces.context.tsx @@ -1,8 +1,7 @@ -import { FC, useCallback, useMemo, useState } from 'react' -import { toast } from 'react-toastify' - +import { type FC, useCallback, useMemo, useState } from "react"; +import { toast } from "react-toastify"; import { - IWorkspaceSummary, + type IWorkspaceSummary, useAuthenticatedGetWorkspaces, useAuthenticatedPostWorkspaces, useAuthenticatedDeleteWorkspaces, @@ -10,180 +9,222 @@ import { useAuthenticatedRejectWorkspaceInvite, useAuthenticatedWorkspaceInvite, useAuthenticatedRemoveUserWorkspace, - useAuthenticatedGetWorkspaceUsers -} from 'services/requests/workspaces' - -import { createCustomContext } from 'utils' + useAuthenticatedGetWorkspaceUsers, +} from "services/requests/workspaces"; +import { createCustomContext } from "utils"; interface IWorkspacesContext { - workspaces: IWorkspaceSummary[] - workspacesError: boolean - workspacesLoading: boolean - handleRefreshWorkspaces: () => void - - workspace: IWorkspaceSummary | null - handleChangeWorkspace: (id: string) => void - handleCreateWorkspace: (name: string) => Promise - handleDeleteWorkspace: (id: string) => void - handleUpdateWorkspace: (workspace: IWorkspaceSummary) => void - handleAcceptWorkspaceInvite: (id: string) => void - handleRejectWorkspaceInvite: (id: string) => void, - handleInviteUserWorkspace: (id: string, userEmail: string, permission: string) => void - handleRemoveUserWorkspace: (workspaceId: string, userId: string) => void - workspaceUsers: any - workspaceUsersRefresh: () => void - workspaceUsersTablePageSize: number - workspaceUsersTablePage: number - setWorkspaceUsersTablePageSize: (pageSize: number) => void - setWorkspaceUsersTablePage: (page: number) => void + workspaces: IWorkspaceSummary[]; + workspacesError: boolean; + workspacesLoading: boolean; + handleRefreshWorkspaces: () => void; + workspace: IWorkspaceSummary | null; + handleChangeWorkspace: (id: string) => void; + handleCreateWorkspace: (name: string) => Promise; + handleDeleteWorkspace: (id: string) => void; + handleUpdateWorkspace: (workspace: IWorkspaceSummary) => void; + handleAcceptWorkspaceInvite: (id: string) => void; + handleRejectWorkspaceInvite: (id: string) => void; + handleInviteUserWorkspace: ( + id: string, + userEmail: string, + permission: string, + ) => void; + handleRemoveUserWorkspace: (workspaceId: string, userId: string) => void; + workspaceUsers: any; + workspaceUsersRefresh: () => void; + workspaceUsersTablePageSize: number; + workspaceUsersTablePage: number; + setWorkspaceUsersTablePageSize: (pageSize: number) => void; + setWorkspaceUsersTablePage: (page: number) => void; } export const [WorkspacesContext, useWorkspaces] = - createCustomContext('Workspaces Context') + createCustomContext("Workspaces Context"); interface IWorkspacesProviderProps { - children: React.ReactNode + children: React.ReactNode; } -export const WorkspacesProvider: FC = ({ children }) => { +export const WorkspacesProvider: FC = ({ + children, +}) => { const [workspace, setWorkspace] = useState( - !!localStorage.getItem('workspace') - ? (JSON.parse(localStorage.getItem('workspace')!) as IWorkspaceSummary) - : null - ) + localStorage.getItem("workspace") + ? // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + (JSON.parse(localStorage.getItem("workspace")!) as IWorkspaceSummary) + : null, + ); - const [workspaceUsersTablePageSize, setWorkspaceUsersTablePageSize] = useState(5); - const [workspaceUsersTablePage, setWorkspaceUsersTablePage] = useState(0); + const [workspaceUsersTablePageSize, setWorkspaceUsersTablePageSize] = + useState(5); + const [workspaceUsersTablePage, setWorkspaceUsersTablePage] = + useState(0); // Requests hooks const { data, error: workspacesError, isValidating: workspacesLoading, - mutate: workspacesRefresh - } = useAuthenticatedGetWorkspaces() + mutate: workspacesRefresh, + } = useAuthenticatedGetWorkspaces(); - const { - data: workspaceUsers, - mutate: workspaceUsersRefresh - } = useAuthenticatedGetWorkspaceUsers( - workspace ? - { - workspaceId: workspace.id, - page: workspaceUsersTablePage, - pageSize: workspaceUsersTablePageSize - } : { workspaceId: '', page: workspaceUsersTablePage, pageSize: workspaceUsersTablePageSize } - ) - - const postWorkspace = useAuthenticatedPostWorkspaces() - const deleteWorkspace = useAuthenticatedDeleteWorkspaces() - - const acceptWorkspaceInvite = useAuthenticatedAcceptWorkspaceInvite() - const rejectWorkspaceInvite = useAuthenticatedRejectWorkspaceInvite() - const inviteWorkspace = useAuthenticatedWorkspaceInvite() - const removeUserWorkspace = useAuthenticatedRemoveUserWorkspace() + const { data: workspaceUsers, mutate: workspaceUsersRefresh } = + useAuthenticatedGetWorkspaceUsers( + workspace + ? { + workspaceId: workspace.id, + page: workspaceUsersTablePage, + pageSize: workspaceUsersTablePageSize, + } + : { + workspaceId: "", + page: workspaceUsersTablePage, + pageSize: workspaceUsersTablePageSize, + }, + ); + + const postWorkspace = useAuthenticatedPostWorkspaces(); + const deleteWorkspace = useAuthenticatedDeleteWorkspaces(); + + const acceptWorkspaceInvite = useAuthenticatedAcceptWorkspaceInvite(); + const rejectWorkspaceInvite = useAuthenticatedRejectWorkspaceInvite(); + const inviteWorkspace = useAuthenticatedWorkspaceInvite(); + const removeUserWorkspace = useAuthenticatedRemoveUserWorkspace(); // Memoized data - const workspaces: IWorkspaceSummary[] = useMemo(() => data ?? [], [data]) + const workspaces: IWorkspaceSummary[] = useMemo(() => data ?? [], [data]); // Handlers - const handleRemoveUserWorkspace = useCallback((workspaceId: string, userId: string) => { - if (!workspaceId || !userId) { - toast.error("Workspace and user must be defined to remove user from workspace.") - } - removeUserWorkspace({workspaceId: workspaceId, userId: userId}).then(() => { - toast.success(`User removed successfully from workspace.`) - workspacesRefresh() - }).catch((error) => { - console.log('Removing user error:', error.response.data.detail) - toast.error(error.response.data.detail) - }) - }, [removeUserWorkspace, workspacesRefresh]) - - const handleInviteUserWorkspace = useCallback((id: string, userEmail: string, permission: string) => { - if (!id) { - return false - } - inviteWorkspace({workspaceId: id, userEmail: userEmail, permission: permission}).then(() => { - toast.success(`User invited successfully`) - workspaceUsersRefresh() - }).catch((error) => { - console.log('Inviting user error:', error.response.data.detail) - toast.error(error.response.data.detail) - }) - }, [inviteWorkspace, workspaceUsersRefresh()]) - - const handleAcceptWorkspaceInvite = useCallback(async(id: string) => { - acceptWorkspaceInvite({workspaceId: id}).then(() => { - //toast.success(`Workspace invitation accepted successfully`) - workspacesRefresh() - }).catch((error) => { - // todo custom msg - console.log('Accepting workspace invitation error:', error) - toast.error('Error accepting workspace invitation, try again later') - }) - }, [acceptWorkspaceInvite, workspacesRefresh]) - - const handleRejectWorkspaceInvite = useCallback(async(id: string) => { - rejectWorkspaceInvite({workspaceId: id}).then(() => { - toast.error(`You have rejected the workspace invitation.`) - workspacesRefresh() - }).catch((error) => { - // todo custom msg - console.log('Rejecting workspace invitation error:', error) - toast.error('Error rejecting workspace invitation, try again later') - }) - }, [rejectWorkspaceInvite, workspacesRefresh]) - + const handleRemoveUserWorkspace = useCallback( + (workspaceId: string, userId: string) => { + if (!workspaceId || !userId) { + toast.error( + "Workspace and user must be defined to remove user from workspace.", + ); + } + removeUserWorkspace({ workspaceId, userId }) + .then(() => { + toast.success(`User removed successfully from workspace.`); + void workspacesRefresh(); + }) + .catch((error) => { + console.log("Removing user error:", error.response.data.detail); + toast.error(error.response.data.detail); + }); + }, + [removeUserWorkspace, workspacesRefresh], + ); + + const handleInviteUserWorkspace = useCallback( + (id: string, userEmail: string, permission: string) => { + if (!id) { + return false; + } + inviteWorkspace({ + workspaceId: id, + userEmail, + permission, + }) + .then(() => { + toast.success(`User invited successfully`); + void workspaceUsersRefresh(); + }) + .catch((error) => { + console.log("Inviting user error:", error.response.data.detail); + toast.error(error.response.data.detail); + }); + }, + [inviteWorkspace, workspaceUsersRefresh()], + ); + + const handleAcceptWorkspaceInvite = useCallback( + async (id: string) => { + acceptWorkspaceInvite({ workspaceId: id }) + .then(() => { + // toast.success(`Workspace invitation accepted successfully`) + void workspacesRefresh(); + }) + .catch((error) => { + // todo custom msg + console.log("Accepting workspace invitation error:", error); + toast.error("Error accepting workspace invitation, try again later"); + }); + }, + [acceptWorkspaceInvite, workspacesRefresh], + ); + + const handleRejectWorkspaceInvite = useCallback( + async (id: string) => { + rejectWorkspaceInvite({ workspaceId: id }) + .then(() => { + toast.error(`You have rejected the workspace invitation.`); + void workspacesRefresh(); + }) + .catch((error) => { + // todo custom msg + console.log("Rejecting workspace invitation error:", error); + toast.error("Error rejecting workspace invitation, try again later"); + }); + }, + [rejectWorkspaceInvite, workspacesRefresh], + ); const handleCreateWorkspace = useCallback( - (name: string) => - postWorkspace({ name }) + async (name: string) => + await postWorkspace({ name }) .then((data) => { - toast.success(`Workflow ${name} created successfully`) - workspacesRefresh() - return data + toast.success(`Workflow ${name} created successfully`); + void workspacesRefresh(); + return data; }) .catch(() => { - toast.error('Error creating workspace, try again later') + toast.error("Error creating workspace, try again later"); }), - [postWorkspace, workspacesRefresh] - ) + [postWorkspace, workspacesRefresh], + ); const handleUpdateWorkspace = useCallback((workspace: IWorkspaceSummary) => { - setWorkspace(workspace) - localStorage.setItem('workspace', JSON.stringify(workspace)) - }, []) + setWorkspace(workspace); + localStorage.setItem("workspace", JSON.stringify(workspace)); + }, []); const handleChangeWorkspace = useCallback( (id: string) => { const next = - workspaces.filter((workspace) => workspace.id === id)?.[0] ?? null - //setWorkspace(next) - //localStorage.setItem('workspace', JSON.stringify(next)) - handleUpdateWorkspace(next) + workspaces.filter((workspace) => workspace.id === id)?.[0] ?? null; + // setWorkspace(next) + // localStorage.setItem('workspace', JSON.stringify(next)) + handleUpdateWorkspace(next); }, - [workspaces, handleUpdateWorkspace] - ) - - const handleDeleteWorkspace = useCallback((id: string)=>{ - deleteWorkspace({id}).then(() => { - const storageWorkspace = JSON.parse(localStorage.getItem('workspace')!) - if (storageWorkspace && storageWorkspace.id === id) { - localStorage.removeItem('workspace') - setWorkspace(null) - } - workspacesRefresh() - } - ).catch((error) => { - console.log('Deleting workspace error:', error) - if (error.response.status === 403) { - toast.error("You don't have permission to delete this workspace.") - return - } - toast.error('Error deleting workspace, try again later') - }) - }, [deleteWorkspace, workspacesRefresh]) + [workspaces, handleUpdateWorkspace], + ); + + const handleDeleteWorkspace = useCallback( + (id: string) => { + deleteWorkspace({ id }) + .then(() => { + const storageWorkspace = JSON.parse( + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + localStorage.getItem("workspace")!, + ); + if (storageWorkspace && storageWorkspace.id === id) { + localStorage.removeItem("workspace"); + setWorkspace(null); + } + void workspacesRefresh(); + }) + .catch((error) => { + console.log("Deleting workspace error:", error); + if (error.response.status === 403) { + toast.error("You don't have permission to delete this workspace."); + return; + } + toast.error("Error deleting workspace, try again later"); + }); + }, + [deleteWorkspace, workspacesRefresh], + ); return ( = ({ children }) = workspaces, workspacesError: !!workspacesError, workspacesLoading, - handleRefreshWorkspaces: () => workspacesRefresh(), + handleRefreshWorkspaces: async () => await workspacesRefresh(), workspace, handleChangeWorkspace, handleCreateWorkspace, @@ -206,10 +247,10 @@ export const WorkspacesProvider: FC = ({ children }) = workspaceUsersTablePageSize, workspaceUsersTablePage, setWorkspaceUsersTablePageSize, - setWorkspaceUsersTablePage + setWorkspaceUsersTablePage, }} > {children} - ) -} + ); +}; diff --git a/frontend/src/index.tsx b/frontend/src/index.tsx index 016040dc..a12c4262 100644 --- a/frontend/src/index.tsx +++ b/frontend/src/index.tsx @@ -1,7 +1,10 @@ -import React from "react" +import App from "modules/app/app.component"; +import React from "react"; import ReactDOM from "react-dom/client"; -import "./index.css" -import App from "modules/app/app.component" -const root = ReactDOM.createRoot(document.getElementById("root") as HTMLElement); +import "./index.css"; + +const root = ReactDOM.createRoot( + document.getElementById("root") as HTMLElement, +); root.render(); diff --git a/frontend/src/modules/app/app.component.tsx b/frontend/src/modules/app/app.component.tsx index b773cd7d..65845cf9 100644 --- a/frontend/src/modules/app/app.component.tsx +++ b/frontend/src/modules/app/app.component.tsx @@ -1,20 +1,19 @@ -import { ThemeProvider } from '@mui/material/styles'; -import CssBaseline from '@mui/material/CssBaseline' -import { FC } from 'react' -import 'react-datepicker/dist/react-datepicker.css' -import { BrowserRouter } from 'react-router-dom' -import { ToastContainer } from 'react-toastify' -import 'react-toastify/dist/ReactToastify.css' +import CssBaseline from "@mui/material/CssBaseline"; +import { ThemeProvider } from "@mui/material/styles"; +import { AuthenticationProvider } from "context/authentication"; +import { WorkspacesProvider } from "context/workspaces/workspaces.context"; +import { type FC } from "react"; +import "react-datepicker/dist/react-datepicker.css"; +import { BrowserRouter } from "react-router-dom"; +import { ToastContainer } from "react-toastify"; +import "react-toastify/dist/ReactToastify.css"; +import { SWRConfig } from "swr"; -import { AuthenticationProvider } from 'context/authentication' +import ApplicationRoutes from "./router/application-routes.component"; +import { theme } from "./theme.config"; -import ApplicationRoutes from './router/application-routes.component' -import { theme } from './theme.config' - -import 'ag-grid-community/dist/styles/ag-grid.css' -import 'ag-grid-community/dist/styles/ag-theme-material.css' -import { WorkspacesProvider } from 'context/workspaces/workspaces.context' -import { SWRConfig } from 'swr' +import "ag-grid-community/dist/styles/ag-grid.css"; +import "ag-grid-community/dist/styles/ag-theme-material.css"; /** * @todo add more things such as Toast Container and Auth Provider @@ -24,15 +23,15 @@ export const App: FC = () => ( - - - - - - - + + + + + + + -) +); -export default App +export default App; diff --git a/frontend/src/modules/app/router/application-routes.component.tsx b/frontend/src/modules/app/router/application-routes.component.tsx index e5e57a0a..694d0a29 100644 --- a/frontend/src/modules/app/router/application-routes.component.tsx +++ b/frontend/src/modules/app/router/application-routes.component.tsx @@ -1,17 +1,15 @@ -import { FC } from 'react' -import { Navigate, Route, Routes } from 'react-router-dom' - -import { PrivateRoute } from './private-route.component' -import { PublicRoute } from './public-route.component' - -import SignInPage from 'pages/public/sign-in/sign-in-page.component' -import SignUpPage from 'pages/public/sign-up/sign-up-page.component' - +import { WorkflowsEditorPage, WorkflowsPage } from "pages/private/workflows/"; import { - WorkflowsEditorPage, - WorkflowsPage -} from 'pages/private/workflows/' -import { WorkspacesPage, WorkspaceSettingsPage } from 'pages/private/workspaces' + WorkspacesPage, + WorkspaceSettingsPage, +} from "pages/private/workspaces"; +import SignInPage from "pages/public/sign-in/sign-in-page.component"; +import SignUpPage from "pages/public/sign-up/sign-up-page.component"; +import { type FC } from "react"; +import { Navigate, Route, Routes } from "react-router-dom"; + +import { PrivateRoute } from "./private-route.component"; +import { PublicRoute } from "./public-route.component"; /** * Application router @@ -22,56 +20,60 @@ import { WorkspacesPage, WorkspaceSettingsPage } from 'pages/private/workspaces' */ export const ApplicationRoutes: FC = () => ( - } /> + } /> } /> } /> {/** @todo implement page */}

Recover password

} /> } /> } /> } + path="/workspace-settings" + element={ + + } /> } /> } + path="/workflows-editor" + element={ + + } /> {/** @todo implement page */}

404 not found

} /> } /> - } /> + } />
-) +); -export default ApplicationRoutes +export default ApplicationRoutes; diff --git a/frontend/src/modules/app/router/private-route.component.tsx b/frontend/src/modules/app/router/private-route.component.tsx index 931129eb..c0331a06 100644 --- a/frontend/src/modules/app/router/private-route.component.tsx +++ b/frontend/src/modules/app/router/private-route.component.tsx @@ -1,19 +1,19 @@ -import { FC } from 'react' -import { Navigate } from 'react-router-dom' -import { useAuthentication } from 'context/authentication' -import { useWorkspaces } from 'context/workspaces/workspaces.context' +import { useAuthentication } from "context/authentication"; +import { useWorkspaces } from "context/workspaces/workspaces.context"; +import { type FC } from "react"; +import { Navigate } from "react-router-dom"; interface IPrivateRouteProps { /** * @todo type properly */ - component: any + component: any; /** * `true` if this route is accessible only after selecting a workspace * @default false * */ - requireWorkspace?: boolean + requireWorkspace?: boolean; } /** @@ -21,10 +21,10 @@ interface IPrivateRouteProps { */ export const PrivateRoute: FC = ({ component: Component, - requireWorkspace + requireWorkspace, }) => { - const { isLogged } = useAuthentication() - const { workspace } = useWorkspaces() + const { isLogged } = useAuthentication(); + const { workspace } = useWorkspaces(); /** * @todo simplify, **especially** if we have to add another state (maybe state machine?) @@ -41,13 +41,13 @@ export const PrivateRoute: FC = ({ switch (true) { case isLogged && requireWorkspace && !workspace: - return + return ; case isLogged && requireWorkspace && !!workspace: case isLogged && !requireWorkspace: - return + return ; default: - return + return ; } -} +}; diff --git a/frontend/src/modules/app/router/public-route.component.tsx b/frontend/src/modules/app/router/public-route.component.tsx index f1f4692f..2fa5563e 100644 --- a/frontend/src/modules/app/router/public-route.component.tsx +++ b/frontend/src/modules/app/router/public-route.component.tsx @@ -1,17 +1,17 @@ -import { FC } from "react" -import { Navigate } from "react-router-dom" -import { useAuthentication } from "context/authentication" +import { useAuthentication } from "context/authentication"; +import { type FC } from "react"; +import { Navigate } from "react-router-dom"; export interface IPublicRouteProps { /** * @todo type properly */ - component: any + component: any; /** * `true` if this route is accessible only for not authenticated users * @default false * */ - publicOnly?: boolean + publicOnly?: boolean; } /** @@ -21,8 +21,8 @@ export const PublicRoute: FC = ({ publicOnly, component: Component, }) => { - const { isLogged } = useAuthentication() - return publicOnly && isLogged ? : -} + const { isLogged } = useAuthentication(); + return publicOnly && isLogged ? : ; +}; -export default PublicRoute +export default PublicRoute; diff --git a/frontend/src/modules/app/theme.config.ts b/frontend/src/modules/app/theme.config.ts index dd9a7f3f..b76333d7 100644 --- a/frontend/src/modules/app/theme.config.ts +++ b/frontend/src/modules/app/theme.config.ts @@ -1,31 +1,31 @@ -//import { createTheme } from '@material-ui/core' -import { createTheme } from '@mui/material/styles'; +// import { createTheme } from '@material-ui/core' +import { createTheme } from "@mui/material/styles"; // Theme creation: https://bareynol.github.io/mui-theme-creator/ // TODO - make this styles work export const theme = createTheme({ palette: { - //type: 'light', + // type: 'light', primary: { - main: '#323c3d' + main: "#323c3d", }, secondary: { - main: '#f50057' + main: "#f50057", }, background: { - default: '#f1f3f3' - } + default: "#f1f3f3", + }, }, typography: { h1: { fontSize: 30, - marginLeft: 30 + marginLeft: 30, }, h2: { - fontSize: 25 + fontSize: 25, }, h3: { - fontSize: 20 + fontSize: 20, }, // h4: { // fontSize: 15 @@ -33,7 +33,7 @@ export const theme = createTheme({ // h5: { // fontSize: 10 // } - } -}) + }, +}); -export default theme +export default theme; diff --git a/frontend/src/modules/layout/index.ts b/frontend/src/modules/layout/index.ts index 3bb4ad2f..7045f5cd 100644 --- a/frontend/src/modules/layout/index.ts +++ b/frontend/src/modules/layout/index.ts @@ -1,2 +1,2 @@ -export * from './private-layout/private-layout.component' -export * from './public-layout/public-layout.component' +export * from "./private-layout/private-layout.component"; +export * from "./public-layout/public-layout.component"; diff --git a/frontend/src/modules/layout/private-layout/header/drawer-menu-item.component.tsx b/frontend/src/modules/layout/private-layout/header/drawer-menu-item.component.tsx index 17870889..f4e18b72 100644 --- a/frontend/src/modules/layout/private-layout/header/drawer-menu-item.component.tsx +++ b/frontend/src/modules/layout/private-layout/header/drawer-menu-item.component.tsx @@ -2,19 +2,19 @@ import { ListItem, ListItemButton, ListItemIcon, - ListItemText -} from '@mui/material' -import Tooltip from '@mui/material/Tooltip' -import { FC, ReactNode } from 'react' + ListItemText, +} from "@mui/material"; +import Tooltip from "@mui/material/Tooltip"; +import { type FC, type ReactNode } from "react"; interface IDrawerMenuItemProps { - disabled?: boolean - isMenuOpen: boolean - selected?: boolean - icon: ReactNode - label: string - onClick: () => void - className?: string + disabled?: boolean; + isMenuOpen: boolean; + selected?: boolean; + icon: ReactNode; + label: string; + onClick: () => void; + className?: string; } export const DrawerMenuItem: FC = ({ @@ -23,39 +23,39 @@ export const DrawerMenuItem: FC = ({ selected, icon, label, - onClick + onClick, }) => { return ( - + {icon} - ) -} + ); +}; diff --git a/frontend/src/modules/layout/private-layout/header/drawer-menu.component.tsx b/frontend/src/modules/layout/private-layout/header/drawer-menu.component.tsx index 9c1722a3..bab41a98 100644 --- a/frontend/src/modules/layout/private-layout/header/drawer-menu.component.tsx +++ b/frontend/src/modules/layout/private-layout/header/drawer-menu.component.tsx @@ -6,88 +6,86 @@ import { Logout as LogoutIcon, Person as PersonIcon, Toc, - Workspaces -} from '@mui/icons-material' + Workspaces, +} from "@mui/icons-material"; +import MenuIcon from "@mui/icons-material/Menu"; import { Box, Divider, IconButton, List, Toolbar, - useTheme -} from '@mui/material' -import { FC } from 'react' -import { useLocation, useNavigate } from 'react-router-dom' -import MenuIcon from '@mui/icons-material/Menu' -import { useAuthentication } from 'context/authentication' -import { useWorkspaces } from 'context/workspaces/workspaces.context' -import { DrawerMenuItem } from './drawer-menu-item.component' -import { AppBar, Drawer, DrawerHeader } from './drawer-menu.style' + useTheme, +} from "@mui/material"; +import { useAuthentication } from "context/authentication"; +import { useWorkspaces } from "context/workspaces/workspaces.context"; +import { type FC } from "react"; +import { useLocation, useNavigate } from "react-router-dom"; +import { DrawerMenuItem } from "./drawer-menu-item.component"; +import { AppBar, Drawer, DrawerHeader } from "./drawer-menu.style"; interface IDrawerMenuProps { - isOpen: boolean - handleClose: () => void + isOpen: boolean; + handleClose: () => void; } /** * Drawer menu. * @todo move AppBar into its own component (or to header.component) */ -export const DrawerMenu: FC = ({ - isOpen, - handleClose -}) => { - const theme = useTheme() - const { logout } = useAuthentication() - const navigate = useNavigate() - const { pathname } = useLocation() - const { workspace } = useWorkspaces() +export const DrawerMenu: FC = ({ isOpen, handleClose }) => { + const theme = useTheme(); + const { logout } = useAuthentication(); + const navigate = useNavigate(); + const { pathname } = useLocation(); + const { workspace } = useWorkspaces(); return ( - - + + - - {theme.direction === 'rtl' ? : } + + {theme.direction === "rtl" ? : } logo - !!workspace - ? navigate('/workspace-settings') - : null /* go to selected workspace setting */ + () => { + if (workspace) { + navigate("/workspace-settings"); + } + } /* go to selected workspace setting */ } > {workspace?.workspace_name ? workspace?.workspace_name - : 'No workspace selected'} + : "No workspace selected"} - + - {theme.direction === 'rtl' ? ( + {theme.direction === "rtl" ? ( ) : ( @@ -97,31 +95,35 @@ export const DrawerMenu: FC = ({ navigate('/workspaces')} + selected={pathname === "/workspaces"} + onClick={() => { + navigate("/workspaces"); + }} icon={} - label={'Workspaces'} + label={"Workspaces"} isMenuOpen={isOpen} /> - workspace?.id ? navigate('/workflows') : '' - } + selected={pathname === "/workflows"} + onClick={() => { + if (workspace?.id) navigate("/workflows"); + }} icon={} - label={'Workflows'} + label={"Workflows"} isMenuOpen={isOpen} disabled={!workspace?.id} /> (workspace?.id ? navigate('/workflows-editor') : '')} + selected={pathname === "/workflows-editor"} + onClick={() => { + if (workspace?.id) navigate("/workflows-editor"); + }} icon={} - label={'Workflow Editor'} + label={"Workflow Editor"} isMenuOpen={isOpen} disabled={!workspace?.id} /> @@ -129,22 +131,26 @@ export const DrawerMenu: FC = ({ navigate('/profile')} + selected={pathname === "/profile"} + onClick={() => { + navigate("/profile"); + }} icon={} - label={'Profile'} + label={"Profile"} isMenuOpen={isOpen} disabled /> logout()} + onClick={() => { + logout(); + }} icon={} - label={'Logout'} + label={"Logout"} isMenuOpen={isOpen} /> - ) -} + ); +}; diff --git a/frontend/src/modules/layout/private-layout/header/drawer-menu.style.ts b/frontend/src/modules/layout/private-layout/header/drawer-menu.style.ts index 334870a8..0645af34 100644 --- a/frontend/src/modules/layout/private-layout/header/drawer-menu.style.ts +++ b/frontend/src/modules/layout/private-layout/header/drawer-menu.style.ts @@ -1,9 +1,10 @@ -import MuiAppBar, { AppBarProps as MuiAppBarProps } from '@mui/material/AppBar'; +import MuiAppBar, { + type AppBarProps as MuiAppBarProps, +} from "@mui/material/AppBar"; +import MuiDrawer from "@mui/material/Drawer"; +import { styled, type Theme, type CSSObject } from "@mui/material/styles"; -import { styled, Theme, CSSObject } from '@mui/material/styles' -import MuiDrawer from '@mui/material/Drawer' - -const drawerWidth = 270 +const drawerWidth = 270; interface AppBarProps extends MuiAppBarProps { open?: boolean; @@ -11,91 +12,91 @@ interface AppBarProps extends MuiAppBarProps { const openedMixin = (theme: Theme): CSSObject => ({ width: drawerWidth, - transition: theme.transitions.create('width', { + transition: theme.transitions.create("width", { easing: theme.transitions.easing.sharp, - duration: theme.transitions.duration.enteringScreen + duration: theme.transitions.duration.enteringScreen, }), - overflowX: 'hidden' -}) + overflowX: "hidden", +}); const closedMixin = (theme: Theme): CSSObject => ({ - transition: theme.transitions.create('width', { + transition: theme.transitions.create("width", { easing: theme.transitions.easing.sharp, - duration: theme.transitions.duration.leavingScreen + duration: theme.transitions.duration.leavingScreen, }), - overflowX: 'hidden', + overflowX: "hidden", width: `calc(${theme.spacing(7)} + 1px)`, - [theme.breakpoints.up('sm')]: { - width: `calc(${theme.spacing(8)} + 1px)` - } -}) + [theme.breakpoints.up("sm")]: { + width: `calc(${theme.spacing(8)} + 1px)`, + }, +}); -export const DrawerHeaderStyled = styled('div')(({ theme }) => ({ - display: 'flex', - alignItems: 'center', - justifyContent: 'flex-end', +export const DrawerHeaderStyled = styled("div")(({ theme }) => ({ + display: "flex", + alignItems: "center", + justifyContent: "flex-end", padding: theme.spacing(0, 1), // necessary for content to be below app bar - ...theme.mixins.toolbar -})) + ...theme.mixins.toolbar, +})); export const DrawerStyled = styled(MuiDrawer, { - shouldForwardProp: (prop) => prop !== 'open' + shouldForwardProp: (prop) => prop !== "open", })(({ theme, open }) => ({ width: drawerWidth, flexShrink: 0, - whiteSpace: 'nowrap', - boxSizing: 'border-box', + whiteSpace: "nowrap", + boxSizing: "border-box", ...(open && { ...openedMixin(theme), - '& .MuiDrawer-paper': openedMixin(theme) + "& .MuiDrawer-paper": openedMixin(theme), }), ...(!open && { ...closedMixin(theme), - '& .MuiDrawer-paper': closedMixin(theme) - }) -})) + "& .MuiDrawer-paper": closedMixin(theme), + }), +})); -export const Drawer = styled(MuiDrawer, { shouldForwardProp: (prop) => prop !== 'open' })( - ({ theme, open }) => ({ - width: drawerWidth, - flexShrink: 0, - whiteSpace: 'nowrap', - boxSizing: 'border-box', - ...(open && { - ...openedMixin(theme), - '& .MuiDrawer-paper': openedMixin(theme), - }), - ...(!open && { - ...closedMixin(theme), - '& .MuiDrawer-paper': closedMixin(theme), - }), +export const Drawer = styled(MuiDrawer, { + shouldForwardProp: (prop) => prop !== "open", +})(({ theme, open }) => ({ + width: drawerWidth, + flexShrink: 0, + whiteSpace: "nowrap", + boxSizing: "border-box", + ...(open && { + ...openedMixin(theme), + "& .MuiDrawer-paper": openedMixin(theme), }), -); + ...(!open && { + ...closedMixin(theme), + "& .MuiDrawer-paper": closedMixin(theme), + }), +})); export const AppBar = styled(MuiAppBar, { - shouldForwardProp: (prop) => prop !== 'open', + shouldForwardProp: (prop) => prop !== "open", })(({ theme, open }) => ({ zIndex: theme.zIndex.drawer + 1, - transition: theme.transitions.create(['width', 'margin'], { + transition: theme.transitions.create(["width", "margin"], { easing: theme.transitions.easing.sharp, duration: theme.transitions.duration.leavingScreen, }), ...(open && { marginLeft: drawerWidth, width: `calc(100% - ${drawerWidth}px)`, - transition: theme.transitions.create(['width', 'margin'], { + transition: theme.transitions.create(["width", "margin"], { easing: theme.transitions.easing.sharp, duration: theme.transitions.duration.enteringScreen, }), }), })); -export const DrawerHeader = styled('div')(({ theme }) => ({ - display: 'flex', - alignItems: 'center', - justifyContent: 'flex-end', +export const DrawerHeader = styled("div")(({ theme }) => ({ + display: "flex", + alignItems: "center", + justifyContent: "flex-end", padding: theme.spacing(0, 1), // necessary for content to be below app bar ...theme.mixins.toolbar, -})); \ No newline at end of file +})); diff --git a/frontend/src/modules/layout/private-layout/header/header.component.tsx b/frontend/src/modules/layout/private-layout/header/header.component.tsx index 9e9f3fc4..125072cc 100644 --- a/frontend/src/modules/layout/private-layout/header/header.component.tsx +++ b/frontend/src/modules/layout/private-layout/header/header.component.tsx @@ -1,20 +1,22 @@ -import { FC, useRef, useState } from 'react' +import { Box } from "@mui/material"; +import { type FC, useRef, useState } from "react"; -import { Box } from '@mui/material' -import { DrawerMenu } from './drawer-menu.component' +import { DrawerMenu } from "./drawer-menu.component"; export const Header: FC = () => { - const [menuOpen, setMenuOpen] = useState(false) - const barHeight = useRef(null) + const [menuOpen, setMenuOpen] = useState(false); + const barHeight = useRef(null); return ( <> setMenuOpen(!menuOpen)} + handleClose={() => { + setMenuOpen(!menuOpen); + }} /> - ) -} + ); +}; diff --git a/frontend/src/modules/layout/private-layout/private-layout.component.tsx b/frontend/src/modules/layout/private-layout/private-layout.component.tsx index ef9c99c1..94928f59 100644 --- a/frontend/src/modules/layout/private-layout/private-layout.component.tsx +++ b/frontend/src/modules/layout/private-layout/private-layout.component.tsx @@ -1,25 +1,23 @@ -import { Box, Container } from '@mui/material' -import { FC, ReactNode } from 'react' -import { Header } from './header/header.component' +import { Box, Container } from "@mui/material"; +import { type FC, type ReactNode } from "react"; -type IPrivateLayoutProps = { - children: ReactNode - sidePanel?: ReactNode +import { Header } from "./header/header.component"; + +interface IPrivateLayoutProps { + children: ReactNode; + sidePanel?: ReactNode; } -export const PrivateLayout: FC = ({ - children -}) => { +export const PrivateLayout: FC = ({ children }) => { return ( - +
- + {children} - - ) -} + ); +}; -export default PrivateLayout +export default PrivateLayout; diff --git a/frontend/src/modules/layout/public-layout/public-layout.component.tsx b/frontend/src/modules/layout/public-layout/public-layout.component.tsx index a61bf95c..af5dc129 100644 --- a/frontend/src/modules/layout/public-layout/public-layout.component.tsx +++ b/frontend/src/modules/layout/public-layout/public-layout.component.tsx @@ -1,23 +1,23 @@ -import { Box, Container, Card, CardContent } from '@mui/material' -import { FC, ReactNode } from 'react' +import { Box, Container, Card, CardContent } from "@mui/material"; +import { type FC, type ReactNode } from "react"; export const PublicLayout: FC<{ children: ReactNode }> = ({ children }) => { return ( - + - + {children} - ) -} + ); +}; -export default PublicLayout +export default PublicLayout; diff --git a/frontend/src/pages/private/workflows/index.ts b/frontend/src/pages/private/workflows/index.ts index 70544be3..04a264b8 100644 --- a/frontend/src/pages/private/workflows/index.ts +++ b/frontend/src/pages/private/workflows/index.ts @@ -1,4 +1,4 @@ -export * from './workflows/workflows-page.component' -export * from './workflows-editor/workflows-editor-page.component' -export * from './workflows/components/workflows.component' -export * from './workflows-editor/components/workflows-editor.component' +export * from "./workflows/workflows-page.component"; +export * from "./workflows-editor/workflows-editor-page.component"; +export * from "./workflows/components/workflows.component"; +export * from "./workflows-editor/components/workflows-editor.component"; diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/custom-node.component.tsx b/frontend/src/pages/private/workflows/workflows-editor/components/custom-node.component.tsx index cfd12125..3df35d07 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/components/custom-node.component.tsx +++ b/frontend/src/pages/private/workflows/workflows-editor/components/custom-node.component.tsx @@ -1,141 +1,160 @@ -import { memo } from 'react' -import { Handle, Position } from 'reactflow' -import { getUuidSlice } from 'utils' +/* eslint-disable no-prototype-builtins */ +import { memo } from "react"; +import { Handle, Position } from "reactflow"; +import { getUuidSlice } from "utils"; interface IStyleData { - iconClassName: string - iconStyle: object - label: string - module: string - nodeStyle: object - nodeType: "default" | "input" | "output" - useIcon: boolean - iconId: string + iconClassName: string; + iconStyle: object; + label: string; + module: string; + nodeStyle: object; + nodeType: "default" | "input" | "output"; + useIcon: boolean; + iconId: string; } /** * @todo improve dtypes */ export interface INodeData { - name: string - style: IStyleData - handleOriantation: "horizontal" | "vertical" - error: boolean + name: string; + style: IStyleData; + handleOriantation: "horizontal" | "vertical"; + error: boolean; } - /** * @todo make it work */ const CustomNode = memo((data: any) => { - const extendedData = data.data + const extendedData = data.data; const dominoReactflowClassTypeMap: any = { - "source": "input", - "default": "default", - "sink": "output" - } - var extendedClassExt = "" - if (extendedData?.style.nodeType === undefined || !['default', 'source', 'sink'].includes(extendedData?.style.nodeType)) { - extendedClassExt = 'default' + source: "input", + default: "default", + sink: "output", + }; + let extendedClassExt = ""; + if ( + extendedData?.style.nodeType === undefined || + !["default", "source", "sink"].includes(extendedData?.style.nodeType) + ) { + extendedClassExt = "default"; } else { - extendedClassExt = dominoReactflowClassTypeMap[extendedData?.style.nodeType] + extendedClassExt = + dominoReactflowClassTypeMap[extendedData?.style.nodeType]; } - const extendedClass = `react-flow__node-${extendedClassExt}` + const extendedClass = `react-flow__node-${extendedClassExt}`; // Handle render definition const nodeTypeRenderHandleMap: any = { - "input": { + input: { renderTargetHandle: false, - renderSourceHandle: true + renderSourceHandle: true, }, - "output": { + output: { renderTargetHandle: true, - renderSourceHandle: false + renderSourceHandle: false, }, - "default": { + default: { renderTargetHandle: true, - renderSourceHandle: true - } - } + renderSourceHandle: true, + }, + }; - var targetHandlePosition = Position.Top - var sourceHandlePosition = Position.Bottom - if (extendedData?.handleOriantation === 'horizontal') { - targetHandlePosition = Position.Left - sourceHandlePosition = Position.Right + let targetHandlePosition = Position.Top; + let sourceHandlePosition = Position.Bottom; + if (extendedData?.handleOriantation === "horizontal") { + targetHandlePosition = Position.Left; + sourceHandlePosition = Position.Right; } // // Icon - const useIcon = !!extendedData?.style?.useIcon - const iconId = useIcon && extendedData?.style?.hasOwnProperty('iconId') ? extendedData?.style?.iconId : '' + const useIcon = !!extendedData?.style?.useIcon; + const iconId = + useIcon && extendedData?.style?.hasOwnProperty("iconId") + ? extendedData?.style?.iconId + : ""; const iconClass = - useIcon && extendedData?.style?.hasOwnProperty('iconClassName') - ? - extendedData.style.iconClassName - : 'fas fa-eye' + useIcon && extendedData?.style?.hasOwnProperty("iconClassName") + ? extendedData.style.iconClassName + : "fas fa-eye"; const iconStyle = - // @ts-ignore: Unreachable code error - useIcon && extendedData?.style?.hasOwnProperty('iconStyle') ? extendedData.style.iconStyle : {} + useIcon && extendedData?.style?.hasOwnProperty("iconStyle") + ? extendedData.style.iconStyle + : {}; // // Style - var customStyle: any = { - display: 'flex', - flexDirection: 'row-reverse', - justifyContent: useIcon ? 'left' : 'center', - alignItems: 'center' - } - if (extendedData?.style.hasOwnProperty('nodeStyle')) { - customStyle = Object.assign(customStyle, extendedData.style.nodeStyle) + let customStyle: any = { + display: "flex", + flexDirection: "row-reverse", + justifyContent: useIcon ? "left" : "center", + alignItems: "center", + }; + if (extendedData?.style.hasOwnProperty("nodeStyle")) { + customStyle = Object.assign(customStyle, extendedData.style.nodeStyle); } - if(extendedData?.error){ - customStyle = Object.assign(customStyle, {backgroundColor:"#f44336",color:"#e6e6e6"}) + if (extendedData?.error) { + customStyle = Object.assign(customStyle, { + backgroundColor: "#f44336", + color: "#e6e6e6", + }); } - return (
- { - nodeTypeRenderHandleMap[extendedClassExt]['renderSourceHandle'] ? ( - - ) : "" - } -
- { - extendedData?.style?.label ? extendedData?.style?.label : extendedData?.name - } + {nodeTypeRenderHandleMap[extendedClassExt].renderSourceHandle ? ( + + ) : ( + "" + )} +
+ {extendedData?.style?.label + ? extendedData?.style?.label + : extendedData?.name}

{getUuidSlice(data.id)}

- { - useIcon ? ( -
- - - -
- ) : ( - '' - ) - } - { - nodeTypeRenderHandleMap[extendedClassExt]['renderTargetHandle'] ? ( - - ) : "" - } - + {useIcon ? ( +
+ + + +
+ ) : ( + "" + )} + {nodeTypeRenderHandleMap[extendedClassExt].renderTargetHandle ? ( + + ) : ( + "" + )}
- ) -}) + ); +}); + +CustomNode.displayName = "CustomNode"; -export default CustomNode +export default CustomNode; diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/drawer-menu-component.tsx b/frontend/src/pages/private/workflows/workflows-editor/components/drawer-menu-component.tsx index fd230001..fcf3bc2f 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/components/drawer-menu-component.tsx +++ b/frontend/src/pages/private/workflows/workflows-editor/components/drawer-menu-component.tsx @@ -1,7 +1,7 @@ import { ChevronLeft as ChevronLeftIcon, - ChevronRight as ChevronRightIcon -} from '@mui/icons-material' + ChevronRight as ChevronRightIcon, +} from "@mui/icons-material"; import { AppBar, Box, @@ -9,58 +9,56 @@ import { IconButton, ListItem, Typography, - useTheme -} from '@mui/material' -import { FC, ReactNode, useState } from 'react' + useTheme, +} from "@mui/material"; import { Drawer, - DrawerHeader -} from 'modules/layout/private-layout/header/drawer-menu.style' -import SidebarAddNode from './sidebar-add-node.component' + DrawerHeader, +} from "modules/layout/private-layout/header/drawer-menu.style"; +import { type FC, type ReactNode, useState } from "react"; +import SidebarAddNode from "./sidebar-add-node.component"; interface PermanentDrawerRightWorkflowsProps { - isOpen?: boolean - handleClose: () => void - children?: ReactNode - sidePanel?: ReactNode + isOpen?: boolean; + handleClose: () => void; + children?: ReactNode; + sidePanel?: ReactNode; } export const PermanentDrawerRightWorkflows: FC< PermanentDrawerRightWorkflowsProps > = ({ isOpen, handleClose }) => { - const theme = useTheme() - const [openDrawer, setOpenDrawer] = useState(true) + const theme = useTheme(); + const [openDrawer, setOpenDrawer] = useState(true); return ( - + - - + + {openDrawer && ( - + Pieces )} - setOpenDrawer(!openDrawer)} edge='start'> - {openDrawer ? ( - - ) : ( - - )} + { + setOpenDrawer(!openDrawer); + }} + edge="start" + > + {openDrawer ? : } {openDrawer && ( <> - + @@ -69,5 +67,5 @@ export const PermanentDrawerRightWorkflows: FC< - ) -} + ); +}; diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/piece-docs-popover.component.tsx b/frontend/src/pages/private/workflows/workflows-editor/components/piece-docs-popover.component.tsx index 038689bc..b0bb68be 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/components/piece-docs-popover.component.tsx +++ b/frontend/src/pages/private/workflows/workflows-editor/components/piece-docs-popover.component.tsx @@ -1,127 +1,195 @@ -import React from 'react'; -import { Popover, IconButton, Typography } from '@mui/material'; -import CloseIcon from '@mui/icons-material/Close'; -import DragHandleIcon from '@mui/icons-material/DragHandle'; -import Draggable from 'react-draggable'; +import CloseIcon from "@mui/icons-material/Close"; +import DragHandleIcon from "@mui/icons-material/DragHandle"; +import { Popover, IconButton, Typography } from "@mui/material"; +import React from "react"; +import Draggable from "react-draggable"; +import { type IOperator, type IIOProperty } from "services/requests/piece"; -import { IOperator, IIOProperty } from 'services/requests/piece'; +function renderPieceProperties( + operator: IOperator, + key: "input_schema" | "output_schema" | "secrets_schema", +) { + const schema = operator[key]; + const properties = schema?.properties || {}; + return Object.entries(properties).map(([key, value]) => { + const argument = value as IIOProperty; + let typeName: string = argument.type; + let valuesOptions: string[] = []; + if (argument.allOf && argument.allOf.length > 0) { + typeName = "enum"; + const typeClass = argument.allOf[0].$ref.split("/").pop(); + valuesOptions = schema?.definitions?.[typeClass].enum; + } -function renderPieceProperties(operator: IOperator, key: 'input_schema' | 'output_schema' | 'secrets_schema') { - const schema = operator[key]; - const properties = schema?.properties || {}; - return Object.entries(properties).map(([key, value]) => { - const argument = value as IIOProperty; - let typeName: string = argument.type; - let valuesOptions: string[] = []; - - if (argument.allOf && argument.allOf.length > 0) { - typeName = "enum"; - const typeClass = argument.allOf[0]['$ref'].split("/").pop(); - valuesOptions = schema?.definitions?.[typeClass].enum; - } - - return ( - - {key} [{typeName}] - {argument.description} - {argument.allOf && argument.allOf.length > 0 && ( - <> - {' Options: '} - {valuesOptions.join(", ")} - - )} - - ); - }); + return ( + + {key} [{typeName}] - {argument.description} + {argument.allOf && argument.allOf.length > 0 && ( + <> + {" Options: "} + {valuesOptions.join(", ")} + + )} + + ); + }); } interface PieceDocsPopoverProps { - operator: IOperator; - popoverOpen: boolean; - handlePopoverClose: (event: React.MouseEvent, reason: any) => void; + operator: IOperator; + popoverOpen: boolean; + handlePopoverClose: ( + event: React.MouseEvent, + reason: any, + ) => void; } -const PieceDocsPopover: React.FC = ({ operator, popoverOpen, handlePopoverClose }) => ( - - = ({ + operator, + popoverOpen, + handlePopoverClose, +}) => ( + + +
+
+ +
+ + {operator.name} + +
+ { + handlePopoverClose(event, "closeButtonClick"); }} + > + + +
+
+
+ + {operator.description} + + + {operator.source_url ? ( + + source code + + ) : ( + No source code available + )} + + + Input + + {renderPieceProperties(operator, "input_schema")} + + Output + + {renderPieceProperties(operator, "output_schema")} + {operator.secrets_schema && ( + -
-
- -
- {operator.name} -
- handlePopoverClose(event, 'closeButtonClick')}> - - -
-
-
- {operator.description} - - {operator.source_url ? ( - source code - ) : ( - No source code available - )} - - Input - {renderPieceProperties(operator, 'input_schema')} - Output - {renderPieceProperties(operator, 'output_schema')} - {operator.secrets_schema && Secrets} - {operator.secrets_schema && renderPieceProperties(operator, 'secrets_schema')} -
- - + > + Secrets +
+ )} + {operator.secrets_schema && + renderPieceProperties(operator, "secrets_schema")} +
+
+
); export default PieceDocsPopover; diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-add-node.component.tsx b/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-add-node.component.tsx index c8689ff5..1e268b76 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-add-node.component.tsx +++ b/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-add-node.component.tsx @@ -1,6 +1,4 @@ -import { FC, SyntheticEvent, useState } from 'react' - -import ExpandMoreIcon from '@mui/icons-material/ExpandMore' +import ExpandMoreIcon from "@mui/icons-material/ExpandMore"; import { Accordion, AccordionDetails, @@ -9,12 +7,13 @@ import { Box, ToggleButton, ToggleButtonGroup, - Typography -} from '@mui/material' + Typography, +} from "@mui/material"; +import { useWorkflowsEditor } from "context/workflows/workflows-editor.context"; +import { type FC, type SyntheticEvent, useState } from "react"; +import { type IOperator } from "services/requests/piece"; -import { useWorkflowsEditor } from 'context/workflows/workflows-editor.context' -import { IOperator } from 'services/requests/piece' -import PiecesSidebarNode from './sidebar-node.component' +import PiecesSidebarNode from "./sidebar-node.component"; /** * @todo cleanup comments when no longer needed @@ -27,43 +26,42 @@ const SidebarAddNode: FC = () => { repositoriesLoading, repositoryOperators, nodeDirection, - toggleNodeDirection - } = useWorkflowsEditor() + toggleNodeDirection, + } = useWorkflowsEditor(); - const [piecesMap, setPiecesMap] = useState<{ [key: string]: IOperator[] }>({}) - const [expandedRepos, setExpandedRepos] = useState([]) + const [piecesMap, setPiecesMap] = useState>({}); + const [expandedRepos, setExpandedRepos] = useState([]); /** controls if an accordion is loading operators */ const [loadingOperators, setLoadingOperators] = useState( - false - ) + false, + ); return ( - - - + + horizontal vertical @@ -83,7 +81,7 @@ const SidebarAddNode: FC = () => { {repositoriesLoading && ( - Loading repositories... + Loading repositories... )} {!repositoriesLoading && repositories.map((repo) => ( @@ -92,68 +90,64 @@ const SidebarAddNode: FC = () => { expanded={expandedRepos.includes(repo.id)} key={repo.id} onChange={(event: SyntheticEvent, expanded: boolean) => { - if (loadingOperators) return - setLoadingOperators(repo.id) + if (loadingOperators) return; + setLoadingOperators(repo.id); // Check if the repo is currently expanded - const isExpanded = expandedRepos.includes(repo.id) + const isExpanded = expandedRepos.includes(repo.id); // If the repo is already expanded, remove it from the expandedRepos array // Otherwise, add it to the expandedRepos array - setExpandedRepos(isExpanded ? - prev => prev.filter(id => id !== repo.id) : - prev => [...prev, repo.id] - ) + setExpandedRepos( + isExpanded + ? (prev) => prev.filter((id) => id !== repo.id) + : (prev) => [...prev, repo.id], + ); // If the repo is not currently expanded, load its pieces if (!isExpanded) { - setPiecesMap(prev => ({ + setPiecesMap((prev) => ({ ...prev, [repo.id]: repositoryOperators[repo.id], - })) + })); } - setLoadingOperators(false) + setLoadingOperators(false); }} > - } - > + }> {repo.label} - {!!loadingOperators && loadingOperators === repo.id && ( - Loading operators... + Loading operators... )} {expandedRepos.includes(repo.id) && - piecesMap[repo.id] && - piecesMap[repo.id].length && + piecesMap[repo.id]?.length && piecesMap[repo.id].map((operator) => ( ))} - )) - } - - ) -} + ))} + + ); +}; -export default SidebarAddNode +export default SidebarAddNode; diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component/container-resource-form.component.tsx b/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component/container-resource-form.component.tsx index 44f3cbfc..d0c4d6e9 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component/container-resource-form.component.tsx +++ b/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component/container-resource-form.component.tsx @@ -1,19 +1,15 @@ +import { Grid, Typography } from "@mui/material"; +import CheckboxInput from "components/checkbox-input"; +import NumberInput from "components/number-input"; +import { type IContainerResourceFormData } from "context/workflows/types"; import React from "react"; -import { - Grid, - Typography, -} from '@mui/material' - import * as yup from "yup"; -import { IContainerResourceFormData } from "context/workflows/types"; -import NumberInput from "components/number-input"; -import CheckboxInput from "components/checkbox-input"; // TODO check if these values make sense -const minAcceptedMemory = 128 -const minAcceptedCpu = 100 -const maxAcceptedMemory = 12800 -const maxAcceptedCpu = 10000 +const minAcceptedMemory = 128; +const minAcceptedCpu = 100; +const maxAcceptedMemory = 12800; +const maxAcceptedCpu = 10000; export const defaultContainerResources: IContainerResourceFormData = { useGpu: false, @@ -23,51 +19,57 @@ export const defaultContainerResources: IContainerResourceFormData = { }, cpu: { min: 100, - max: 100 - } -} + max: 100, + }, +}; -export const ContainerResourceFormSchema: yup.ObjectSchema = yup.object().shape({ - cpu: yup.object().shape({ - min: yup - .number() - .integer() - .typeError('Must must be a number') - .max(maxAcceptedCpu) - .min(minAcceptedCpu) - .required(), - max: yup - .number() - .integer() - .typeError('Must be a number') - .max(maxAcceptedCpu) - .when("min",([min],schema)=>schema.min(min)) - .required() - }), - memory: yup.object().shape({ - min: yup - .number() - .integer() - .max(maxAcceptedMemory) - .min(minAcceptedMemory) - .required(), - max: yup - .number() - .integer() - .typeError('Must be a number') - .max(maxAcceptedMemory) - .when("min",([min],schema)=>schema.min(min)) - .required() - }), - useGpu: yup.boolean().required(), -}); +export const ContainerResourceFormSchema: yup.ObjectSchema = + yup.object().shape({ + cpu: yup.object().shape({ + min: yup + .number() + .integer() + .typeError("Must must be a number") + .max(maxAcceptedCpu) + .min(minAcceptedCpu) + .required(), + max: yup + .number() + .integer() + .typeError("Must be a number") + .max(maxAcceptedCpu) + .when("min", ([min], schema) => schema.min(min)) + .required(), + }), + memory: yup.object().shape({ + min: yup + .number() + .integer() + .max(maxAcceptedMemory) + .min(minAcceptedMemory) + .required(), + max: yup + .number() + .integer() + .typeError("Must be a number") + .max(maxAcceptedMemory) + .when("min", ([min], schema) => schema.min(min)) + .required(), + }), + useGpu: yup.boolean().required(), + }); const ContainerResourceForm: React.FC = () => { - return ( - Container Resources + + Container Resources + { type="int" inputProps={{ min: minAcceptedCpu, - max: maxAcceptedCpu + max: maxAcceptedCpu, }} /> @@ -89,7 +91,7 @@ const ContainerResourceForm: React.FC = () => { required inputProps={{ min: minAcceptedCpu, - max: maxAcceptedCpu + max: maxAcceptedCpu, }} /> @@ -101,7 +103,7 @@ const ContainerResourceForm: React.FC = () => { required inputProps={{ min: minAcceptedMemory, - max: maxAcceptedMemory + max: maxAcceptedMemory, }} /> @@ -113,18 +115,15 @@ const ContainerResourceForm: React.FC = () => { required inputProps={{ min: minAcceptedMemory, - max: maxAcceptedMemory + max: maxAcceptedMemory, }} /> - + - ) -} + ); +}; export default ContainerResourceForm; diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component/index.tsx b/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component/index.tsx index 59c33673..755c7263 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component/index.tsx +++ b/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component/index.tsx @@ -1,51 +1,43 @@ -import React, { useCallback, useEffect, useMemo, useState } from 'react' +import ExpandMoreIcon from "@mui/icons-material/ExpandMore"; import { Drawer, Grid, Typography, Accordion, AccordionSummary, - AccordionDetails -} from '@mui/material' -import ExpandMoreIcon from '@mui/icons-material/ExpandMore'; -import { FormProvider, useForm } from 'react-hook-form'; -import * as yup from "yup" + AccordionDetails, +} from "@mui/material"; +import { type IWorkflowPieceData } from "context/workflows/types"; +import { useWorkflowsEditor } from "context/workflows/workflows-editor.context"; +import React, { useCallback, useEffect, useMemo, useState } from "react"; +import { FormProvider, useForm } from "react-hook-form"; +import { yupResolver } from "utils"; +import * as yup from "yup"; -import { useWorkflowsEditor } from 'context/workflows/workflows-editor.context' - -import PieceForm from './piece-form.component' -import { createInputsSchemaValidation } from './piece-form.component/validation' - -import ContainerResourceForm, { ContainerResourceFormSchema } from './container-resource-form.component'; - -import StorageForm, { storageFormSchema } from './storage-form.component'; - -import { IWorkflowPieceData } from 'context/workflows/types'; -import { yupResolver } from 'utils'; +import ContainerResourceForm, { + ContainerResourceFormSchema, +} from "./container-resource-form.component"; +import PieceForm from "./piece-form.component"; +import { createInputsSchemaValidation } from "./piece-form.component/validation"; +import StorageForm, { storageFormSchema } from "./storage-form.component"; interface ISidebarPieceFormProps { - formId: string, - schema: InputSchema, - title: string, - open: boolean, - onClose: (event: any) => void, + formId: string; + schema: InputSchema; + title: string; + open: boolean; + onClose: (event: any) => void; } const SidebarPieceForm: React.FC = (props) => { - const { - schema, - formId, - open, - onClose, - title, - } = props + const { schema, formId, open, onClose, title } = props; const { setForageWorkflowPiecesData, fetchForageWorkflowPiecesDataById, setForageWorkflowPiecesOutputSchema, clearDownstreamDataById, - } = useWorkflowsEditor() + } = useWorkflowsEditor(); const SidebarPieceFormSchema = useMemo(() => { return yup.object().shape({ @@ -53,177 +45,218 @@ const SidebarPieceForm: React.FC = (props) => { containerResources: ContainerResourceFormSchema, inputs: createInputsSchemaValidation(schema), }); - }, [schema]) + }, [schema]); const resolver = yupResolver(SidebarPieceFormSchema); - const [formLoaded, setFormLoaded] = useState(false) + const [formLoaded, setFormLoaded] = useState(false); const methods = useForm({ resolver, - mode: "onChange" - }) - const { trigger, reset } = methods - const data = methods.watch() + mode: "onChange", + }); + const { trigger, reset } = methods; + const data = methods.watch(); const loadData = useCallback(async () => { - setFormLoaded(false) - const data = await fetchForageWorkflowPiecesDataById(formId) + setFormLoaded(false); + const data = await fetchForageWorkflowPiecesDataById(formId); if (data) { - reset(data) // put forage data on form if exist + reset(data); // put forage data on form if exist } else { - reset() + reset(); } - trigger() - setFormLoaded(true) - }, [formId, fetchForageWorkflowPiecesDataById, reset, trigger]) + void trigger(); + setFormLoaded(true); + }, [formId, fetchForageWorkflowPiecesDataById, reset, trigger]); const updateOutputSchema = useCallback(async () => { if (schema?.properties) { - const outputSchemaProperty = Object.keys(schema.properties).find((key) => { - const inputSchema = schema.properties[key] - return ( - "items" in inputSchema && - "$ref" in inputSchema.items && - inputSchema.items.$ref === '#/definitions/OutputArgsModel' - ) - }) + const outputSchemaProperty = Object.keys(schema.properties).find( + (key) => { + const inputSchema = schema.properties[key]; + return ( + "items" in inputSchema && + "$ref" in inputSchema.items && + inputSchema.items.$ref === "#/definitions/OutputArgsModel" + ); + }, + ); if (outputSchemaProperty && data?.inputs?.[outputSchemaProperty]?.value) { - const formsData = data.inputs[outputSchemaProperty].value - const newProperties = formsData.reduce((acc: any, cur: { value: { type: string; name: string; description: any; }; }) => { - let defaultValue: any = "" - let newProperties = {} - - if (cur.value.type === "integer") { - defaultValue = 1 - } else if (cur.value.type === "float") { - defaultValue = 1.1 - } else if (cur.value.type === "boolean") { - defaultValue = false - } - - if (cur.value.type === "array") { - newProperties = { - [cur.value.name as string]: { - items: { - type: "string" - }, - description: cur.value.description, - title: cur.value.name, - type: cur.value.type, - } + const formsData = data.inputs[outputSchemaProperty].value; + const newProperties = formsData.reduce( + ( + acc: any, + cur: { value: { type: string; name: string; description: any } }, + ) => { + let defaultValue: any = ""; + let newProperties = {}; + + if (cur.value.type === "integer") { + defaultValue = 1; + } else if (cur.value.type === "float") { + defaultValue = 1.1; + } else if (cur.value.type === "boolean") { + defaultValue = false; } - } else { - newProperties = { - [cur.value.name as string]: { - default: defaultValue, - description: cur.value.description, - title: cur.value.name, - type: cur.value.type, - } + + if (cur.value.type === "array") { + newProperties = { + [cur.value.name]: { + items: { + type: "string", + }, + description: cur.value.description, + title: cur.value.name, + type: cur.value.type, + }, + }; + } else { + newProperties = { + [cur.value.name]: { + default: defaultValue, + description: cur.value.description, + title: cur.value.name, + type: cur.value.type, + }, + }; } - } - return { ...acc, ...newProperties } - }, {}) + return { ...acc, ...newProperties }; + }, + {}, + ); - await setForageWorkflowPiecesOutputSchema(formId, newProperties) - await clearDownstreamDataById(formId) + await setForageWorkflowPiecesOutputSchema(formId, newProperties); + await clearDownstreamDataById(formId); } } - }, [data.inputs, formId, schema.properties,clearDownstreamDataById, setForageWorkflowPiecesOutputSchema]) + }, [ + data.inputs, + formId, + schema.properties, + clearDownstreamDataById, + setForageWorkflowPiecesOutputSchema, + ]); const saveData = useCallback(async () => { if (formId && open) { - await setForageWorkflowPiecesData(formId, data as IWorkflowPieceData) - await updateOutputSchema() + await setForageWorkflowPiecesData(formId, data as IWorkflowPieceData); + await updateOutputSchema(); } - }, [formId, open, setForageWorkflowPiecesData, data, updateOutputSchema]) + }, [formId, open, setForageWorkflowPiecesData, data, updateOutputSchema]); - //load forage + // load forage useEffect(() => { if (open) { - loadData() + void loadData(); } else { - reset() + reset(); } - }, [open, reset, loadData]) + }, [open, reset, loadData]); // save on forage useEffect(() => { - saveData() - }, [saveData]) + void saveData(); + }, [saveData]); return ( -
+
{title} - + -
- +
+ - Input Arguments + + Input Arguments + - Upstream + + Upstream + - {formLoaded && - - + {formLoaded && ( + + - + -
+
+ }} + > }> - + Advanced Options -
+
- } + )}
-
+
- ) -} + ); +}; export default SidebarPieceForm; diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component/piece-form.component/index.tsx b/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component/piece-form.component/index.tsx index 288aa0ac..1020598d 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component/piece-form.component/index.tsx +++ b/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component/piece-form.component/index.tsx @@ -1,10 +1,10 @@ -import React, { useCallback, useEffect, useMemo, useState } from 'react'; -import PieceFormItem from './piece-form-item.component'; -import { useFormContext } from 'react-hook-form'; -import { IWorkflowPieceData } from 'context/workflows/types'; +import { type IWorkflowPieceData } from "context/workflows/types"; +import { useWorkflowsEditor } from "context/workflows/workflows-editor.context"; +import React, { useCallback, useEffect, useMemo, useState } from "react"; +import { useFormContext } from "react-hook-form"; -import { useWorkflowsEditor } from 'context/workflows/workflows-editor.context'; -import { UpstreamOptions, getUpstreamOptions } from './upstream-options'; +import PieceFormItem from "./piece-form-item.component"; +import { type UpstreamOptions, getUpstreamOptions } from "./upstream-options"; interface PieceFormProps { formId: string; @@ -12,48 +12,57 @@ interface PieceFormProps { } const PieceForm: React.FC = ({ formId, schema }) => { - const { fetchForageWorkflowEdges, getForageWorkflowPieces } = useWorkflowsEditor() - const { control } = useFormContext() - const [upstreamOptions, setUpstreamOptions] = useState({}) + const { fetchForageWorkflowEdges, getForageWorkflowPieces } = + useWorkflowsEditor(); + const { control } = useFormContext(); + const [upstreamOptions, setUpstreamOptions] = useState({}); const shouldRender = useMemo(() => { - return schema?.properties - }, [schema]) + return schema?.properties; + }, [schema]); const handleUpstreamOptions = useCallback(async () => { if (!shouldRender) { - return + return; } const workflowPieces = await getForageWorkflowPieces(); const workflowEdges = await fetchForageWorkflowEdges(); - const upstreamOptions = getUpstreamOptions(formId, schema, workflowPieces, workflowEdges) - setUpstreamOptions(upstreamOptions) - - }, [fetchForageWorkflowEdges, formId, getForageWorkflowPieces, schema, shouldRender]) + const upstreamOptions = getUpstreamOptions( + formId, + schema, + workflowPieces, + workflowEdges, + ); + setUpstreamOptions(upstreamOptions); + }, [ + fetchForageWorkflowEdges, + formId, + getForageWorkflowPieces, + schema, + shouldRender, + ]); useEffect(() => { - handleUpstreamOptions() - }, [handleUpstreamOptions]) + void handleUpstreamOptions(); + }, [handleUpstreamOptions]); if (!shouldRender) return null; return (
- { - Object.keys(schema.properties).map(key => ( -
- -
- )) - } + {Object.keys(schema.properties).map((key) => ( +
+ +
+ ))}
); }; diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component/piece-form.component/piece-form-item.component/array-input.tsx b/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component/piece-form.component/piece-form-item.component/array-input.tsx index 5070a678..333995ff 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component/piece-form.component/piece-form-item.component/array-input.tsx +++ b/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component/piece-form.component/piece-form-item.component/array-input.tsx @@ -1,145 +1,183 @@ -import React, { useCallback, useMemo, useState } from 'react'; -import { Control, FieldArrayWithId, useFieldArray, useWatch } from 'react-hook-form'; +import AddIcon from "@mui/icons-material/Add"; +import DeleteIcon from "@mui/icons-material/Delete"; +import { Card, CardContent, IconButton, Grid } from "@mui/material"; +import CheckboxInput from "components/checkbox-input"; +import CodeEditorInput from "components/codeeditor-input"; +import DatetimeInput from "components/datetime-input"; +import NumberInput from "components/number-input"; +import SelectInput from "components/select-input"; +import TextInput from "components/text-input"; +import { + type IWorkflowPieceData, + type InputArray, +} from "context/workflows/types"; +import React, { useCallback, useMemo, useState } from "react"; +import { + type Control, + type FieldArrayWithId, + useFieldArray, + useWatch, +} from "react-hook-form"; +import { getFromUpstream } from "utils"; -import { Card, CardContent, IconButton, Grid } from '@mui/material'; -import AddIcon from '@mui/icons-material/Add'; -import DeleteIcon from '@mui/icons-material/Delete'; +import { type ArrayOption } from "../../piece-form.component/upstream-options"; -import { IWorkflowPieceData, InputArray } from 'context/workflows/types'; - -import TextInput from 'components/text-input'; -import SelectInput from 'components/select-input'; -import NumberInput from 'components/number-input'; -import CheckboxInput from 'components/checkbox-input'; -import DatetimeInput from 'components/datetime-input'; -import CodeEditorInput from 'components/codeeditor-input'; - -import SelectUpstreamInput from './select-upstream-input'; -import ObjectInputComponent from './object-input'; -import { ArrayOption } from '../../piece-form.component/upstream-options'; -import { disableCheckboxOptions } from './disableCheckboxOptions'; -import { getFromUpstream } from 'utils'; +import { disableCheckboxOptions } from "./disableCheckboxOptions"; +import ObjectInputComponent from "./object-input"; +import SelectUpstreamInput from "./select-upstream-input"; interface ArrayInputItemProps { - formId: string - inputKey: string + formId: string; + inputKey: string; schema: any; - control: Control - definitions?: any - upstreamOptions: ArrayOption + control: Control; + definitions?: any; + upstreamOptions: ArrayOption; } -const ArrayInput: React.FC = ({ formId, inputKey, schema, upstreamOptions, definitions, control }) => { - - const name = `inputs.${inputKey}.value` as `inputs.${string}.value` - const { fields: data, append, remove } = useFieldArray({ +const ArrayInput: React.FC = ({ + formId, + inputKey, + schema, + upstreamOptions, + definitions, + control, +}) => { + const name: `inputs.${string}.value` = `inputs.${inputKey}.value`; + const { + fields: data, + append, + remove, + } = useFieldArray({ name, control, - }) - const fields = data as unknown as FieldArrayWithId[] - const formsData = useWatch({ name }) + }); + const fields = data as unknown as Array>; + const formsData = useWatch({ name }); - const [enumOptions, setEnumOptions] = useState([]) + const [enumOptions, setEnumOptions] = useState([]); const subItemSchema = useMemo(() => { let subItemSchema: any = schema?.items; if (schema?.items?.$ref) { - const subItemSchemaName = schema.items.$ref.split('/').pop(); + const subItemSchemaName = schema.items.$ref.split("/").pop(); subItemSchema = definitions?.[subItemSchemaName]; } - return subItemSchema - }, [definitions, schema]) + return subItemSchema; + }, [definitions, schema]); - const disableUpstream = useMemo(()=>{ - return disableCheckboxOptions(subItemSchema) - },[subItemSchema]) + const disableUpstream = useMemo(() => { + return disableCheckboxOptions(subItemSchema); + }, [subItemSchema]); - const isFromUpstream = useCallback((index: number) => { - return formsData?.[index]?.fromUpstream ?? false - }, [formsData]) + const isFromUpstream = useCallback( + (index: number) => { + return formsData?.[index]?.fromUpstream ?? false; + }, + [formsData], + ); const elementType = useMemo(() => { if (subItemSchema?.allOf && subItemSchema.allOf.length > 0) { - const typeClass = subItemSchema.allOf[0]['$ref'].split("/").pop(); - const valuesOptions: Array = definitions?.[typeClass].enum; - setEnumOptions(valuesOptions) - return "SelectInput" - } else if ((subItemSchema?.type === 'number') && !subItemSchema?.format) { - return "NumberInput" - } else if (subItemSchema?.type === 'integer' && !subItemSchema?.format) { - return "NumberInputInt" - } else if (subItemSchema?.type === 'boolean' && !subItemSchema?.format) { + const typeClass = subItemSchema.allOf[0].$ref.split("/").pop(); + const valuesOptions: string[] = definitions?.[typeClass].enum; + setEnumOptions(valuesOptions); + return "SelectInput"; + } else if (subItemSchema?.type === "number" && !subItemSchema?.format) { + return "NumberInput"; + } else if (subItemSchema?.type === "integer" && !subItemSchema?.format) { + return "NumberInputInt"; + } else if (subItemSchema?.type === "boolean" && !subItemSchema?.format) { return "CheckboxInput"; - } else if (subItemSchema?.type === 'string' && !subItemSchema?.format && !subItemSchema?.widget) { + } else if ( + subItemSchema?.type === "string" && + !subItemSchema?.format && + !subItemSchema?.widget + ) { return "TextInput"; - } else if (subItemSchema?.type === 'string' && subItemSchema?.format === 'date') { + } else if ( + subItemSchema?.type === "string" && + subItemSchema?.format === "date" + ) { return "DateInput"; - } else if (subItemSchema?.type === 'string' && subItemSchema?.format === 'time') { + } else if ( + subItemSchema?.type === "string" && + subItemSchema?.format === "time" + ) { return "TimeInput"; - } else if (subItemSchema?.type === 'string' && subItemSchema?.format === 'date-time') { + } else if ( + subItemSchema?.type === "string" && + subItemSchema?.format === "date-time" + ) { return "DatetimeInput"; - } else if (subItemSchema?.type === 'string' && subItemSchema?.widget === 'codeeditor') { - return "CodeEditorInput" - } else if (subItemSchema?.type === 'object') { + } else if ( + subItemSchema?.type === "string" && + subItemSchema?.widget === "codeeditor" + ) { + return "CodeEditorInput"; + } else if (subItemSchema?.type === "object") { return "ObjectInput"; } else { return "Unknown"; } - }, [subItemSchema, definitions]) + }, [subItemSchema, definitions]); const handleAddInput = useCallback(() => { function empty(object: Record, fromUpstream = false) { Object.keys(object).forEach(function (k) { - if (object[k] && typeof object[k] === 'object') { + if (object[k] && typeof object[k] === "object") { return empty(object[k]); } - if(fromUpstream){ - object[k] = getFromUpstream(schema, definitions, k) + if (fromUpstream) { + object[k] = getFromUpstream(schema, definitions, k); } else { - object[k] = ''; + object[k] = ""; } }); - return object + return object; } - const defaultValue = schema.default[0] - const isObject = typeof defaultValue === "object" + const defaultValue = schema.default[0]; + const isObject = typeof defaultValue === "object"; let defaultObj = { fromUpstream: getFromUpstream(schema), upstreamArgument: "", upstreamId: "", upstreamValue: "", - value: "" - } as unknown + value: "", + } as unknown; if (isObject) { - const emptyObjValue = empty({...defaultValue}) - const emptyObjFromUpstream = empty({...defaultValue},true) + const emptyObjValue = empty({ ...defaultValue }); + const emptyObjFromUpstream = empty({ ...defaultValue }, true); defaultObj = { fromUpstream: emptyObjFromUpstream, upstreamArgument: emptyObjValue, upstreamId: emptyObjValue, upstreamValue: emptyObjValue, - value: defaultValue - } as unknown + value: defaultValue, + } as unknown; } - append([defaultObj] as any) - }, [append, definitions, schema]) + append([defaultObj] as any); + }, [append, definitions, schema]); return (
- + {schema?.title}
- - - {fields && fields.map((fieldWithId, index) => { - const { id } = fieldWithId - const fromUpstream = isFromUpstream(index) + + {fields?.map((fieldWithId, index) => { + const { id } = fieldWithId; + const fromUpstream = isFromUpstream(index); return ( = ({ formId, inputKey, schema, u borderRadius: "6px", }} > - - { remove(index) }} aria-label="Delete"> + + { + remove(index); + }} + aria-label="Delete" + > - {fromUpstream && elementType !== "ObjectInput" && ( - + = ({ formId, inputKey, schema, u )} {!fromUpstream && elementType === "SelectInput" && ( - + = ({ formId, inputKey, schema, u )} {!fromUpstream && elementType === "NumberInput" && ( - + = ({ formId, inputKey, schema, u )} {!fromUpstream && elementType === "NumberInputInt" && ( - + = ({ formId, inputKey, schema, u )} {!fromUpstream && elementType === "CheckboxInput" && ( - + = ({ formId, inputKey, schema, u )} {!fromUpstream && elementType === "TextInput" && ( - + )} {!fromUpstream && elementType === "DateInput" && ( - + = ({ formId, inputKey, schema, u )} {!fromUpstream && elementType === "TimeInput" && ( - + = ({ formId, inputKey, schema, u )} {!fromUpstream && elementType === "DatetimeInput" && ( - + = ({ formId, inputKey, schema, u )} {!fromUpstream && elementType === "CodeEditorInput" && ( - - + + )} {!fromUpstream && elementType === "Unknown" && ( - -
+ +
Unknown widget type for {subItemSchema?.title}
@@ -316,13 +318,12 @@ const ArrayInput: React.FC = ({ formId, inputKey, schema, u /> )} - ); })} ); -} +}; export default React.memo(ArrayInput); diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component/piece-form.component/piece-form-item.component/disableCheckboxOptions.ts b/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component/piece-form.component/piece-form-item.component/disableCheckboxOptions.ts index d2c9969d..e3d7aa2e 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component/piece-form.component/piece-form-item.component/disableCheckboxOptions.ts +++ b/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component/piece-form.component/piece-form-item.component/disableCheckboxOptions.ts @@ -1,14 +1,14 @@ function getFromUpstreamType(schema: InputSchemaProperty): FromUpstream { if (schema?.from_upstream) { - return schema?.from_upstream + return schema?.from_upstream; } - return "allowed" + return "allowed"; } export function disableCheckboxOptions(schema: InputSchemaProperty): boolean { let disable: boolean = false; - const fromUpstream = getFromUpstreamType(schema) + const fromUpstream = getFromUpstreamType(schema); if (fromUpstream === "allowed") { disable = false; @@ -26,5 +26,5 @@ export function disableCheckboxOptions(schema: InputSchemaProperty): boolean { disable = true; } - return disable + return disable; } diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component/piece-form.component/piece-form-item.component/index.tsx b/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component/piece-form.component/piece-form-item.component/index.tsx index 88ece59a..2e3fa493 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component/piece-form.component/piece-form-item.component/index.tsx +++ b/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component/piece-form.component/piece-form-item.component/index.tsx @@ -1,49 +1,56 @@ -import React, { useMemo } from 'react'; -import { - Box, - Grid, -} from '@mui/material'; -import { Control, useWatch } from 'react-hook-form'; - -import { IWorkflowPieceData } from 'context/workflows/types'; +import { Box, Grid } from "@mui/material"; +import CheckboxInput from "components/checkbox-input"; +import CodeEditorInput from "components/codeeditor-input"; +import DatetimeInput from "components/datetime-input"; +import NumberInput from "components/number-input"; +import SelectInput from "components/select-input"; +import TextInput from "components/text-input"; +import { type IWorkflowPieceData } from "context/workflows/types"; +import React, { useMemo } from "react"; +import { type Control, useWatch } from "react-hook-form"; -import NumberInput from 'components/number-input'; -import CheckboxInput from 'components/checkbox-input'; -import SelectInput from 'components/select-input'; -import DatetimeInput from 'components/datetime-input'; -import CodeEditorInput from 'components/codeeditor-input'; -import TextInput from 'components/text-input'; - -import SelectUpstreamInput from './select-upstream-input'; -import ArrayInput from './array-input'; +import { + type ArrayOption, + type Option, +} from "../../piece-form.component/upstream-options"; -import { ArrayOption, Option } from '../../piece-form.component/upstream-options'; -import { disableCheckboxOptions } from './disableCheckboxOptions'; +import ArrayInput from "./array-input"; +import { disableCheckboxOptions } from "./disableCheckboxOptions"; +import SelectUpstreamInput from "./select-upstream-input"; interface PieceFormItemProps { - formId: string + formId: string; schema: InputSchemaProperty; itemKey: string; - control: Control - definitions?: Definitions - upstreamOptions: Option[] | ArrayOption + control: Control; + definitions?: Definitions; + upstreamOptions: Option[] | ArrayOption; } -const PieceFormItem: React.FC = ({ formId, upstreamOptions, itemKey, schema, definitions, control }) => { - const disableUpstream = useMemo(()=>{ - return disableCheckboxOptions(schema) - },[schema]) +const PieceFormItem: React.FC = ({ + formId, + upstreamOptions, + itemKey, + schema, + definitions, + control, +}) => { + const disableUpstream = useMemo(() => { + return disableCheckboxOptions(schema); + }, [schema]); - const checkedFromUpstream = useWatch({ name: `inputs.${itemKey}.fromUpstream` }) + const checkedFromUpstream = useWatch({ + name: `inputs.${itemKey}.fromUpstream`, + }); - let inputElement: React.ReactNode = null + let inputElement: React.ReactNode = null; if (checkedFromUpstream) { - let options: Option[] = [] - if ("type" in schema && schema.type === 'array') { - options = (upstreamOptions as ArrayOption).array + let options: Option[] = []; + if ("type" in schema && schema.type === "array") { + options = (upstreamOptions as ArrayOption).array; } else { - options = upstreamOptions as Option[] + options = upstreamOptions as Option[]; } inputElement = ( @@ -51,46 +58,54 @@ const PieceFormItem: React.FC = ({ formId, upstreamOptions, name={`inputs.${itemKey}`} label={schema?.title} options={options} - />); + /> + ); } else if ("allOf" in schema && schema.allOf.length > 0) { - const typeClass = schema.allOf[0]['$ref'].split("/").pop() as string; - let enumOptions: string[] = [] + const typeClass = schema.allOf[0].$ref.split("/").pop() as string; + let enumOptions: string[] = []; - if (definitions?.[typeClass] && (definitions[typeClass]).type === "string") { - enumOptions = (definitions[typeClass] as EnumDefinition).enum + if (definitions?.[typeClass] && definitions[typeClass].type === "string") { + enumOptions = (definitions[typeClass] as EnumDefinition).enum; } - inputElement = + inputElement = ( label={itemKey} emptyValue name={`inputs.${itemKey}.value`} options={enumOptions} /> - } else if ("type" in schema && (schema.type === 'number' || schema.type === 'float')) { - - inputElement = + ); + } else if ( + "type" in schema && + (schema.type === "number" || schema.type === "float") + ) { + inputElement = ( name={`inputs.${itemKey}.value`} type="float" label={schema.title} defaultValue={schema?.default ?? 10.5} /> - } else if ("type" in schema && schema.type === 'integer') { - inputElement = + ); + } else if ("type" in schema && schema.type === "integer") { + inputElement = ( name={`inputs.${itemKey}.value`} type="int" label={schema.title} defaultValue={schema?.default ?? 10} /> - } else if ("type" in schema && schema.type === 'boolean') { - inputElement = - name={`inputs.${itemKey}.value`} - label={schema.title} - /> - } else if ("type" in schema && schema.type === 'array') { - inputElement = + ); + } else if ("type" in schema && schema.type === "boolean") { + inputElement = ( + + name={`inputs.${itemKey}.value`} + label={schema.title} + /> + ); + } else if ("type" in schema && schema.type === "array") { + inputElement = ( = ({ formId, upstreamOptions, upstreamOptions={upstreamOptions as ArrayOption} control={control} /> + ); } else if ( "type" in schema && "format" in schema && - schema.type === 'string' && - schema.format === 'date') { - inputElement = + schema.type === "string" && + schema.format === "date" + ) { + inputElement = ( name={`inputs.${itemKey}.value`} label={schema.title} type="date" - />; + /> + ); } else if ( "type" in schema && "format" in schema && - schema.type === 'string' && - schema.format === 'time') { - inputElement = + schema.type === "string" && + schema.format === "time" + ) { + inputElement = ( name={`inputs.${itemKey}.value`} label={schema.title} type="time" - />; + /> + ); } else if ( "type" in schema && "format" in schema && - schema.type === 'string' && - schema.format === 'date-time') { - inputElement = + schema.type === "string" && + schema.format === "date-time" + ) { + inputElement = ( name={`inputs.${itemKey}.value`} label={schema.title} type="date-time" - />; + /> + ); } else if ( "type" in schema && "widget" in schema && - schema.type === 'string' && - schema.widget === 'codeeditor') { - inputElement = - - name={`inputs.${itemKey}.value`} - /> + schema.type === "string" && + schema.widget === "codeeditor" + ) { + inputElement = ( + name={`inputs.${itemKey}.value`} /> + ); } else if ( "type" in schema && !("format" in schema) && - schema.type === 'string') { - inputElement = + schema.type === "string" + ) { + inputElement = ( - variant='outlined' + variant="outlined" name={`inputs.${itemKey}.value`} label={schema.title} - />; + /> + ); } else { - inputElement =
- Unknown widget type for {schema.title} -
; + inputElement = ( +
+ Unknown widget type for {schema.title} +
+ ); } return ( @@ -168,7 +194,7 @@ const PieceFormItem: React.FC = ({ formId, upstreamOptions, {inputElement} - + = ({ schema, name, upstreamOptions, definitions }) => { - const formsData = useWatch({ name }) +const ObjectInputComponent: React.FC = ({ + schema, + name, + upstreamOptions, + definitions, +}) => { + const formsData = useWatch({ name }); const itensSchema = useMemo(() => { - return (getDefinition(schema,definitions) as ObjectDefinition).properties - }, [schema, definitions]) + return (getDefinition(schema, definitions) as ObjectDefinition).properties; + }, [schema, definitions]); - const [enumOptions, setEnumOptions] = useState([]) + const [enumOptions, setEnumOptions] = useState([]); - const isFromUpstream = useCallback((key: string) => { - return (formsData?.fromUpstream[key] ?? false) as boolean - }, [formsData]) + const isFromUpstream = useCallback( + (key: string) => { + return (formsData?.fromUpstream[key] ?? false) as boolean; + }, + [formsData], + ); const defaultValues = useMemo(() => { - const defaultValues = schema.default[0] + const defaultValues = schema.default[0]; - return (defaultValues ?? {}) as Record - }, [schema]) + return (defaultValues ?? {}) as Record; + }, [schema]); const elementType = useMemo(() => { const getElementType = function (key: string) { - const schemaDefinition = getDefinition(schema,definitions) + const schemaDefinition = getDefinition(schema, definitions); if ("properties" in schemaDefinition) { - const itemSchemaDefinition = getDefinition(schemaDefinition.properties[key],definitions) - if("enum" in itemSchemaDefinition){ - const valuesOptions = (itemSchemaDefinition as EnumDefinition).enum; - setEnumOptions(valuesOptions) - return "SelectInput" + const itemSchemaDefinition = getDefinition( + schemaDefinition.properties[key], + definitions, + ); + if ("enum" in itemSchemaDefinition) { + const valuesOptions = itemSchemaDefinition.enum; + setEnumOptions(valuesOptions); + return "SelectInput"; } - return "TextInput" + return "TextInput"; } else { return "TextInput"; } - } - - return Object.keys(defaultValues).reduce>((acc, cur) => { - acc[cur] = getElementType(cur) - return acc - }, {}) - - }, [defaultValues, schema, definitions]) + }; + return Object.keys(defaultValues).reduce>( + (acc, cur) => { + acc[cur] = getElementType(cur); + return acc; + }, + {}, + ); + }, [defaultValues, schema, definitions]); return ( <> {Object.entries(defaultValues).map(([key, value]) => { - const fromUpstream = isFromUpstream(key) - const disableUpstream = disableCheckboxOptions(itensSchema[key] as any) + const fromUpstream = isFromUpstream(key); + const disableUpstream = disableCheckboxOptions(itensSchema[key] as any); return ( = ({ schema, name, upstreamOptions, d justifyContent="space-between" sx={{ marginBottom: 1 }} > - {fromUpstream ? + {fromUpstream ? ( = ({ schema, name, upstreamOptions, d object /> - : + ) : ( - {elementType[key] === 'TextInput' && + {elementType[key] === "TextInput" && ( - } - {elementType[key] === 'SelectInput' && + )} + {elementType[key] === "SelectInput" && ( - } + )} - } - + )} + - ) + ); })} ); -} +}; export default ObjectInputComponent; diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component/piece-form.component/piece-form-item.component/select-upstream-input.tsx b/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component/piece-form.component/piece-form-item.component/select-upstream-input.tsx index 9cf3d19f..e1a62bb3 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component/piece-form.component/piece-form-item.component/select-upstream-input.tsx +++ b/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component/piece-form.component/piece-form-item.component/select-upstream-input.tsx @@ -1,55 +1,84 @@ -import { FormControl, FormHelperText, InputLabel, MenuItem, Select, SelectChangeEvent } from '@mui/material'; -import React, { useCallback } from 'react'; -import { Controller, useFormContext } from 'react-hook-form'; -import { Option } from '../../piece-form.component/upstream-options'; -import { IWorkflowPieceData } from 'context/workflows/types'; -import { fetchFromObject } from 'utils'; +import { + FormControl, + FormHelperText, + InputLabel, + MenuItem, + Select, + type SelectChangeEvent, +} from "@mui/material"; +import { type IWorkflowPieceData } from "context/workflows/types"; +import React, { useCallback } from "react"; +import { Controller, useFormContext } from "react-hook-form"; +import { fetchFromObject } from "utils"; -type ObjectName = `inputs.${string}.value.${number}.upstreamValue.${string}` -type Name = `inputs.${string}` -type Props = { - label: string - name: Name - options: Option[] - object?: false -} | { - label: string - name: ObjectName - options: Option[] - object: true -} +import { type Option } from "../../piece-form.component/upstream-options"; -const SelectUpstreamInput: React.FC = ({ options, label, name, object }) => { - const { setValue, control, formState: { errors } } = useFormContext() +type ObjectName = `inputs.${string}.value.${number}.upstreamValue.${string}`; +type Name = `inputs.${string}`; +type Props = + | { + label: string; + name: Name; + options: Option[]; + object?: false; + } + | { + label: string; + name: ObjectName; + options: Option[]; + object: true; + }; - const handleSelectChange = useCallback((event: SelectChangeEvent, onChange: (e: any) => void) => { - const value = event.target.value - const upstream = options.find(op => op?.value === value) as Option - let nameArgument = "" - let nameId = "" +const SelectUpstreamInput: React.FC = ({ + options, + label, + name, + object, +}) => { + const { + setValue, + control, + formState: { errors }, + } = useFormContext(); - if (object) { - nameArgument = name.replace(`.upstreamValue.`, ".upstreamArgument.") - nameId = name.replace(`.upstreamValue.`, ".upstreamId.") + const handleSelectChange = useCallback( + (event: SelectChangeEvent, onChange: (e: any) => void) => { + const value = event.target.value; + const upstream = options.find((op) => op?.value === value) as Option; + let nameArgument = ""; + let nameId = ""; - } else { - nameArgument = `${name}.upstreamArgument` - nameId = `${name}.upstreamId` - } + if (object) { + nameArgument = name.replace(`.upstreamValue.`, ".upstreamArgument."); + nameId = name.replace(`.upstreamValue.`, ".upstreamId."); + } else { + nameArgument = `${name}.upstreamArgument`; + nameId = `${name}.upstreamId`; + } - setValue(nameArgument as `inputs.${string}.upstreamArgument`, upstream.argument) - setValue(nameId as `inputs.${string}.upstreamId`, upstream.id) - onChange(event) - }, [name, object, options, setValue]); + setValue( + nameArgument as `inputs.${string}.upstreamArgument`, + upstream.argument, + ); + setValue(nameId as `inputs.${string}.upstreamId`, upstream.id); + onChange(event); + }, + [name, object, options, setValue], + ); - const error = fetchFromObject(errors, object ? name as ObjectName : `${name}.upstreamValue`) + const error = fetchFromObject( + errors, + object ? name : `${name}.upstreamValue`, + ); return ( - {label} + + {label} + ( )} /> - - {error?.message} - + {error?.message} ); -} +}; export default React.memo(SelectUpstreamInput); diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component/piece-form.component/upstream-options.ts b/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component/piece-form.component/upstream-options.ts index 668e9bce..7e5fe3c8 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component/piece-form.component/upstream-options.ts +++ b/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component/piece-form.component/upstream-options.ts @@ -1,96 +1,106 @@ -import { generateTaskName, getUuidSlice } from "utils" +import { generateTaskName, getUuidSlice } from "utils"; -export type Option = { - id: string, - argument: string, - value: string +export interface Option { + id: string; + argument: string; + value: string; } -export type ArrayOption = { - array: Option[] - items: Option[] +export interface ArrayOption { + array: Option[]; + items: Option[]; } -export type UpstreamOptions = Record +export type UpstreamOptions = Record; const getInputType = (schema: Record) => { - let type = schema.format ? schema.format : schema.type - if ('allOf' in schema || "oneOf" in schema || "anyOf" in schema) { - type = 'enum' + let type = schema.format ? schema.format : schema.type; + if ("allOf" in schema || "oneOf" in schema || "anyOf" in schema) { + type = "enum"; } - return type === "number" ? "float" : type as string -} - -const getOptions = (upstreamPieces: Record, type: string): Option[] | ArrayOption => { - const options: Option[] = [] + return type === "number" ? "float" : (type as string); +}; - Object.keys(upstreamPieces).forEach(upstreamId => { +const getOptions = ( + upstreamPieces: Record, + type: string, +): Option[] | ArrayOption => { + const options: Option[] = []; - const upPieces = upstreamPieces[upstreamId] + Object.keys(upstreamPieces).forEach((upstreamId) => { + const upPieces = upstreamPieces[upstreamId]; for (const upPiece of upPieces) { - const upSchema = upPiece.output_schema.properties + const upSchema = upPiece.output_schema.properties; for (const property in upSchema) { - - const upType = getInputType(upSchema[property]) - - if ((upType === type) || (upType==="string" && type==="object")) { - const value = `${upPiece?.name} (${getUuidSlice(upPiece.id)}) - ${upSchema[property].title}` - const upstreamArgument = property - const taskName = generateTaskName(upPiece.name,upPiece.id) - options.push({ id: taskName, argument: upstreamArgument, value }) + const upType = getInputType(upSchema[property]); + + if (upType === type || (upType === "string" && type === "object")) { + const value = `${upPiece?.name} (${getUuidSlice(upPiece.id)}) - ${ + upSchema[property].title + }`; + const upstreamArgument = property; + const taskName = generateTaskName(upPiece.name, upPiece.id); + options.push({ id: taskName, argument: upstreamArgument, value }); } } } - }) + }); - return options -} + return options; +}; -export const getUpstreamOptions = (formId: string, schema: any, workflowPieces: any, workflowEdges: any): UpstreamOptions => { - const upstreamPieces: Record = {} - const upstreamOptions: UpstreamOptions = {} +export const getUpstreamOptions = ( + formId: string, + schema: any, + workflowPieces: any, + workflowEdges: any, +): UpstreamOptions => { + const upstreamPieces: Record = {}; + const upstreamOptions: UpstreamOptions = {}; for (const ed of workflowEdges) { if (ed.target === formId) { if (Array.isArray(upstreamPieces[formId])) { - upstreamPieces[formId].push({...workflowPieces[ed.source], id: ed.source}) + upstreamPieces[formId].push({ + ...workflowPieces[ed.source], + id: ed.source, + }); } else { - upstreamPieces[formId] = [] - upstreamPieces[formId].push({...workflowPieces[ed.source], id: ed.source}) + upstreamPieces[formId] = []; + upstreamPieces[formId].push({ + ...workflowPieces[ed.source], + id: ed.source, + }); } } } - Object.keys(schema.properties).forEach(key => { - - let currentSchema = schema.properties[key] - const currentType = getInputType(currentSchema) + Object.keys(schema.properties).forEach((key) => { + const currentSchema = schema.properties[key]; + const currentType = getInputType(currentSchema); if (currentType === "array") { - let itemsSchema = currentSchema?.items; if (currentSchema?.items?.$ref) { - const subItemSchemaName = currentSchema.items.$ref.split('/').pop(); + const subItemSchemaName = currentSchema.items.$ref.split("/").pop(); itemsSchema = schema.definitions?.[subItemSchemaName]; } - const itemsType = getInputType(itemsSchema) - - const array = getOptions(upstreamPieces, currentType) - const items = getOptions(upstreamPieces, itemsType) + const itemsType = getInputType(itemsSchema); - upstreamOptions[key] = { array, items } as ArrayOption + const array = getOptions(upstreamPieces, currentType); + const items = getOptions(upstreamPieces, itemsType); + // eslint-disable-next-line @typescript-eslint/consistent-type-assertions + upstreamOptions[key] = { array, items } as ArrayOption; } else { + const options = getOptions(upstreamPieces, currentType); - const options = getOptions(upstreamPieces, currentType) - - upstreamOptions[key] = options - + upstreamOptions[key] = options; } - }) + }); - return upstreamOptions -} + return upstreamOptions; +}; diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component/piece-form.component/validation.ts b/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component/piece-form.component/validation.ts index a05624c8..4249994f 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component/piece-form.component/validation.ts +++ b/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component/piece-form.component/validation.ts @@ -1,189 +1,195 @@ -import * as yup from "yup" +import * as yup from "yup"; const defaultValidation = { - fromUpstream: yup.boolean(), //? allowed | never | always + fromUpstream: yup.boolean(), // ? allowed | never | always upstreamArgument: yup.string().when("fromUpstream", ([fromUpstream]) => { if (fromUpstream) { - return yup.string().required() + return yup.string().required(); } - return yup.string() + return yup.string(); }), upstreamId: yup.string().when("fromUpstream", ([fromUpstream]) => { if (fromUpstream) { - return yup.string().required() + return yup.string().required(); } - return yup.string() + return yup.string(); }), upstreamValue: yup.string().when("fromUpstream", ([fromUpstream]) => { if (fromUpstream) { - return yup.string().required() + return yup.string().required(); } - return yup.string() + return yup.string(); }), -} +}; const validationObject = () => { - return yup.lazy(value => { - const rawValidationObject = Object.entries(value.fromUpstream).reduce((objValidation, [key, fromUpstream]) => { - if (fromUpstream) { - objValidation.fromUpstream[key] = yup.boolean().required() - objValidation.upstreamArgument[key] = yup.string().required() - objValidation.upstreamId[key] = yup.string().required() - objValidation.upstreamValue[key] = yup.string().required() - objValidation.value[key] = yup.mixed().notRequired() - } else { - objValidation.fromUpstream[key] = yup.boolean().required() - objValidation.upstreamArgument[key] = yup.mixed().notRequired() - objValidation.upstreamId[key] = yup.mixed().notRequired() - objValidation.upstreamValue[key] = yup.mixed().notRequired() - objValidation.value[key] = yup.string().required() - } + return yup.lazy((value) => { + const rawValidationObject = Object.entries( + value.fromUpstream, + ).reduce( + (objValidation, [key, fromUpstream]) => { + if (fromUpstream) { + objValidation.fromUpstream[key] = yup.boolean().required(); + objValidation.upstreamArgument[key] = yup.string().required(); + objValidation.upstreamId[key] = yup.string().required(); + objValidation.upstreamValue[key] = yup.string().required(); + objValidation.value[key] = yup.mixed().notRequired(); + } else { + objValidation.fromUpstream[key] = yup.boolean().required(); + objValidation.upstreamArgument[key] = yup.mixed().notRequired(); + objValidation.upstreamId[key] = yup.mixed().notRequired(); + objValidation.upstreamValue[key] = yup.mixed().notRequired(); + objValidation.value[key] = yup.string().required(); + } - return objValidation - }, { - fromUpstream: {}, - upstreamArgument: {}, - upstreamId: {}, - upstreamValue: {}, - value: {}, - } as yup.AnyObject) + return objValidation; + }, + { + fromUpstream: {}, + upstreamArgument: {}, + upstreamId: {}, + upstreamValue: {}, + value: {}, + }, + ); - const validationObject = Object.entries(rawValidationObject).reduce((acc,[key,obj])=>{ - return {...acc, [key]: yup.object(obj)} - },{}) + const validationObject = Object.entries(rawValidationObject).reduce( + (acc, [key, obj]) => { + return { ...acc, [key]: yup.object(obj) }; + }, + {}, + ); - return yup.object().shape(validationObject) - }) -} + return yup.object().shape(validationObject); + }); +}; function getValidationValueBySchemaType(schema: any) { - let inputSchema + let inputSchema; - if ((schema.type === 'number') && !schema.format) { + if (schema.type === "number" && !schema.format) { inputSchema = yup.object({ ...defaultValidation, value: yup.number().when("fromUpstream", ([fromUpstream]) => { if (fromUpstream) { - return yup.mixed().notRequired() + return yup.mixed().notRequired(); } - return yup.number().typeError('Must must be a number').required() - }) - }) - } - else if (schema.type === 'integer' && !schema.format) { + return yup.number().typeError("Must must be a number").required(); + }), + }); + } else if (schema.type === "integer" && !schema.format) { inputSchema = yup.object({ ...defaultValidation, value: yup.number().when("fromUpstream", ([fromUpstream]) => { if (fromUpstream) { - return yup.mixed().notRequired() + return yup.mixed().notRequired(); } - return yup.number().integer().typeError('Must must be a number').required() - }) - }) - } - else if (schema.type === 'boolean' && !schema.format) { + return yup + .number() + .integer() + .typeError("Must must be a number") + .required(); + }), + }); + } else if (schema.type === "boolean" && !schema.format) { inputSchema = yup.object({ ...defaultValidation, value: yup.boolean().when("fromUpstream", ([fromUpstream]) => { if (fromUpstream) { - return yup.mixed().notRequired() + return yup.mixed().notRequired(); } - return yup.boolean().required() - }) - }) - } - else if (schema.type === 'string' && schema.format === 'date') { + return yup.boolean().required(); + }), + }); + } else if (schema.type === "string" && schema.format === "date") { inputSchema = yup.object({ ...defaultValidation, value: yup.string().when("fromUpstream", ([fromUpstream]) => { if (fromUpstream) { - return yup.mixed().notRequired() + return yup.mixed().notRequired(); } - return yup.string().required() - }) - }) - } - else if (schema.type === 'string' && schema?.format === 'time') { + return yup.string().required(); + }), + }); + } else if (schema.type === "string" && schema?.format === "time") { inputSchema = yup.object({ ...defaultValidation, value: yup.string().when("fromUpstream", ([fromUpstream]) => { if (fromUpstream) { - return yup.mixed().notRequired() + return yup.mixed().notRequired(); } - return yup.string().required() - }) - }) - } - else if (schema.type === 'string' && schema?.format === 'date-time') { + return yup.string().required(); + }), + }); + } else if (schema.type === "string" && schema?.format === "date-time") { inputSchema = yup.object({ ...defaultValidation, value: yup.string().when("fromUpstream", ([fromUpstream]) => { if (fromUpstream) { - return yup.mixed().notRequired() + return yup.mixed().notRequired(); } - return yup.string().required() - }) - }) - } - else if (schema.type === 'string' && schema?.widget === 'codeeditor') { + return yup.string().required(); + }), + }); + } else if (schema.type === "string" && schema?.widget === "codeeditor") { inputSchema = yup.object({ ...defaultValidation, value: yup.string().when("fromUpstream", ([fromUpstream]) => { if (fromUpstream) { - return yup.mixed().notRequired() + return yup.mixed().notRequired(); } - return yup.string() - }) - }) - } - else if (schema.type === 'string' && !schema.format) { + return yup.string(); + }), + }); + } else if (schema.type === "string" && !schema.format) { inputSchema = yup.object({ ...defaultValidation, value: yup.string().when("fromUpstream", ([fromUpstream]) => { if (fromUpstream) { - return yup.mixed().notRequired() + return yup.mixed().notRequired(); } - return yup.string().required() - }) - }) - } - else if (schema.type === 'object') { - inputSchema = validationObject() + return yup.string().required(); + }), + }); + } else if (schema.type === "object") { + inputSchema = validationObject(); } else { - inputSchema = yup.mixed().notRequired() + inputSchema = yup.mixed().notRequired(); } - return inputSchema + return inputSchema; } export function createInputsSchemaValidation(schema: any) { if (!schema?.properties) { - return yup.mixed().notRequired() + return yup.mixed().notRequired(); } - const validationSchema = - Object.entries(schema.properties).reduce((acc, cur: [string, any]) => { - const [key, subSchema] = cur - let inputSchema + const validationSchema = Object.entries(schema.properties).reduce( + (acc, cur: [string, any]) => { + const [key, subSchema] = cur; + let inputSchema; - if (subSchema.type === 'array') { + if (subSchema.type === "array") { let subItemSchema: any = subSchema?.items; if (subSchema?.items?.$ref) { - const subItemSchemaName = subSchema.items.$ref.split('/').pop(); + const subItemSchemaName = subSchema.items.$ref.split("/").pop(); subItemSchema = schema.definitions?.[subItemSchemaName]; } inputSchema = yup.object({ ...defaultValidation, - value: yup.array().of( - getValidationValueBySchemaType(subItemSchema) as any - ) - }) + value: yup + .array() + .of(getValidationValueBySchemaType(subItemSchema) as any), + }); } else { - inputSchema = getValidationValueBySchemaType(subSchema) + inputSchema = getValidationValueBySchemaType(subSchema); } - return { ...acc, [key]: inputSchema } - }, {}) + return { ...acc, [key]: inputSchema }; + }, + {}, + ); - return yup.object().shape(validationSchema) + return yup.object().shape(validationSchema); } diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component/storage-form.component.tsx b/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component/storage-form.component.tsx index 6dc4effe..3d45afcd 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component/storage-form.component.tsx +++ b/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component/storage-form.component.tsx @@ -1,16 +1,32 @@ -import React from 'react'; -import { Controller, useFormContext } from 'react-hook-form'; -import * as yup from 'yup' -import { FormControl, FormHelperText, Grid, InputLabel, MenuItem, Select, Typography } from '@mui/material'; -import { IStorageFormData, IWorkflowPieceData, StorageAccessModes, storageAccessModes } from 'context/workflows/types'; +import { + FormControl, + FormHelperText, + Grid, + InputLabel, + MenuItem, + Select, + Typography, +} from "@mui/material"; +import { + type IStorageFormData, + type IWorkflowPieceData, + type StorageAccessModes, + storageAccessModes, +} from "context/workflows/types"; +import React from "react"; +import { Controller, useFormContext } from "react-hook-form"; +import * as yup from "yup"; export const storageFormSchema = yup.object().shape({ - storageAccessMode: yup.mixed().oneOf(Object.values(storageAccessModes)).required(), + storageAccessMode: yup + .mixed() + .oneOf(Object.values(storageAccessModes)) + .required(), }); export const defaultStorage: IStorageFormData = { - storageAccessMode: storageAccessModes.None -} + storageAccessMode: storageAccessModes.None, +}; const StorageForm: React.FC = () => { const { formState, control } = useFormContext(); @@ -18,7 +34,13 @@ const StorageForm: React.FC = () => { return ( - Storage + + Storage + @@ -30,9 +52,9 @@ const StorageForm: React.FC = () => { render={({ field }) => ( setVersion(e.target.value)} + label="Repository versoin" + disabled={step !== "SELECT_VERSION"} + onChange={(e) => { + setVersion(e.target.value); + }} > {availableVersions.map(({ version }) => ( @@ -239,26 +244,29 @@ export const RepositoriesCard: FC = () => { !url || isStepLoading || !!error || - (step === 'SELECT_VERSION' && !version) + (step === "SELECT_VERSION" && !version) } - color='primary' - variant='contained' + color="primary" + variant="contained" onClick={handleNextStep} sx={{ mt: 1, - width: '100%', - display: 'flex', - alignItems: 'centerr' + width: "100%", + display: "flex", + alignItems: "centerr", }} > {isStepLoading ? : stepButtonContent[step]} - {!!repositories.length ? ( + {repositories.length ? ( {repositories.map((repo, index) => ( - + @@ -275,12 +283,15 @@ export const RepositoriesCard: FC = () => { secondary={`${repo.path} - version: ${repo.version}`} /> - + - - + + @@ -288,11 +299,11 @@ export const RepositoriesCard: FC = () => { ))} ) : ( - + No repositories! )} - ) -} + ); +}; diff --git a/frontend/src/pages/private/workspaces/workspace-settings/components/repository-secrets-card.component.tsx b/frontend/src/pages/private/workspaces/workspace-settings/components/repository-secrets-card.component.tsx index 5b6d8c47..446ce303 100644 --- a/frontend/src/pages/private/workspaces/workspace-settings/components/repository-secrets-card.component.tsx +++ b/frontend/src/pages/private/workspaces/workspace-settings/components/repository-secrets-card.component.tsx @@ -1,196 +1,238 @@ /* eslint-disable react/prop-types */ -import { useState, useImperativeHandle, useCallback, forwardRef, Ref, useMemo } from 'react' +import CancelIcon from "@mui/icons-material/Cancel"; +import DeleteIcon from "@mui/icons-material/Delete"; +import EditIcon from "@mui/icons-material/Edit"; +import SaveAltIcon from "@mui/icons-material/SaveAlt"; +import { + Card, + CardHeader, + CardContent, + Box, + Typography, + Grid, + TextField, + IconButton, + Tooltip, +} from "@mui/material"; +import { + useState, + useImperativeHandle, + useCallback, + forwardRef, + type Ref, + useMemo, +} from "react"; import { useForm } from "react-hook-form"; -import { useAuthenticatedGetRepositorySecrets, useAuthenticatedPatchRepositorySecret } from 'services/requests/repository' -import { toast } from 'react-toastify'; +import { toast } from "react-toastify"; import { - Card, - CardHeader, - CardContent, - Box, - Typography, - Grid, - TextField, - IconButton, - Tooltip -} from '@mui/material' -import EditIcon from '@mui/icons-material/Edit'; -import SaveAltIcon from '@mui/icons-material/SaveAlt'; -import DeleteIcon from '@mui/icons-material/Delete'; -import CancelIcon from '@mui/icons-material/Cancel'; - + useAuthenticatedGetRepositorySecrets, + useAuthenticatedPatchRepositorySecret, +} from "services/requests/repository"; interface SecretsCardProps { - repositoryId: number | null; + repositoryId: number | null; } - /* eslint-disable react/prop-types */ const SecretsCard = (props: SecretsCardProps, ref: Ref) => { - const filledDefaultValue = '******' - const { repositoryId } = props; - const { register, getValues, resetField } = useForm(); - const [currrentEdittingSecretId, setCurrrentEdittingSecretId] = useState(null) - - useImperativeHandle(ref, () => ({ - ...ref - })); - - const { - data: secrets, - mutate: refreshSecrets, - } = useAuthenticatedGetRepositorySecrets({ repositoryId: repositoryId?.toString() ?? '' }) - - - const patchRepository = useAuthenticatedPatchRepositorySecret() - - const handleEditSecret = useCallback((e: any) => { - e.preventDefault(); - const selectedSecretId = e.currentTarget.value - setCurrrentEdittingSecretId(selectedSecretId) - }, []) - - const handleSaveSecret = useCallback(async(e: any) => { - e.preventDefault(); - const selectedSecretId = e.currentTarget.value - - if (!repositoryId) { - toast.error('Repository not selected.') - return - } - - if (e.currentTarget.ariaLabel === 'clear'){ - const payload = { - value: null - } - patchRepository({ - repositoryId: repositoryId.toString(), - secretId: selectedSecretId as string, - payload: payload - }).then((response) => { - toast.success('Secret updated.') - refreshSecrets() - resetField(selectedSecretId?.toString(), { keepTouched : false}) - setCurrrentEdittingSecretId(null) - }).catch((err) => { - toast.error('Error while updating secrets') - }) - return - } - - const formValue = getValues(selectedSecretId?.toString()) - if (!formValue){ - toast.warning("Please enter a valid value for the secret.") - return - } - if (formValue === filledDefaultValue) { - toast.warning('Please enter a new value for the secret.') - return - } - + const filledDefaultValue = "******"; + const { repositoryId } = props; + const { register, getValues, resetField } = useForm(); + const [currrentEdittingSecretId, setCurrrentEdittingSecretId] = useState< + number | null + >(null); + + useImperativeHandle(ref, () => ({ + ...ref, + })); + + const { data: secrets, mutate: refreshSecrets } = + useAuthenticatedGetRepositorySecrets({ + repositoryId: repositoryId?.toString() ?? "", + }); + + const patchRepository = useAuthenticatedPatchRepositorySecret(); + + const handleEditSecret = useCallback((e: any) => { + e.preventDefault(); + const selectedSecretId = e.currentTarget.value; + setCurrrentEdittingSecretId(selectedSecretId); + }, []); + + const handleSaveSecret = useCallback( + async (e: any) => { + e.preventDefault(); + const selectedSecretId = e.currentTarget.value; + + if (!repositoryId) { + toast.error("Repository not selected."); + return; + } + + if (e.currentTarget.ariaLabel === "clear") { const payload = { - value: formValue, - } + value: null, + }; patchRepository({ - repositoryId: repositoryId.toString(), - secretId: selectedSecretId as string, - payload: payload - }).then((response)=>{ - toast.success('Secret updated') - refreshSecrets() - setCurrrentEdittingSecretId(null) - }).catch((err) => { - console.log(err) - toast.error('Error while updating secret.') + repositoryId: repositoryId.toString(), + secretId: selectedSecretId as string, + payload, }) - - }, [getValues, repositoryId, patchRepository, refreshSecrets, resetField]) - - const listItems = useMemo(() => { - const auxListItems = secrets && secrets?.length > 0 ? secrets?.map((secret, index) => ( - - - - - - { - currrentEdittingSecretId?.toString() === secret.id.toString() ? ( -
- - - - - - - - - - - - setCurrrentEdittingSecretId(null)}> - - - -
- ) : ( - - - - - - ) - } -
-
- )) : ( - - { - repositoryId === null ? ( - - No repository selected. - - ) : ( - - This repository has no secrets. - - ) + .then((response) => { + toast.success("Secret updated."); + void refreshSecrets(); + resetField(selectedSecretId?.toString(), { keepTouched: false }); + setCurrrentEdittingSecretId(null); + }) + .catch((_err) => { + toast.error("Error while updating secrets"); + }); + return; + } + + const formValue = getValues(selectedSecretId?.toString()); + if (!formValue) { + toast.warning("Please enter a valid value for the secret."); + return; + } + if (formValue === filledDefaultValue) { + toast.warning("Please enter a new value for the secret."); + return; + } + + const payload = { + value: formValue, + }; + patchRepository({ + repositoryId: repositoryId.toString(), + secretId: selectedSecretId as string, + payload, + }) + .then((response) => { + toast.success("Secret updated"); + void refreshSecrets(); + setCurrrentEdittingSecretId(null); + }) + .catch((err) => { + console.log(err); + toast.error("Error while updating secret."); + }); + }, + [getValues, repositoryId, patchRepository, refreshSecrets, resetField], + ); + + const listItems = useMemo(() => { + const auxListItems = + secrets && secrets?.length > 0 ? ( + secrets?.map((secret, index) => ( + + + - ) - return auxListItems - }, [secrets, repositoryId, currrentEdittingSecretId, handleEditSecret, handleSaveSecret, register]) - - return ( - - - - - - Secrets are environment variables that are encrypted and injected to the operator container based on the operator SecretsModel. - Anyone with access to this workspace can use these secrets for running operators. - -
- - {listItems} - -
-
-
-
- ); -} - -export default forwardRef(SecretsCard); \ No newline at end of file + + {currrentEdittingSecretId?.toString() === secret.id.toString() ? ( +
+ + + + + + + + + + + + { + setCurrrentEdittingSecretId(null); + }} + > + + + +
+ ) : ( + + + + + + )} +
+
+ )) + ) : ( + + {repositoryId === null ? ( + + No repository selected. + + ) : ( + + This repository has no secrets. + + )} + + ); + return auxListItems; + }, [ + secrets, + repositoryId, + currrentEdittingSecretId, + handleEditSecret, + handleSaveSecret, + register, + ]); + + return ( + + + + + + Secrets are environment variables that are encrypted and injected to + the operator container based on the operator SecretsModel. Anyone + with access to this workspace can use these secrets for running + operators. + +
+ + {listItems} + +
+
+
+
+ ); +}; + +export default forwardRef(SecretsCard); diff --git a/frontend/src/pages/private/workspaces/workspace-settings/components/storage-secrets-card.component.tsx b/frontend/src/pages/private/workspaces/workspace-settings/components/storage-secrets-card.component.tsx index 4d9111f6..75dcf947 100644 --- a/frontend/src/pages/private/workspaces/workspace-settings/components/storage-secrets-card.component.tsx +++ b/frontend/src/pages/private/workspaces/workspace-settings/components/storage-secrets-card.component.tsx @@ -1,198 +1,241 @@ /* eslint-disable react/prop-types */ -import { useState, useCallback, useMemo, useEffect } from 'react' +import CancelIcon from "@mui/icons-material/Cancel"; +import DeleteIcon from "@mui/icons-material/Delete"; +import EditIcon from "@mui/icons-material/Edit"; +import SaveAltIcon from "@mui/icons-material/SaveAlt"; +import { + Card, + CardHeader, + CardContent, + Box, + Typography, + Grid, + TextField, + Tooltip, + IconButton, + Alert, +} from "@mui/material"; +import { useWorkspaceSettings } from "context/workspaces/workspace-settings.context"; +import { useState, useCallback, useMemo, useEffect } from "react"; import { useForm } from "react-hook-form"; -import { useAuthenticatedGetRepositorySecrets, useAuthenticatedPatchRepositorySecret } from 'services/requests/repository' -import { toast } from 'react-toastify'; +import { toast } from "react-toastify"; import { - Card, - CardHeader, - CardContent, - Box, - Typography, - Grid, - TextField, - Tooltip, - IconButton, - Alert -} from '@mui/material' -import EditIcon from '@mui/icons-material/Edit'; -import SaveAltIcon from '@mui/icons-material/SaveAlt'; -import DeleteIcon from '@mui/icons-material/Delete'; -import CancelIcon from '@mui/icons-material/Cancel'; -import { useWorkspaceSettings } from 'context/workspaces/workspace-settings.context'; + useAuthenticatedGetRepositorySecrets, + useAuthenticatedPatchRepositorySecret, +} from "services/requests/repository"; /* eslint-disable react/prop-types */ const StorageSecretsCard = () => { - const filledDefaultValue = '******' - const { register, getValues, resetField } = useForm(); - const [currrentEdittingSecretId, setCurrrentEdittingSecretId] = useState(null) - const [repositoryId, setRepositoryId] = useState(null) - - const { - defaultRepositories - } = useWorkspaceSettings() + const filledDefaultValue = "******"; + const { register, getValues, resetField } = useForm(); + const [currrentEdittingSecretId, setCurrrentEdittingSecretId] = useState< + number | null + >(null); + const [repositoryId, setRepositoryId] = useState(null); - const storageRepository = useMemo(() => { - return defaultRepositories.find(repository => { - return repository.name.includes('storage') - }) - }, [defaultRepositories]) + const { defaultRepositories } = useWorkspaceSettings(); - useEffect(() => { - if (storageRepository) { - setRepositoryId(+storageRepository.id) - } - }, [storageRepository]) + const storageRepository = useMemo(() => { + return defaultRepositories.find((repository) => { + return repository.name.includes("storage"); + }); + }, [defaultRepositories]); - const { - data: secrets, - mutate: refreshSecrets, - } = useAuthenticatedGetRepositorySecrets({ repositoryId: storageRepository?.id.toString() ?? '' }) - - const patchRepositorySecret = useAuthenticatedPatchRepositorySecret() + useEffect(() => { + if (storageRepository) { + setRepositoryId(+storageRepository.id); + } + }, [storageRepository]); - const handleEditSecret = useCallback((e: any) => { - e.preventDefault(); - const selectedSecretId = e.currentTarget.value - setCurrrentEdittingSecretId(selectedSecretId) - }, []) + const { data: secrets, mutate: refreshSecrets } = + useAuthenticatedGetRepositorySecrets({ + repositoryId: storageRepository?.id.toString() ?? "", + }); - const handleSaveSecret = useCallback(async(e: any) => { - e.preventDefault(); - const selectedSecretId = e.currentTarget.value + const patchRepositorySecret = useAuthenticatedPatchRepositorySecret(); - if (!repositoryId) { - toast.error('Repository not selected.') - return - } + const handleEditSecret = useCallback((e: any) => { + e.preventDefault(); + const selectedSecretId = e.currentTarget.value; + setCurrrentEdittingSecretId(selectedSecretId); + }, []); - if (e.currentTarget.ariaLabel === 'clear'){ - const payload = { - value: null - } - patchRepositorySecret({ - repositoryId: repositoryId.toString(), - secretId: selectedSecretId as string, - payload: payload - }).then((response) => { - toast.success('Secret updated.') - refreshSecrets() - resetField(selectedSecretId?.toString(), { keepTouched : false}) - setCurrrentEdittingSecretId(null) - }).catch((err) => { - toast.error('Error while updating secrets') - }) - return - } + const handleSaveSecret = useCallback( + async (e: any) => { + e.preventDefault(); + const selectedSecretId = e.currentTarget.value; - const formValue = getValues(selectedSecretId?.toString()) - if (!formValue){ - toast.warning("Please enter a valid value for the secret.") - return - } - if (formValue === filledDefaultValue) { - toast.warning('Please enter a new value for the secret.') - return - } + if (!repositoryId) { + toast.error("Repository not selected."); + return; + } + if (e.currentTarget.ariaLabel === "clear") { const payload = { - value: formValue, - } + value: null, + }; patchRepositorySecret({ - repositoryId: repositoryId.toString(), - secretId: selectedSecretId as string, - payload: payload - }).then((response)=>{ - toast.success('Secret updated') - refreshSecrets() - setCurrrentEdittingSecretId(null) - }).catch((err) => { - console.log(err) - toast.error('Error while updating secret.') + repositoryId: repositoryId.toString(), + secretId: selectedSecretId as string, + payload, }) + .then((response) => { + toast.success("Secret updated."); + void refreshSecrets(); + resetField(selectedSecretId?.toString(), { keepTouched: false }); + setCurrrentEdittingSecretId(null); + }) + .catch((_err) => { + toast.error("Error while updating secrets"); + }); + return; + } - }, [getValues, repositoryId, patchRepositorySecret, refreshSecrets, resetField]) + const formValue = getValues(selectedSecretId?.toString()); + if (!formValue) { + toast.warning("Please enter a valid value for the secret."); + return; + } + if (formValue === filledDefaultValue) { + toast.warning("Please enter a new value for the secret."); + return; + } - const storageForms = useMemo(() => { - const auxListItems = secrets && secrets?.length > 0 ? secrets?.map((secret, index) => ( + const payload = { + value: formValue, + }; + patchRepositorySecret({ + repositoryId: repositoryId.toString(), + secretId: selectedSecretId as string, + payload, + }) + .then((response) => { + toast.success("Secret updated"); + void refreshSecrets(); + setCurrrentEdittingSecretId(null); + }) + .catch((err) => { + console.log(err); + toast.error("Error while updating secret."); + }); + }, + [ + getValues, + repositoryId, + patchRepositorySecret, + refreshSecrets, + resetField, + ], + ); + + const storageForms = useMemo(() => { + const auxListItems = + secrets && secrets?.length > 0 + ? secrets?.map((secret, index) => ( - - - - - { - currrentEdittingSecretId?.toString() === secret.id.toString() ? ( -
- - - - - - - - - - - - setCurrrentEdittingSecretId(null)}> - - - -
- ) : ( - - - - - - ) - } -
+ + + + + {currrentEdittingSecretId?.toString() === + secret.id.toString() ? ( +
+ + + + + + + + + + + + { + setCurrrentEdittingSecretId(null); + }} + > + + + +
+ ) : ( + + + + + + )} +
- )) : '' - return auxListItems - }, [secrets, currrentEdittingSecretId, register, repositoryId, handleEditSecret, handleSaveSecret]) - + )) + : ""; + return auxListItems; + }, [ + secrets, + currrentEdittingSecretId, + register, + repositoryId, + handleEditSecret, + handleSaveSecret, + ]); - return ( - - - - - - Storage Secrets are environment variables that are encrypted and injected to a sidecar container to the Operators making use of shared storage. - Anyone with access to this workspace can use these secrets for sharing storage between running operators. - - { - secrets && secrets?.length > 0 ? ( -
- - {storageForms} - -
- ) : ( - - No storage repositories! - - ) - } -
-
-
- ); -} + return ( + + + + + + Storage Secrets are environment variables that are encrypted and + injected to a sidecar container to the Operators making use of + shared storage. Anyone with access to this workspace can use these + secrets for sharing storage between running operators. + + {secrets && secrets?.length > 0 ? ( +
+ + {storageForms} + +
+ ) : ( + + No storage repositories! + + )} +
+
+
+ ); +}; -export default StorageSecretsCard; \ No newline at end of file +export default StorageSecretsCard; diff --git a/frontend/src/pages/private/workspaces/workspace-settings/components/users-card.component.tsx b/frontend/src/pages/private/workspaces/workspace-settings/components/users-card.component.tsx index 7402bcfb..7178fada 100644 --- a/frontend/src/pages/private/workspaces/workspace-settings/components/users-card.component.tsx +++ b/frontend/src/pages/private/workspaces/workspace-settings/components/users-card.component.tsx @@ -1,6 +1,4 @@ -import { FC, useCallback, useState } from 'react' - -import { PersonAdd } from '@mui/icons-material' +import { PersonAdd } from "@mui/icons-material"; import { Card, CardHeader, @@ -12,68 +10,69 @@ import { MenuItem, Grid, InputLabel, - FormControl -} from '@mui/material' -import TextField from '@mui/material/TextField' -import { useWorkspaces } from 'context/workspaces/workspaces.context' -import { useWorkspaceSettings } from 'context/workspaces/workspace-settings.context' -import { toast } from 'react-toastify' + FormControl, +} from "@mui/material"; +import TextField from "@mui/material/TextField"; +import { useWorkspaceSettings } from "context/workspaces/workspace-settings.context"; +import { useWorkspaces } from "context/workspaces/workspaces.context"; +import { type FC, useCallback, useState } from "react"; +import { toast } from "react-toastify"; /** * @todo integrate with backend * @returns Users card component */ export const UsersCard: FC = () => { - const [userEmail, setUserEmail] = useState('') - const [permission, setPermission] = useState('') - const { workspaceData } = useWorkspaceSettings() - const { handleInviteUserWorkspace } = useWorkspaces() - + const [userEmail, setUserEmail] = useState(""); + const [permission, setPermission] = useState(""); + const { workspaceData } = useWorkspaceSettings(); + const { handleInviteUserWorkspace } = useWorkspaces(); + const inviteUser = useCallback(() => { // if not user email or not permission toastfail if (!userEmail || !permission) { - toast.error('Email and permission are required.') + toast.error("Email and permission are required."); return; } if (!workspaceData) { - toast.error('Workspace not found.') + toast.error("Workspace not found."); return; } - handleInviteUserWorkspace(workspaceData.id, userEmail, permission) - setUserEmail('') - setPermission('') - - }, [permission, userEmail, handleInviteUserWorkspace, workspaceData]) - + handleInviteUserWorkspace(workspaceData.id, userEmail, permission); + setUserEmail(""); + setPermission(""); + }, [permission, userEmail, handleInviteUserWorkspace, workspaceData]); if (!workspaceData) { - return null + return null; } return ( - - + + - Invite user + Invite user setUserEmail(e.target.value)} + onChange={(e) => { + setUserEmail(e.target.value); + }} fullWidth - variant='outlined' - id='user' - label='User e-mail' - type='email' - name='user' + variant="outlined" + id="user" + label="User e-mail" + type="email" + name="user" /> - @@ -86,10 +85,12 @@ export const UsersCard: FC = () => { id="select-workspace-invite-permission" value={permission} label="Permission" - onChange={(e) => setPermission(e.target.value as string)} + onChange={(e) => { + setPermission(e.target.value); + }} > - Read - Owner + Read + Owner
@@ -117,5 +118,5 @@ export const UsersCard: FC = () => { )} */} - ) -} + ); +}; diff --git a/frontend/src/pages/private/workspaces/workspace-settings/components/workspace-secrets-card.component.tsx b/frontend/src/pages/private/workspaces/workspace-settings/components/workspace-secrets-card.component.tsx index 188af9db..ae1902b4 100644 --- a/frontend/src/pages/private/workspaces/workspace-settings/components/workspace-secrets-card.component.tsx +++ b/frontend/src/pages/private/workspaces/workspace-settings/components/workspace-secrets-card.component.tsx @@ -1,167 +1,192 @@ /* eslint-disable react/prop-types */ -import { useState, useCallback, useEffect } from 'react' -import { useForm } from "react-hook-form"; -import { useAuthenticatedPatchWorkspace } from 'services/requests/workspaces' -import { toast } from 'react-toastify'; +import CancelIcon from "@mui/icons-material/Cancel"; +import DeleteIcon from "@mui/icons-material/Delete"; +import EditIcon from "@mui/icons-material/Edit"; +import SaveAltIcon from "@mui/icons-material/SaveAlt"; import { - Card, - CardHeader, - CardContent, - Box, - Typography, - Grid, - TextField, - Tooltip, - IconButton, -} from '@mui/material' -import EditIcon from '@mui/icons-material/Edit'; -import SaveAltIcon from '@mui/icons-material/SaveAlt'; -import DeleteIcon from '@mui/icons-material/Delete'; -import CancelIcon from '@mui/icons-material/Cancel'; -import { useWorkspaceSettings } from 'context/workspaces/workspace-settings.context'; -import { useWorkspaces } from 'context/workspaces/workspaces.context'; + Card, + CardHeader, + CardContent, + Box, + Typography, + Grid, + TextField, + Tooltip, + IconButton, +} from "@mui/material"; +import { useWorkspaceSettings } from "context/workspaces/workspace-settings.context"; +import { useWorkspaces } from "context/workspaces/workspaces.context"; +import { useState, useCallback, useEffect } from "react"; +import { useForm } from "react-hook-form"; +import { toast } from "react-toastify"; +import { useAuthenticatedPatchWorkspace } from "services/requests/workspaces"; /* eslint-disable react/prop-types */ const WorkspaceSecretsCard = () => { - //const filledDefaultValue = '******' - const [defaultValue, setDefaultValue] = useState('******') - const { register, getValues, resetField } = useForm(); - const [currentEdittingToken, setCurrentEdittingToken] = useState(false) - const { handleUpdateWorkspace } = useWorkspaces() - const { workspaceData: workspace } = useWorkspaceSettings() - - const patchWorkspace = useAuthenticatedPatchWorkspace() + // const filledDefaultValue = '******' + const [defaultValue, setDefaultValue] = useState("******"); + const { register, getValues, resetField } = useForm(); + const [currentEdittingToken, setCurrentEdittingToken] = + useState(false); + const { handleUpdateWorkspace } = useWorkspaces(); + const { workspaceData: workspace } = useWorkspaceSettings(); - useEffect(()=>{ - if (workspace){ - handleUpdateWorkspace(workspace) - if (workspace.github_access_token_filled){ - setDefaultValue('******') - }else{ - setDefaultValue('') - } - } - }, [workspace, handleUpdateWorkspace]) + const patchWorkspace = useAuthenticatedPatchWorkspace(); - const handleSaveToken = useCallback(async(e: any) => { - e.preventDefault(); - setCurrentEdittingToken(false); - if (!workspace) { - toast.error("Workspace not selected.") - return - } - - if (e.currentTarget.ariaLabel === 'clear') { - const payload = { - github_access_token: null - } - patchWorkspace({ - workspaceId: workspace?.id, - payload: payload - }).then((response) => { - toast.success('Secret updated.') - handleUpdateWorkspace(response.data) - resetField(`github-token-workspace-${workspace?.id}`, { keepTouched: false }) - }).catch((err) => { - toast.error('Error while updating secrets') - }) - setCurrentEdittingToken(false) - return - } + useEffect(() => { + if (workspace) { + handleUpdateWorkspace(workspace); + if (workspace.github_access_token_filled) { + setDefaultValue("******"); + } else { + setDefaultValue(""); + } + } + }, [workspace, handleUpdateWorkspace]); - const formValue = getValues(`github-token-workspace-${workspace?.id}`) - if (!formValue) { - toast.warning("Please enter a valid value for the secret.") - return - } - if (formValue === defaultValue) { - toast.warning('Please enter a new value for the secret.') - return - } + const handleSaveToken = useCallback( + async (e: any) => { + e.preventDefault(); + setCurrentEdittingToken(false); + if (!workspace) { + toast.error("Workspace not selected."); + return; + } + if (e.currentTarget.ariaLabel === "clear") { const payload = { - github_access_token: formValue, - } + github_access_token: null, + }; patchWorkspace({ - workspaceId: workspace?.id, - payload: payload - }).then((response) => { - toast.success('Secret updated.') - handleUpdateWorkspace(response.data) - }).catch((err) => { - toast.error('Error while updating secrets') + workspaceId: workspace?.id, + payload, }) - setCurrentEdittingToken(false) + .then((response) => { + toast.success("Secret updated."); + handleUpdateWorkspace(response.data); + resetField(`github-token-workspace-${workspace?.id}`, { + keepTouched: false, + }); + }) + .catch((_err) => { + toast.error("Error while updating secrets"); + }); + setCurrentEdittingToken(false); + return; + } - }, [workspace, getValues, patchWorkspace, resetField, handleUpdateWorkspace, defaultValue]); + const formValue = getValues(`github-token-workspace-${workspace?.id}`); + if (!formValue) { + toast.warning("Please enter a valid value for the secret."); + return; + } + if (formValue === defaultValue) { + toast.warning("Please enter a new value for the secret."); + return; + } - if (!workspace) { - return ( -

Workspace not selected.

- ) - } - return ( - - - - - - Workspace github token is used to access private pieces repositories. - Furhtermore, authenticated requests get a higher rate limit from Github. - - -
- - - - - - { - currentEdittingToken ? ( -
- - - - - - - - - - - - setCurrentEdittingToken(false)}> - - - -
- ) : ( - - setCurrentEdittingToken(true)}> - - - - ) - } -
-
-
-
-
- ); -} + const payload = { + github_access_token: formValue, + }; + patchWorkspace({ + workspaceId: workspace?.id, + payload, + }) + .then((response) => { + toast.success("Secret updated."); + handleUpdateWorkspace(response.data); + }) + .catch((_err) => { + toast.error("Error while updating secrets"); + }); + setCurrentEdittingToken(false); + }, + [ + workspace, + getValues, + patchWorkspace, + resetField, + handleUpdateWorkspace, + defaultValue, + ], + ); + + if (!workspace) { + return

Workspace not selected.

; + } + return ( + + + + + + Workspace github token is used to access private pieces + repositories. Furhtermore, authenticated requests get a higher rate + limit from Github. + + +
+ + + + + + {currentEdittingToken ? ( +
+ + + + + + + + + + + + { + setCurrentEdittingToken(false); + }} + > + + + +
+ ) : ( + + { + setCurrentEdittingToken(true); + }} + > + + + + )} +
+
+
+
+
+ ); +}; -export default WorkspaceSecretsCard; \ No newline at end of file +export default WorkspaceSecretsCard; diff --git a/frontend/src/pages/private/workspaces/workspace-settings/components/workspace-users-card.component.tsx b/frontend/src/pages/private/workspaces/workspace-settings/components/workspace-users-card.component.tsx index 899066fd..5db212d9 100644 --- a/frontend/src/pages/private/workspaces/workspace-settings/components/workspace-users-card.component.tsx +++ b/frontend/src/pages/private/workspaces/workspace-settings/components/workspace-users-card.component.tsx @@ -1,181 +1,204 @@ /* eslint-disable react/prop-types */ -import { useState, useMemo, useCallback } from 'react' -import { DataGrid, GridColumns, GridActionsCellItem } from '@mui/x-data-grid'; +import DeleteOutlineOutlinedIcon from "@mui/icons-material/DeleteOutlineOutlined"; import { - Card, - CardHeader, - CardContent, - Grid, - Tooltip, - Dialog, - DialogActions, - DialogContent, - DialogContentText, - DialogTitle, - Button -} from '@mui/material' -import { useWorkspaces } from 'context/workspaces/workspaces.context'; -import DeleteOutlineOutlinedIcon from '@mui/icons-material/DeleteOutlineOutlined'; - + Card, + CardHeader, + CardContent, + Grid, + Tooltip, + Dialog, + DialogActions, + DialogContent, + DialogContentText, + DialogTitle, + Button, +} from "@mui/material"; +import { + DataGrid, + type GridColumns, + GridActionsCellItem, +} from "@mui/x-data-grid"; +import { useWorkspaces } from "context/workspaces/workspaces.context"; +import { useState, useMemo, useCallback } from "react"; const WorkspaceMembersCard = () => { + const { + workspace, + handleRemoveUserWorkspace, + workspaceUsersTablePage, + setWorkspaceUsersTablePage, + workspaceUsersTablePageSize, + setWorkspaceUsersTablePageSize, + workspaceUsers, + workspaceUsersRefresh, + } = useWorkspaces(); - const { - workspace, - handleRemoveUserWorkspace, - workspaceUsersTablePage, - setWorkspaceUsersTablePage, - workspaceUsersTablePageSize, - setWorkspaceUsersTablePageSize, - workspaceUsers, - workspaceUsersRefresh - } = useWorkspaces() - - const [removeUserId, setRemoveUserId] = useState(''); - const [isOpenRemoveDialog, setIsOpenRemoveDialog] = useState(false); - - - const columns = useMemo>( - () => [ - { - field: 'id', - headerName: 'User Id', - flex: 1, - hide: true - - }, - { - field: 'count', - headerName: '#', - width: 90 - }, - { - field: 'memberEmail', - headerName: 'Member Email', - flex: 1 + const [removeUserId, setRemoveUserId] = useState(""); + const [isOpenRemoveDialog, setIsOpenRemoveDialog] = useState(false); - }, - { - field: 'memberPermission', - headerName: 'Member Permission', - flex: 1, - valueFormatter: ({ value }) => value.charAt(0).toUpperCase() + value.slice(1) - }, - { - field: 'status', - headerName: 'Status', - flex: 1, - valueFormatter: ({ value }) => value.charAt(0).toUpperCase() + value.slice(1) - - }, - { - field: 'actions', - type: 'actions', - headerName: 'Remove', - minWidth: 150, - flex: 0.6, - hide: workspace?.user_permission === 'owner' ? false : true, - getActions: (params) => [ - - - - } - label="Delete" - onClick={() => { setRemoveUserId(params.id); setIsOpenRemoveDialog(true) }} - /> - ], - }, - ], [workspace]); - - const { rowsData, totalRows } = useMemo(()=> { - if (!workspaceUsers) { - return { rowsData: [], totalRows: 0} - } - const rowsData = [] - var count = workspaceUsersTablePage * workspaceUsersTablePageSize - for (let element of workspaceUsers.data) { - count = count + 1 - rowsData.push({ - id: element.user_id, - count: count, - memberEmail: element.user_email, - status: element.status, - memberPermission: element.user_permission, - }) - } - const totalRows = workspaceUsers.metadata?.total || 0 - return { rowsData, totalRows} - - }, [workspaceUsers, workspaceUsersTablePage, workspaceUsersTablePageSize]) + const columns = useMemo>( + () => [ + { + field: "id", + headerName: "User Id", + flex: 1, + hide: true, + }, + { + field: "count", + headerName: "#", + width: 90, + }, + { + field: "memberEmail", + headerName: "Member Email", + flex: 1, + }, + { + field: "memberPermission", + headerName: "Member Permission", + flex: 1, + valueFormatter: ({ value }) => + value.charAt(0).toUpperCase() + value.slice(1), + }, + { + field: "status", + headerName: "Status", + flex: 1, + valueFormatter: ({ value }) => + value.charAt(0).toUpperCase() + value.slice(1), + }, + { + field: "actions", + type: "actions", + headerName: "Remove", + minWidth: 150, + flex: 0.6, + hide: workspace?.user_permission !== "owner", + getActions: (params) => [ + // eslint-disable-next-line react/jsx-key + + + + } + label="Delete" + onClick={() => { + setRemoveUserId(params.id); + setIsOpenRemoveDialog(true); + }} + />, + ], + }, + ], + [workspace], + ); - const removeUser = useCallback(async () => { - if (workspace && removeUserId) { - handleRemoveUserWorkspace(workspace?.id, removeUserId) - } - setIsOpenRemoveDialog(false) - setRemoveUserId(null) - workspaceUsersRefresh() - }, [workspace, removeUserId, handleRemoveUserWorkspace, workspaceUsersRefresh]) + const { rowsData, totalRows } = useMemo(() => { + if (!workspaceUsers) { + return { rowsData: [], totalRows: 0 }; + } + const rowsData = []; + let count = workspaceUsersTablePage * workspaceUsersTablePageSize; + for (const element of workspaceUsers.data) { + count = count + 1; + rowsData.push({ + id: element.user_id, + count, + memberEmail: element.user_email, + status: element.status, + memberPermission: element.user_permission, + }); + } + const totalRows = workspaceUsers.metadata?.total || 0; + return { rowsData, totalRows }; + }, [workspaceUsers, workspaceUsersTablePage, workspaceUsersTablePageSize]); + const removeUser = useCallback(async () => { + if (workspace && removeUserId) { + handleRemoveUserWorkspace(workspace?.id, removeUserId); + } + setIsOpenRemoveDialog(false); + setRemoveUserId(null); + workspaceUsersRefresh(); + }, [ + workspace, + removeUserId, + handleRemoveUserWorkspace, + workspaceUsersRefresh, + ]); - return ( - - setIsOpenRemoveDialog(false)} - aria-labelledby="alert-remove-dialog-title" - aria-describedby="alert-remove-dialog-description" - > - - {"Confirm Remove Member"} - - - - Are you sure you want to remove this user from this workspace? - You can always add the user back later. - - - - - - - - - - -
- setWorkspaceUsersTablePageSize(newPageSize)} - paginationMode="server" - pagination - page={workspaceUsersTablePage} - rowCount={totalRows} - onPageChange={(page) => setWorkspaceUsersTablePage(page)} - sx={{ - '&.MuiDataGrid-root .MuiDataGrid-cell:focus': { - outline: 'none', - }, - }} - keepNonExistentRowsSelected - // onSelectionModelChange={handleSelectionModelChange} - /> -
-
-
-
- ); -} + return ( + + { + setIsOpenRemoveDialog(false); + }} + aria-labelledby="alert-remove-dialog-title" + aria-describedby="alert-remove-dialog-description" + > + + {"Confirm Remove Member"} + + + + Are you sure you want to remove this user from this workspace? You + can always add the user back later. + + + + + + + + + + +
+ { + setWorkspaceUsersTablePageSize(newPageSize); + }} + paginationMode="server" + pagination + page={workspaceUsersTablePage} + rowCount={totalRows} + onPageChange={(page) => { + setWorkspaceUsersTablePage(page); + }} + sx={{ + "&.MuiDataGrid-root .MuiDataGrid-cell:focus": { + outline: "none", + }, + }} + keepNonExistentRowsSelected + // onSelectionModelChange={handleSelectionModelChange} + /> +
+
+
+
+ ); +}; -export default WorkspaceMembersCard; \ No newline at end of file +export default WorkspaceMembersCard; diff --git a/frontend/src/pages/private/workspaces/workspace-settings/workspace-settings-page.component.tsx b/frontend/src/pages/private/workspaces/workspace-settings/workspace-settings-page.component.tsx index 3119d680..1a7cad60 100644 --- a/frontend/src/pages/private/workspaces/workspace-settings/workspace-settings-page.component.tsx +++ b/frontend/src/pages/private/workspaces/workspace-settings/workspace-settings-page.component.tsx @@ -1,73 +1,93 @@ -import { useState } from 'react'; -import { Box, Grid, Typography } from '@mui/material'; -import { PrivateLayout } from 'modules/layout'; -import { WorkspaceSettingsProvider } from 'context/workspaces/workspace-settings.context'; -import { withContext } from 'common/hocs/with-context.hoc'; -import { RepositoriesCard } from './components/repositories-card.component'; -import WorkspaceSecretsCard from './components/workspace-secrets-card.component'; -import { UsersCard } from './components/users-card.component'; -import WorkspaceMembersCard from './components/workspace-users-card.component'; -import SecretsCard from './components/repository-secrets-card.component'; -import StorageSecretsCard from './components/storage-secrets-card.component'; -import { useWorkspaceSettings } from 'context/workspaces/workspace-settings.context'; +import TabContext from "@mui/lab/TabContext"; +import TabList from "@mui/lab/TabList"; +import TabPanel from "@mui/lab/TabPanel"; +import { Box, Grid, Typography } from "@mui/material"; +import Tab from "@mui/material/Tab"; +import { withContext } from "common/hocs/with-context.hoc"; +import { + WorkspaceSettingsProvider, + useWorkspaceSettings, +} from "context/workspaces/workspace-settings.context"; +import { PrivateLayout } from "modules/layout"; +import { useState } from "react"; -import Tab from '@mui/material/Tab'; -import TabContext from '@mui/lab/TabContext'; -import TabList from '@mui/lab/TabList'; -import TabPanel from '@mui/lab/TabPanel'; +import { RepositoriesCard } from "./components/repositories-card.component"; +import SecretsCard from "./components/repository-secrets-card.component"; +import StorageSecretsCard from "./components/storage-secrets-card.component"; +import { UsersCard } from "./components/users-card.component"; +import WorkspaceSecretsCard from "./components/workspace-secrets-card.component"; +import WorkspaceMembersCard from "./components/workspace-users-card.component"; +export const WorkspaceSettingsPage = withContext( + WorkspaceSettingsProvider, + () => { + const { workspace, selectedRepositoryId } = useWorkspaceSettings(); -export const WorkspaceSettingsPage = withContext(WorkspaceSettingsProvider, () => { + const [value, setValue] = useState("1"); - const { - workspace, - selectedRepositoryId - } = useWorkspaceSettings() - - const [value, setValue] = useState('1'); - - return ( - - - - - Workspace: {workspace?.workspace_name} - - - - - setValue(newValue)} aria-label="workspace-tabs"> - - - - - - - - - - - - - - - - - - + return ( + + + + + Workspace: {workspace?.workspace_name} + + + + + { + setValue(newValue); + }} + aria-label="workspace-tabs" + > + + + - - - - - + + + + + + + + + + + + + + - - + + + + + + + + + - - - - - ) -}) + + + + ); + }, +); diff --git a/frontend/src/pages/private/workspaces/workspaces/components/add-workspace.component.tsx b/frontend/src/pages/private/workspaces/workspaces/components/add-workspace.component.tsx index dea9c6ed..74a071b2 100644 --- a/frontend/src/pages/private/workspaces/workspaces/components/add-workspace.component.tsx +++ b/frontend/src/pages/private/workspaces/workspaces/components/add-workspace.component.tsx @@ -1,4 +1,3 @@ -import { FC, useCallback, useState } from 'react' import { Button, Card, @@ -7,74 +6,80 @@ import { CardHeader, Grid, CircularProgress, -} from '@mui/material' -import TextField from '@mui/material/TextField' - -import { useWorkspaces } from 'context/workspaces/workspaces.context' +} from "@mui/material"; +import TextField from "@mui/material/TextField"; +import { useWorkspaces } from "context/workspaces/workspaces.context"; +import { type FC, useCallback, useState } from "react"; export const AddWorkspace: FC = () => { - const { workspaces, handleCreateWorkspace } = useWorkspaces() - const [isLoading, setIsLoading] = useState(false) + const { workspaces, handleCreateWorkspace } = useWorkspaces(); + const [isLoading, setIsLoading] = useState(false); - const [name, setName] = useState('') - const regExp = /[a-zA-Z0-9]/g + const [name, setName] = useState(""); + const regExp = /[a-zA-Z0-9]/g; const createWorkspace = useCallback(async () => { setIsLoading(true); - handleCreateWorkspace(name).then(() => { - setName('') - setIsLoading(false) - }) - }, [handleCreateWorkspace, name]) + void handleCreateWorkspace(name).then(() => { + setName(""); + setIsLoading(false); + }); + }, [handleCreateWorkspace, name]); return ( - + setName(e.target.value)} + onChange={(e) => { + setName(e.target.value); + }} /> - + - ) -} + ); +}; diff --git a/frontend/src/pages/private/workspaces/workspaces/components/item.component.tsx b/frontend/src/pages/private/workspaces/workspaces/components/item.component.tsx index de7a97ad..c130a24f 100644 --- a/frontend/src/pages/private/workspaces/workspaces/components/item.component.tsx +++ b/frontend/src/pages/private/workspaces/workspaces/components/item.component.tsx @@ -6,22 +6,28 @@ import { Typography, CardActions, Button, - Grid -} from '@mui/material' -import { FC } from 'react' -import { useNavigate } from 'react-router-dom' -import { IWorkspaceSummary } from 'services/requests/workspaces' + Grid, +} from "@mui/material"; +import { type FC } from "react"; +import { useNavigate } from "react-router-dom"; +import { type IWorkspaceSummary } from "services/requests/workspaces"; export const WorkspaceListItem: FC<{ - workspace: IWorkspaceSummary - handleSelect: () => void - handleDelete: () => void - handleLeave: () => void - selectedWorkspaceId: string | undefined -}> = ({ workspace, handleSelect, handleDelete, handleLeave, selectedWorkspaceId }) => { - const isSelected = workspace.id === selectedWorkspaceId + workspace: IWorkspaceSummary; + handleSelect: () => void; + handleDelete: () => void; + handleLeave: () => void; + selectedWorkspaceId: string | undefined; +}> = ({ + workspace, + handleSelect, + handleDelete, + handleLeave, + selectedWorkspaceId, +}) => { + const isSelected = workspace.id === selectedWorkspaceId; - const navigate = useNavigate() + const navigate = useNavigate(); return ( - + - + Permission: {workspace.user_permission} - + Status: - {workspace.status === 'accepted' ? 'Collaborating' : 'Refused'} + + {workspace.status === "accepted" + ? "Collaborating" + : "Refused"} + - + - - - ) -} + ); +}; diff --git a/frontend/src/pages/private/workspaces/workspaces/components/pending-item.component.tsx b/frontend/src/pages/private/workspaces/workspaces/components/pending-item.component.tsx index c46efe0d..f32da43d 100644 --- a/frontend/src/pages/private/workspaces/workspaces/components/pending-item.component.tsx +++ b/frontend/src/pages/private/workspaces/workspaces/components/pending-item.component.tsx @@ -1,88 +1,92 @@ import { - Card, - CardActionArea, - CardHeader, - CardContent, - Typography, - CardActions, - Button, - Grid -} from '@mui/material' -import { FC } from 'react' -import { useWorkspaces } from 'context/workspaces/workspaces.context' -import { IWorkspaceSummary } from 'services/requests/workspaces' + Card, + CardActionArea, + CardHeader, + CardContent, + Typography, + CardActions, + Button, + Grid, +} from "@mui/material"; +import { useWorkspaces } from "context/workspaces/workspaces.context"; +import { type FC } from "react"; +import { type IWorkspaceSummary } from "services/requests/workspaces"; export const WorkspacePendingListItem: FC<{ - workspace: IWorkspaceSummary - selectedWorkspaceId: string | undefined + workspace: IWorkspaceSummary; + selectedWorkspaceId: string | undefined; }> = ({ workspace }) => { + const { handleAcceptWorkspaceInvite, handleRejectWorkspaceInvite } = + useWorkspaces(); - const { handleAcceptWorkspaceInvite, handleRejectWorkspaceInvite } = useWorkspaces() - - return ( - + + - - - - - - - - Permission: - - {workspace.user_permission} - - - - Status: - - Pending - - - - - - - - - - - ) -} + + + + + + Permission: + + {workspace.user_permission} + + + + Status: + + Pending + + + + + + + + + +
+ ); +}; diff --git a/frontend/src/pages/private/workspaces/workspaces/workspaces-page.component.tsx b/frontend/src/pages/private/workspaces/workspaces/workspaces-page.component.tsx index 62b13688..8b1a2b9d 100644 --- a/frontend/src/pages/private/workspaces/workspaces/workspaces-page.component.tsx +++ b/frontend/src/pages/private/workspaces/workspaces/workspaces-page.component.tsx @@ -1,23 +1,22 @@ -import { FC, useCallback, useState } from 'react' -import { - Alert, - Grid, +import { + Alert, + Grid, Typography, Dialog, DialogActions, DialogContent, DialogContentText, DialogTitle, - Button -} from '@mui/material' + Button, +} from "@mui/material"; +import { useAuthentication } from "context/authentication"; +import { useWorkspaces } from "context/workspaces/workspaces.context"; +import { PrivateLayout } from "modules/layout"; +import { type FC, useCallback, useState } from "react"; -import { PrivateLayout } from 'modules/layout' -import { useWorkspaces } from 'context/workspaces/workspaces.context' - -import { AddWorkspace } from './components/add-workspace.component' -import { WorkspaceListItem } from './components/item.component' -import { WorkspacePendingListItem } from './components/pending-item.component' -import { useAuthentication } from 'context/authentication' +import { AddWorkspace } from "./components/add-workspace.component"; +import { WorkspaceListItem } from "./components/item.component"; +import { WorkspacePendingListItem } from "./components/pending-item.component"; /** * Workspace list page @@ -33,40 +32,42 @@ export const WorkspacesPage: FC = () => { handleRefreshWorkspaces, handleChangeWorkspace, handleDeleteWorkspace, - handleRemoveUserWorkspace - } = useWorkspaces() + handleRemoveUserWorkspace, + } = useWorkspaces(); + + const auth = useAuthentication(); - const auth = useAuthentication() + const [isOpenDeleteDialog, setIsOpenDeleteDialog] = useState(false); + const [deleteWorkspaceId, setDeleteWorkspaceId] = useState( + null, + ); - const [isOpenDeleteDialog, setIsOpenDeleteDialog] = useState(false) - const [deleteWorkspaceId, setDeleteWorkspaceId] = useState(null) + const [isOpenLeaveDialog, setIsOpenLeaveDialog] = useState(false); + const [leaveWorkspaceId, setLeaveWorkspaceId] = useState(null); - const [isOpenLeaveDialog, setIsOpenLeaveDialog] = useState(false) - const [leaveWorkspaceId, setLeaveWorkspaceId] = useState(null) - const deleteWorkspace = useCallback(() => { - if (deleteWorkspaceId){ - handleDeleteWorkspace(deleteWorkspaceId) + if (deleteWorkspaceId) { + handleDeleteWorkspace(deleteWorkspaceId); } - setDeleteWorkspaceId(null) - setIsOpenDeleteDialog(false) - }, [handleDeleteWorkspace, deleteWorkspaceId]) + setDeleteWorkspaceId(null); + setIsOpenDeleteDialog(false); + }, [handleDeleteWorkspace, deleteWorkspaceId]); - - const leaveWorkspace = useCallback(()=>{ - if (leaveWorkspaceId){ - handleRemoveUserWorkspace(leaveWorkspaceId, auth.store.userId as string) + const leaveWorkspace = useCallback(() => { + if (leaveWorkspaceId) { + handleRemoveUserWorkspace(leaveWorkspaceId, auth.store.userId as string); } - setLeaveWorkspaceId(null) - setIsOpenLeaveDialog(false) - }, [leaveWorkspaceId, handleRemoveUserWorkspace, auth.store.userId]) - + setLeaveWorkspaceId(null); + setIsOpenLeaveDialog(false); + }, [leaveWorkspaceId, handleRemoveUserWorkspace, auth.store.userId]); return ( setIsOpenDeleteDialog(false)} + onClose={() => { + setIsOpenDeleteDialog(false); + }} aria-labelledby="alert-dialog-title" aria-describedby="alert-dialog-description" > @@ -76,19 +77,28 @@ export const WorkspacesPage: FC = () => { Are you sure you want to delete this workspace and all its contents? - This action cannot be undone. + This action{" "} + cannot be undone. - - + setIsOpenLeaveDialog(false)} + onClose={() => { + setIsOpenLeaveDialog(false); + }} aria-labelledby="alert-leave-dialog-title" aria-describedby="alert-leave-dialog-description" > @@ -98,56 +108,73 @@ export const WorkspacesPage: FC = () => { Are you sure you want to leave this workspace and all its contents? - This action cannot be undone and may cause workspace deletion.. + This action{" "} + + cannot be undone and may cause workspace deletion. + + . - - + - + My workspaces {workspacesError && ( /* @TODO: cange alert to toast.error('Error loading workspaces') and add button ('click here to try again') */ - handleRefreshWorkspaces()}> + { + handleRefreshWorkspaces(); + }} + > Error loading workspaces, click here to try again )} {workspacesLoading && ( - Loading your workspaces... + Loading your workspaces... )} - + - {workspaces.map((ws, index) => ( - ws.status === 'rejected' ? null : - ws.status === 'pending' ? + {workspaces.map((ws, index) => + ws.status === "rejected" ? null : ws.status === "pending" ? ( - : + ) : ( handleChangeWorkspace(ws.id)} - handleDelete={()=> { - setDeleteWorkspaceId(ws.id) - setIsOpenDeleteDialog(true) + handleSelect={() => { + handleChangeWorkspace(ws.id); + }} + handleDelete={() => { + setDeleteWorkspaceId(ws.id); + setIsOpenDeleteDialog(true); }} selectedWorkspaceId={workspace?.id} handleLeave={() => { - setLeaveWorkspaceId(ws.id) - setIsOpenLeaveDialog(true) + setLeaveWorkspaceId(ws.id); + setIsOpenLeaveDialog(true); }} /> - ))} + ), + )} - ) -} + ); +}; diff --git a/frontend/src/pages/public/sign-in/sign-in-page.component.tsx b/frontend/src/pages/public/sign-in/sign-in-page.component.tsx index b8c8b2cd..a3a0eb63 100644 --- a/frontend/src/pages/public/sign-in/sign-in-page.component.tsx +++ b/frontend/src/pages/public/sign-in/sign-in-page.component.tsx @@ -1,105 +1,110 @@ -import { FC, useCallback } from 'react' - -import { Box, Button, Grid, Typography, Link as LinkMui } from '@mui/material' - -import { PublicLayout } from 'modules/layout' -import { useAuthentication } from 'context/authentication' -import { Link } from 'react-router-dom' -import * as yup from "yup" -import { yupResolver } from 'utils'; -import { FormProvider, useForm } from 'react-hook-form'; -import TextInput from 'components/text-input'; +import { Box, Button, Grid, Typography, Link as LinkMui } from "@mui/material"; +import TextInput from "components/text-input"; +import { useAuthentication } from "context/authentication"; +import { PublicLayout } from "modules/layout"; +import { type FC, useCallback } from "react"; +import { FormProvider, useForm } from "react-hook-form"; +import { Link } from "react-router-dom"; +import { yupResolver } from "utils"; +import * as yup from "yup"; /** * Sign in component */ interface ISignIn { - email: string, - password: string, + email: string; + password: string; } const validationSignIn: yup.ObjectSchema = yup.object().shape({ email: yup.string().email().required(), - password: yup.string().required() -}) + password: yup.string().required(), +}); export const SignInPage: FC = () => { - const { authenticate, authLoading } = useAuthentication() + const { authenticate, authLoading } = useAuthentication(); - const resolver = yupResolver(validationSignIn) + const resolver = yupResolver(validationSignIn); const methods = useForm({ reValidateMode: "onChange", resolver, - }) + }); - const handleSubmit = useCallback(async (data: ISignIn) => { - await authenticate(data.email, data.password) - }, [authenticate]) + const handleSubmit = useCallback( + async (data: ISignIn) => { + await authenticate(data.email, data.password); + }, + [authenticate], + ); return ( - logo + logo - - Welcome Back + + + Welcome Back + handleSubmit(data))} + component="form" + onSubmit={methods.handleSubmit(async (data) => { + await handleSubmit(data); + })} noValidate sx={{ mt: 1 }} > - + - - + + Forgot password? - - Don't have an account? Sign Up + + {"Don't have an account? Sign Up"} - {'Copyright © '} - + {"Copyright © "} + Tauffer Consulting - {' 2022.'} + {" 2022."} - ) -} + ); +}; -export default SignInPage +export default SignInPage; diff --git a/frontend/src/pages/public/sign-up/sign-up-page.component.tsx b/frontend/src/pages/public/sign-up/sign-up-page.component.tsx index aef8d3d8..88537526 100644 --- a/frontend/src/pages/public/sign-up/sign-up-page.component.tsx +++ b/frontend/src/pages/public/sign-up/sign-up-page.component.tsx @@ -1,14 +1,19 @@ -import { FC, useCallback } from 'react' - -import { Box, Button, Grid, Typography, CircularProgress, Link as LinkMui } from '@mui/material' - -import { PublicLayout } from 'modules/layout' -import { useAuthentication } from 'context/authentication' -import { Link } from 'react-router-dom' -import * as yup from "yup" -import { yupResolver } from 'utils'; -import { FormProvider, useForm } from 'react-hook-form'; -import TextInput from 'components/text-input'; +import { + Box, + Button, + Grid, + Typography, + CircularProgress, + Link as LinkMui, +} from "@mui/material"; +import TextInput from "components/text-input"; +import { useAuthentication } from "context/authentication"; +import { PublicLayout } from "modules/layout"; +import { type FC, useCallback } from "react"; +import { FormProvider, useForm } from "react-hook-form"; +import { Link } from "react-router-dom"; +import { yupResolver } from "utils"; +import * as yup from "yup"; /** * Sign up component @@ -16,133 +21,137 @@ import TextInput from 'components/text-input'; */ interface ISignUp { - email: string, - password: string, + email: string; + password: string; } const validationSignUp: yup.ObjectSchema = yup.object().shape({ email: yup.string().email().required(), - password: yup.string().required() -}) + password: yup.string().required(), +}); export const SignUpPage: FC = () => { - const { register, authLoading } = useAuthentication() + const { register, authLoading } = useAuthentication(); - const resolver = yupResolver(validationSignUp) + const resolver = yupResolver(validationSignUp); const methods = useForm({ reValidateMode: "onChange", resolver, - }) + }); - const handleSubmit = useCallback(async (data: ISignUp) => { - await register(data.email, data.password) - }, [register]) + const handleSubmit = useCallback( + async (data: ISignUp) => { + await register(data.email, data.password); + }, + [register], + ); return ( - logo + logo - - Create an account + + + Create an account + handleSubmit(data))} + component="form" + onSubmit={methods.handleSubmit(async (data) => { + await handleSubmit(data); + })} noValidate sx={{ mt: 1 }} > - + - - + + Forgot password? - + Do you have an account? Sign In - {'Copyright © '} - + {"Copyright © "} + Tauffer Consulting - {' 2022.'} + {" 2022."} - ) -} + ); +}; -export default SignUpPage +export default SignUpPage; diff --git a/frontend/src/react-app-env.d.ts b/frontend/src/react-app-env.d.ts index 6431bc5f..97957c5d 100644 --- a/frontend/src/react-app-env.d.ts +++ b/frontend/src/react-app-env.d.ts @@ -1 +1,2 @@ +/* eslint-disable @typescript-eslint/triple-slash-reference */ /// diff --git a/frontend/src/services/clients/domino.client.ts b/frontend/src/services/clients/domino.client.ts index 1faebabb..e7101f54 100644 --- a/frontend/src/services/clients/domino.client.ts +++ b/frontend/src/services/clients/domino.client.ts @@ -1,17 +1,20 @@ -import axios from 'axios' +import axios from "axios"; +import { environment } from "common/config/environment.config"; +import { dispatchLogout } from "context/authentication"; -import { environment } from 'common/config/environment.config' -import { dispatchLogout } from 'context/authentication' -import { endpoints } from '../config/endpoints.config' -import { dominoMock } from './domino.mock' +import { endpoints } from "../config/endpoints.config"; + +import { dominoMock } from "./domino.mock"; export const dominoApiClient = axios.create({ - baseURL: endpoints?.api ?? '' -}) + baseURL: endpoints?.api ?? "", +}); if (environment.USE_MOCK) { - console.info('⚠ info: using mock for requests, they may be out of sync with current backend development') - dominoMock() + console.info( + "⚠ info: using mock for requests, they may be out of sync with current backend development", + ); + dominoMock(); } /** @@ -19,31 +22,28 @@ if (environment.USE_MOCK) { */ dominoApiClient.interceptors.response.use( (response) => response, - (error) => { + async (error) => { if (error.response.status === 401) { - dispatchLogout() + dispatchLogout(); } - return Promise.reject(error) - } -) + return await Promise.reject(error); + }, +); // Set header from storage on each request using interceptors dominoApiClient.interceptors.request.use( (config) => { - const token = localStorage.getItem('auth_token') + const token = localStorage.getItem("auth_token"); if (token) { config.headers = config.headers ?? {}; - config.headers.Authorization = `Bearer ${token}` - } - else { + config.headers.Authorization = `Bearer ${token}`; + } else { config.headers = config.headers ?? {}; - config.headers.Authorization = `Bearer ${token}` + config.headers.Authorization = `Bearer ${token}`; } - return config + return config; }, - (error) => { - return Promise.reject(error) - } -) - - + async (error) => { + return await Promise.reject(error); + }, +); diff --git a/frontend/src/services/clients/domino.mock.ts b/frontend/src/services/clients/domino.mock.ts index 0b934fc7..eae46a11 100644 --- a/frontend/src/services/clients/domino.mock.ts +++ b/frontend/src/services/clients/domino.mock.ts @@ -1,12 +1,21 @@ -import MockAdapter from 'axios-mock-adapter' -import { postAuthLoginMockResponse, postAuthRegisterMockResponse } from '../requests/authentication' -import { dominoApiClient } from './domino.client' +import MockAdapter from "axios-mock-adapter"; + +import { + postAuthLoginMockResponse, + postAuthRegisterMockResponse, +} from "../requests/authentication"; + +import { dominoApiClient } from "./domino.client"; export const dominoMock = () => { const dominoApiMockAdapter = new MockAdapter(dominoApiClient, { delayResponse: 3000, - onNoMatch: 'passthrough' - }) - dominoApiMockAdapter.onPost('/auth/login').reply(200, postAuthLoginMockResponse) - dominoApiMockAdapter.onPost('/auth/register').reply(200, postAuthRegisterMockResponse) -} + onNoMatch: "passthrough", + }); + dominoApiMockAdapter + .onPost("/auth/login") + .reply(200, postAuthLoginMockResponse); + dominoApiMockAdapter + .onPost("/auth/register") + .reply(200, postAuthRegisterMockResponse); +}; diff --git a/frontend/src/services/config/endpoints.config.ts b/frontend/src/services/config/endpoints.config.ts index b02ed8f3..136a022f 100644 --- a/frontend/src/services/config/endpoints.config.ts +++ b/frontend/src/services/config/endpoints.config.ts @@ -1,8 +1,8 @@ -import { IApiEnv } from 'common/interfaces/environment.interface' -import { environment } from 'common/config/environment.config' +import { environment } from "common/config/environment.config"; +import { type IApiEnv } from "common/interfaces/environment.interface"; interface IEndpoints { - api: string + api: string; } /** @@ -10,19 +10,20 @@ interface IEndpoints { */ const configEndpoints: Record = { local: { - api: 'http://localhost:8000/' + api: "http://localhost:8000/", }, dev: { - api: 'http://localhost/api' + api: "http://localhost/api", }, prod: { - api: 'http://localhost/api' - } -} + api: "http://localhost/api", + }, +}; /** * Exports all endpoints, already set up by current env */ -export const endpoints = configEndpoints[environment.API_ENV] ?? configEndpoints.dev +export const endpoints = + configEndpoints[environment.API_ENV] ?? configEndpoints.dev; -export default endpoints +export default endpoints; diff --git a/frontend/src/services/config/local-forage.config.ts b/frontend/src/services/config/local-forage.config.ts index e0be5e9a..c857e9ee 100644 --- a/frontend/src/services/config/local-forage.config.ts +++ b/frontend/src/services/config/local-forage.config.ts @@ -1,9 +1,9 @@ -import * as localForage from 'localforage' +import * as localForage from "localforage"; localForage.config({ - name: 'Domino', - storeName: 'domino_data', // Should be alphanumeric, with underscores. - description: 'Domino database' -}) + name: "Domino", + storeName: "domino_data", // Should be alphanumeric, with underscores. + description: "Domino database", +}); -export default localForage \ No newline at end of file +export default localForage; diff --git a/frontend/src/services/requests/authentication/index.ts b/frontend/src/services/requests/authentication/index.ts index e02e1bf0..7b7e7ec5 100644 --- a/frontend/src/services/requests/authentication/index.ts +++ b/frontend/src/services/requests/authentication/index.ts @@ -1,2 +1,2 @@ -export * from './post-auth-login.request' -export * from './post-auth-register.request' +export * from "./post-auth-login.request"; +export * from "./post-auth-register.request"; diff --git a/frontend/src/services/requests/authentication/post-auth-login.request.ts b/frontend/src/services/requests/authentication/post-auth-login.request.ts index 96bd8832..26de9c64 100644 --- a/frontend/src/services/requests/authentication/post-auth-login.request.ts +++ b/frontend/src/services/requests/authentication/post-auth-login.request.ts @@ -1,15 +1,16 @@ -import { AxiosResponse } from 'axios' -import { dominoApiClient } from '../../clients/domino.client' +import { type AxiosResponse } from "axios"; + +import { dominoApiClient } from "../../clients/domino.client"; interface IPostAuthLoginParams { - email: string - password: string + email: string; + password: string; } interface IPostAuthLoginResponseInterface { - user_id: string, - group_ids: number[] - access_token: string + user_id: string; + group_ids: number[]; + access_token: string; } /** @@ -18,9 +19,15 @@ interface IPostAuthLoginResponseInterface { * @returns access token */ export const postAuthLogin: ( - params: IPostAuthLoginParams -) => Promise> = (params) => { - return dominoApiClient.post('/auth/login', params) -} + params: IPostAuthLoginParams, +) => Promise> = async ( + params, +) => { + return await dominoApiClient.post("/auth/login", params); +}; -export const postAuthLoginMockResponse: IPostAuthLoginResponseInterface = { user_id: 'some_id', group_ids: [0], access_token: 'MOCK ACCESS TOKEN' } +export const postAuthLoginMockResponse: IPostAuthLoginResponseInterface = { + user_id: "some_id", + group_ids: [0], + access_token: "MOCK ACCESS TOKEN", +}; diff --git a/frontend/src/services/requests/authentication/post-auth-register.request.ts b/frontend/src/services/requests/authentication/post-auth-register.request.ts index 10705b1b..6c397ea8 100644 --- a/frontend/src/services/requests/authentication/post-auth-register.request.ts +++ b/frontend/src/services/requests/authentication/post-auth-register.request.ts @@ -1,15 +1,16 @@ -import { AxiosResponse } from 'axios' -import { dominoApiClient } from '../../clients/domino.client' +import { type AxiosResponse } from "axios"; + +import { dominoApiClient } from "../../clients/domino.client"; interface IPostAuthRegisterParams { - email: string - password: string + email: string; + password: string; } interface IPostAuthRegisterResponseInterface { - id: string - email: string - groups: { group_id: number; group_name: string }[] + id: string; + email: string; + groups: Array<{ group_id: number; group_name: string }>; } /** @@ -18,14 +19,16 @@ interface IPostAuthRegisterResponseInterface { * @returns access token */ export const postAuthRegister: ( - params: IPostAuthRegisterParams -) => Promise> = (params) => { - return dominoApiClient.post('/auth/register', params) -} + params: IPostAuthRegisterParams, +) => Promise> = async ( + params, +) => { + return await dominoApiClient.post("/auth/register", params); +}; export const postAuthRegisterMockResponse: IPostAuthRegisterResponseInterface = -{ - id: 'some_id', - email: 'some@email.com', - groups: [{ group_id: 0, group_name: 'some group' }] -} + { + id: "some_id", + email: "some@email.com", + groups: [{ group_id: 0, group_name: "some group" }], + }; diff --git a/frontend/src/services/requests/piece/get-operator-repositories.request.ts b/frontend/src/services/requests/piece/get-operator-repositories.request.ts index f6d6a8f5..8447c0fc 100644 --- a/frontend/src/services/requests/piece/get-operator-repositories.request.ts +++ b/frontend/src/services/requests/piece/get-operator-repositories.request.ts @@ -1,26 +1,31 @@ -import { AxiosResponse } from 'axios' -import useSWR from 'swr' -import { useWorkspaces } from 'context/workspaces/workspaces.context' -import { dominoApiClient } from '../../clients/domino.client' -import { IGetOperatorsRepositoriesResponseInterface } from './operator.interface' +import { type AxiosResponse } from "axios"; +import { useWorkspaces } from "context/workspaces/workspaces.context"; +import useSWR from "swr"; + +import { dominoApiClient } from "../../clients/domino.client"; + +import { type IGetOperatorsRepositoriesResponseInterface } from "./operator.interface"; interface IGetOperatorRepositoryFilters { - page?: number - page_size?: number - name__like?: string - path__like?: string - version?: string - source?: "github" | "default" + page?: number; + page_size?: number; + name__like?: string; + path__like?: string; + version?: string; + source?: "github" | "default"; } -const getOperatorsRepositoriesUrl = (workspace: string, filters: IGetOperatorRepositoryFilters) => { - const query = new URLSearchParams() - query.set('workspace_id', workspace) +const getOperatorsRepositoriesUrl = ( + workspace: string, + filters: IGetOperatorRepositoryFilters, +) => { + const query = new URLSearchParams(); + query.set("workspace_id", workspace); for (const [key, value] of Object.entries(filters)) { - query.set(key, value) + query.set(key, value); } - return `/pieces-repositories?${query.toString()}` -} + return `/pieces-repositories?${query.toString()}`; +}; /** * Get operator using GET /pieces-repositories @@ -28,32 +33,41 @@ const getOperatorsRepositoriesUrl = (workspace: string, filters: IGetOperatorRep */ const getOperatorsRepositories: ( workspace: string, - filters: IGetOperatorRepositoryFilters -) => Promise> = ( - workspace, - filters -) => { - // - return dominoApiClient.get(getOperatorsRepositoriesUrl(workspace, filters)) - } - + filters: IGetOperatorRepositoryFilters, +) => Promise< + AxiosResponse +> = async (workspace, filters) => { + // + return await dominoApiClient.get( + getOperatorsRepositoriesUrl(workspace, filters), + ); +}; /** * Get pieces repositories for current workspace * @returns pieces repositories as swr response */ -export const useAuthenticatedGetOperatorRepositories = (filters: IGetOperatorRepositoryFilters) => { - const { workspace } = useWorkspaces() +export const useAuthenticatedGetOperatorRepositories = ( + filters: IGetOperatorRepositoryFilters, +) => { + const { workspace } = useWorkspaces(); if (!workspace) throw new Error( - 'Impossible to fetch pieces repositories without specifying a workspace' - ) + "Impossible to fetch pieces repositories without specifying a workspace", + ); - const fetcher = (filters: IGetOperatorRepositoryFilters) => getOperatorsRepositories(workspace.id, filters).then((data) => data.data) + const fetcher = async (filters: IGetOperatorRepositoryFilters) => + await getOperatorsRepositories(workspace.id, filters).then( + (data) => data.data, + ); - return useSWR(getOperatorsRepositoriesUrl(workspace.id, filters), () => fetcher(filters), { - revalidateOnFocus: false, - revalidateOnReconnect: false - }) -} + return useSWR( + getOperatorsRepositoriesUrl(workspace.id, filters), + async () => await fetcher(filters), + { + revalidateOnFocus: false, + revalidateOnReconnect: false, + }, + ); +}; diff --git a/frontend/src/services/requests/piece/get-operators-repositories-releases.request.ts b/frontend/src/services/requests/piece/get-operators-repositories-releases.request.ts index 2f39f0da..f27094ef 100644 --- a/frontend/src/services/requests/piece/get-operators-repositories-releases.request.ts +++ b/frontend/src/services/requests/piece/get-operators-repositories-releases.request.ts @@ -1,10 +1,12 @@ -import { AxiosResponse } from 'axios' -import { useWorkspaces } from 'context/workspaces/workspaces.context' -import { dominoApiClient } from '../../clients/domino.client' +import { type AxiosResponse } from "axios"; +import { useWorkspaces } from "context/workspaces/workspaces.context"; + +import { dominoApiClient } from "../../clients/domino.client"; + import { - IGetOperatorsRepositoriesReleasesParams, - IGetOperatorsRepositoriesReleasesResponseInterface -} from './operator.interface' + type IGetOperatorsRepositoriesReleasesParams, + type IGetOperatorsRepositoriesReleasesResponseInterface, +} from "./operator.interface"; /** * Get operator repository releases using GET /pieces-repositories/releases @@ -12,32 +14,39 @@ import { * @returns operator repository */ const getOperatorsRepositoriesReleases: ( - params: IGetOperatorsRepositoriesReleasesParams + params: IGetOperatorsRepositoriesReleasesParams, ) => Promise< AxiosResponse -> = ({ source, path, workspaceId }) => { - const search = new URLSearchParams() - search.set('source', source) - search.set('path', path) - if (workspaceId){ - search.set('workspace_id', workspaceId) +> = async ({ source, path, workspaceId }) => { + const search = new URLSearchParams(); + search.set("source", source); + search.set("path", path); + if (workspaceId) { + search.set("workspace_id", workspaceId); } - return dominoApiClient.get(`/pieces-repositories/releases?${search.toString()}`) -} + return await dominoApiClient.get( + `/pieces-repositories/releases?${search.toString()}`, + ); +}; /** * Get releases for a given operator repository * @returns pieces repositories releases */ export const useAuthenticatedGetOperatorRepositoriesReleases = () => { - const { workspace } = useWorkspaces() + const { workspace } = useWorkspaces(); if (!workspace) throw new Error( - 'Impossible to fetch pieces repositories without specifying a workspace' - ) + "Impossible to fetch pieces repositories without specifying a workspace", + ); - return (params: IGetOperatorsRepositoriesReleasesParams) => - getOperatorsRepositoriesReleases({...params, workspaceId: workspace.id}).then((data) => { return data.data }) -} + return async (params: IGetOperatorsRepositoriesReleasesParams) => + await getOperatorsRepositoriesReleases({ + ...params, + workspaceId: workspace.id, + }).then((data) => { + return data.data; + }); +}; diff --git a/frontend/src/services/requests/piece/get-piece-repository-pieces.request.ts b/frontend/src/services/requests/piece/get-piece-repository-pieces.request.ts index cd09d799..610ace1e 100644 --- a/frontend/src/services/requests/piece/get-piece-repository-pieces.request.ts +++ b/frontend/src/services/requests/piece/get-piece-repository-pieces.request.ts @@ -1,10 +1,12 @@ -import { AxiosResponse } from 'axios' -import { useCallback } from 'react' -import { dominoApiClient } from '../../clients/domino.client' -import { IGetRepoOperatorsResponseInterface } from './operator.interface' +import { type AxiosResponse } from "axios"; +import { useCallback } from "react"; + +import { dominoApiClient } from "../../clients/domino.client"; + +import { type IGetRepoOperatorsResponseInterface } from "./operator.interface"; interface IGetRepoOperatorsParams { - id: string + id: string; } /** @@ -14,12 +16,12 @@ interface IGetRepoOperatorsParams { * @returns pieces */ const getRepoIdOperators: (args: { - params: IGetRepoOperatorsParams -} -) => Promise> = ({ params }) => { - return dominoApiClient.get(`pieces-repositories/${params.id}/pieces`) -} - + params: IGetRepoOperatorsParams; +}) => Promise> = async ({ + params, +}) => { + return await dominoApiClient.get(`pieces-repositories/${params.id}/pieces`); +}; /** * Get pieces by repo id authenticated fetcher function @@ -28,8 +30,7 @@ const getRepoIdOperators: (args: { */ export const useFetchAuthenticatedGetRepoIdOperators = () => { const fetcher = useCallback(async (params: IGetRepoOperatorsParams) => { - return getRepoIdOperators({ params }).then(data => data.data) - }, []) - return fetcher -} - + return await getRepoIdOperators({ params }).then((data) => data.data); + }, []); + return fetcher; +}; diff --git a/frontend/src/services/requests/piece/index.ts b/frontend/src/services/requests/piece/index.ts index 42a0fc91..10592dcf 100644 --- a/frontend/src/services/requests/piece/index.ts +++ b/frontend/src/services/requests/piece/index.ts @@ -1,2 +1,2 @@ -export * from './get-operator-repositories.request' -export * from './operator.interface' +export * from "./get-operator-repositories.request"; +export * from "./operator.interface"; diff --git a/frontend/src/services/requests/piece/operator.interface.ts b/frontend/src/services/requests/piece/operator.interface.ts index 235b5f6b..4a05e1b0 100644 --- a/frontend/src/services/requests/piece/operator.interface.ts +++ b/frontend/src/services/requests/piece/operator.interface.ts @@ -1,132 +1,123 @@ -import { ERepositorySource } from 'common/interfaces/repository-source.enum' +import { type ERepositorySource } from "common/interfaces/repository-source.enum"; /** * Operator object */ export interface IOperator { - id: string - name: string - description: string + id: string; + name: string; + description: string; dependency: { - docker_image: string | null - dockerfile: string | null - requirements_file: string | null - } - docker_image: string - input_schema: IIOSchema - output_schema: IIOSchema - secrets_schema: IIOSchema | null - source_url: string | null + docker_image: string | null; + dockerfile: string | null; + requirements_file: string | null; + }; + docker_image: string; + input_schema: IIOSchema; + output_schema: IIOSchema; + secrets_schema: IIOSchema | null; + source_url: string | null; style?: { - module?: string - label?: string - nodeType?: string - nodeStyle?: any - useIcon?: boolean - iconClassName?: string - iconStyle?: any - } - repository_id: string + module?: string; + label?: string; + nodeType?: string; + nodeStyle?: any; + useIcon?: boolean; + iconClassName?: string; + iconStyle?: any; + }; + repository_id: string; } -export interface IOperatorForageSchema { - [key: string | number]: IOperator -} +export type IOperatorForageSchema = Record; -export interface IRepositoryOperators { - [key: string | number]: IOperator[] -} +export type IRepositoryOperators = Record; /** * Operator input/output schema */ export interface IIOProperty { - title: string - type: string - description: string | null - default: string | null - allOf: any[] | null + title: string; + type: string; + description: string | null; + default: string | null; + allOf: any[] | null; } export interface IIOSchema { - title: string - description: string - type: string - properties: any - required: string[] - definitions: any + title: string; + description: string; + type: string; + properties: any; + required: string[]; + definitions: any; } - - export interface IOperatorRepository { - id: string - name: string - label: string - created_at: string - source: string - path: string - version: string - workspace_id: number + id: string; + name: string; + label: string; + created_at: string; + source: string; + path: string; + version: string; + workspace_id: number; } export interface IOperatorSchema { - Operator_config: IOperatorConfig - tasks: Record + Operator_config: IOperatorConfig; + tasks: Record; } export interface IOperatorConfig { - name: string - start_date: string - end_date: string - schedule_interval: string - catchup: boolean - generate_report: string - description: string + name: string; + start_date: string; + end_date: string; + schedule_interval: string; + catchup: boolean; + generate_report: string; + description: string; } interface IPaginationMetadata { - page: number - records: number - total: number - last_page: number + page: number; + records: number; + total: number; + last_page: number; } /** * Get Operator Repositories response interface */ -export type IGetOperatorsRepositoriesResponseInterface = { - data: IOperatorRepository[] - metadata: IPaginationMetadata +export interface IGetOperatorsRepositoriesResponseInterface { + data: IOperatorRepository[]; + metadata: IPaginationMetadata; } /** * Get Operator Repositories id Operators */ -export type IGetRepoOperatorsResponseInterface = IOperator[] - - +export type IGetRepoOperatorsResponseInterface = IOperator[]; /** * Operator repository metadata */ -export type IOperatorRepositoryMetadata = { - version: string - last_modified: string +export interface IOperatorRepositoryMetadata { + version: string; + last_modified: string; } /** * Get Operators Repositories Releases response interface */ export type IGetOperatorsRepositoriesReleasesResponseInterface = - IOperatorRepositoryMetadata[] - + IOperatorRepositoryMetadata[]; /** * Get Operators Repositories Releases request params */ -export type IGetOperatorsRepositoriesReleasesParams = { - source: ERepositorySource - path: string - workspaceId?: string +export interface IGetOperatorsRepositoriesReleasesParams { + source: ERepositorySource; + path: string; + workspaceId?: string; } diff --git a/frontend/src/services/requests/repository/delete-operator-repository.request.ts b/frontend/src/services/requests/repository/delete-operator-repository.request.ts index 1510bdcc..65159535 100644 --- a/frontend/src/services/requests/repository/delete-operator-repository.request.ts +++ b/frontend/src/services/requests/repository/delete-operator-repository.request.ts @@ -1,33 +1,33 @@ // TODO move to /runs -import { AxiosResponse } from 'axios' -import { useWorkspaces } from 'context/workspaces/workspaces.context' +import { type AxiosResponse } from "axios"; +import { useWorkspaces } from "context/workspaces/workspaces.context"; +import { dominoApiClient } from "../../clients/domino.client"; -import { dominoApiClient } from '../../clients/domino.client' - - -const deleteRepositoryUrl = (id: string) => `/pieces-repositories/${id}` +const deleteRepositoryUrl = (id: string) => `/pieces-repositories/${id}`; /** * Run workflow by id using /workflow/run/:id * @returns workflow run result */ -const deleteRepository: (id: string) => Promise = (id) => { - return dominoApiClient.delete(deleteRepositoryUrl(id)) -} +const deleteRepository: (id: string) => Promise = async (id) => { + return await dominoApiClient.delete(deleteRepositoryUrl(id)); +}; /** * Run workflow by id fetcher fn * @param params `{ id: string }` */ export const useAuthenticatedDeleteRepository = () => { - const { workspace } = useWorkspaces() - - if (!workspace) throw new Error('Impossible to run workflows without specifying a workspace') + const { workspace } = useWorkspaces(); - const fetcher = (id: string) => - deleteRepository(id).then(data => data) + if (!workspace) + throw new Error( + "Impossible to run workflows without specifying a workspace", + ); - return fetcher -} + const fetcher = async (id: string) => + await deleteRepository(id).then((data) => data); + return fetcher; +}; diff --git a/frontend/src/services/requests/repository/get-operator-repository-secrets.request.ts b/frontend/src/services/requests/repository/get-operator-repository-secrets.request.ts index 25570626..9530517a 100644 --- a/frontend/src/services/requests/repository/get-operator-repository-secrets.request.ts +++ b/frontend/src/services/requests/repository/get-operator-repository-secrets.request.ts @@ -1,58 +1,63 @@ -import { AxiosResponse } from 'axios' -import useSWR from 'swr' -import { useWorkspaces } from 'context/workspaces/workspaces.context' +import { type AxiosResponse } from "axios"; +import { useWorkspaces } from "context/workspaces/workspaces.context"; +import useSWR from "swr"; +import { dominoApiClient } from "../../clients/domino.client"; -import { dominoApiClient } from '../../clients/domino.client' -import { IOperatorRepositorySecretsData } from './operator-repository.interface' - +import { type IOperatorRepositorySecretsData } from "./operator-repository.interface"; interface IGetRepositorySecretsParams { - repositoryId: string + repositoryId: string; } - -const getRepositorySecretsUrl = ( - repositoryId: string -) => `/pieces-repositories/${repositoryId}/secrets` +const getRepositorySecretsUrl = (repositoryId: string) => + `/pieces-repositories/${repositoryId}/secrets`; /** * Get workflows using GET /workflows * @returns workflow */ const getRepositorySecrets: ( - repositoryId: string, -) => Promise> = (repositoryId) => { - - return dominoApiClient.get(getRepositorySecretsUrl(repositoryId)) -} + repositoryId: string, +) => Promise> = async ( + repositoryId, +) => { + return await dominoApiClient.get(getRepositorySecretsUrl(repositoryId)); +}; export const useAuthenticatedGetWorkflowRunTasksFetcher = () => { - const { workspace } = useWorkspaces() + const { workspace } = useWorkspaces(); - if (!workspace) throw new Error('Impossible to fetch workflows without specifying a workspace') + if (!workspace) + throw new Error( + "Impossible to fetch workflows without specifying a workspace", + ); - return (params: IGetRepositorySecretsParams,) => getRepositorySecrets( - params.repositoryId - ).then(data => data.data) -} + return async (params: IGetRepositorySecretsParams) => + await getRepositorySecrets(params.repositoryId).then((data) => data.data); +}; /** * Get workflow runs * @returns runs as swr response */ -export const useAuthenticatedGetRepositorySecrets = (params: IGetRepositorySecretsParams) => { - const { workspace } = useWorkspaces() - if (!workspace) throw new Error('Impossible to fetch workflows without specifying a workspace') - - const fetcher = useAuthenticatedGetWorkflowRunTasksFetcher() - - return useSWR( - params.repositoryId ? getRepositorySecretsUrl(params.repositoryId) : null, - () => fetcher(params), - { - revalidateOnFocus: false, - revalidateOnReconnect: false - } - ) -} \ No newline at end of file +export const useAuthenticatedGetRepositorySecrets = ( + params: IGetRepositorySecretsParams, +) => { + const { workspace } = useWorkspaces(); + if (!workspace) + throw new Error( + "Impossible to fetch workflows without specifying a workspace", + ); + + const fetcher = useAuthenticatedGetWorkflowRunTasksFetcher(); + + return useSWR( + params.repositoryId ? getRepositorySecretsUrl(params.repositoryId) : null, + async () => await fetcher(params), + { + revalidateOnFocus: false, + revalidateOnReconnect: false, + }, + ); +}; diff --git a/frontend/src/services/requests/repository/index.ts b/frontend/src/services/requests/repository/index.ts index 8da2f350..a18bda2f 100644 --- a/frontend/src/services/requests/repository/index.ts +++ b/frontend/src/services/requests/repository/index.ts @@ -1,3 +1,3 @@ -export * from './get-operator-repository-secrets.request' -export * from './patch-operator-repository-secret.request' -export * from './delete-operator-repository.request' \ No newline at end of file +export * from "./get-operator-repository-secrets.request"; +export * from "./patch-operator-repository-secret.request"; +export * from "./delete-operator-repository.request"; diff --git a/frontend/src/services/requests/repository/operator-repository.interface.ts b/frontend/src/services/requests/repository/operator-repository.interface.ts index 7ef7f9fc..bd14ea55 100644 --- a/frontend/src/services/requests/repository/operator-repository.interface.ts +++ b/frontend/src/services/requests/repository/operator-repository.interface.ts @@ -1,5 +1,5 @@ export interface IOperatorRepositorySecretsData { - id: number - name: string - is_filled: boolean -} \ No newline at end of file + id: number; + name: string; + is_filled: boolean; +} diff --git a/frontend/src/services/requests/repository/patch-operator-repository-secret.request.ts b/frontend/src/services/requests/repository/patch-operator-repository-secret.request.ts index a22612c4..f2079e03 100644 --- a/frontend/src/services/requests/repository/patch-operator-repository-secret.request.ts +++ b/frontend/src/services/requests/repository/patch-operator-repository-secret.request.ts @@ -1,48 +1,47 @@ // TODO move to /runs -import { AxiosResponse } from 'axios' -import { useWorkspaces } from 'context/workspaces/workspaces.context' - - -import { dominoApiClient } from '../../clients/domino.client' +import { type AxiosResponse } from "axios"; +import { useWorkspaces } from "context/workspaces/workspaces.context"; +import { dominoApiClient } from "../../clients/domino.client"; interface PatchRepositorySecretParams { - repositoryId: string - secretId: string, - payload: { - value: string | null - } + repositoryId: string; + secretId: string; + payload: { + value: string | null; + }; } -const patchRepositorySecretUrl = (repositoryId: string, secretId: string) => `/pieces-repositories/${repositoryId}/secrets/${secretId}` +const patchRepositorySecretUrl = (repositoryId: string, secretId: string) => + `/pieces-repositories/${repositoryId}/secrets/${secretId}`; /** * Run workflow by id using /workflow/run/:id * @returns workflow run result */ const patchRepositorySecret: ( - params: PatchRepositorySecretParams -) => Promise = (params) => { - - return dominoApiClient.patch(patchRepositorySecretUrl(params.repositoryId, params.secretId), params.payload) -} + params: PatchRepositorySecretParams, +) => Promise = async (params) => { + return await dominoApiClient.patch( + patchRepositorySecretUrl(params.repositoryId, params.secretId), + params.payload, + ); +}; /** * Run workflow by id fetcher fn * @param params `{ id: string }` */ export const useAuthenticatedPatchRepositorySecret = () => { - const { workspace } = useWorkspaces() - - if (!workspace) throw new Error('Impossible to run workflows without specifying a workspace') - - const fetcher = (params: PatchRepositorySecretParams) => - patchRepositorySecret( - params - ).then(data => data) - - return fetcher -} + const { workspace } = useWorkspaces(); + if (!workspace) + throw new Error( + "Impossible to run workflows without specifying a workspace", + ); + const fetcher = async (params: PatchRepositorySecretParams) => + await patchRepositorySecret(params).then((data) => data); + return fetcher; +}; diff --git a/frontend/src/services/requests/runs/get-workflow-run-task-logs.request.ts b/frontend/src/services/requests/runs/get-workflow-run-task-logs.request.ts index 4f75dad1..0a9fae8a 100644 --- a/frontend/src/services/requests/runs/get-workflow-run-task-logs.request.ts +++ b/frontend/src/services/requests/runs/get-workflow-run-task-logs.request.ts @@ -1,54 +1,71 @@ -import { AxiosResponse } from 'axios' -import { useWorkspaces } from 'context/workspaces/workspaces.context' +import { type AxiosResponse } from "axios"; +import { useWorkspaces } from "context/workspaces/workspaces.context"; +import { dominoApiClient } from "../../clients/domino.client"; -import { dominoApiClient } from '../../clients/domino.client' -import { IGetWorkflowRunTasksResponseInterface } from './runs.interface' - +import { type IGetWorkflowRunTasksResponseInterface } from "./runs.interface"; export interface IGetWorkflowRunTaskLogsParams { - workflowId: string - runId: string - taskId: string - taskTryNumber: string + workflowId: string; + runId: string; + taskId: string; + taskTryNumber: string; } - const getWorkflowRunTaskLogsUrl = ( - workspace: string, - workflowId: string, - runId: string, - taskId: string, - taskTryNumber: string -) => `/workspaces/${workspace}/workflows/${workflowId}/runs/${runId}/tasks/${taskId}/${taskTryNumber}/logs` + workspace: string, + workflowId: string, + runId: string, + taskId: string, + taskTryNumber: string, +) => + `/workspaces/${workspace}/workflows/${workflowId}/runs/${runId}/tasks/${taskId}/${taskTryNumber}/logs`; /** * Get workflows using GET /workflows * @returns workflow */ const getWorkflowRunTaskLogs: ( - workspace: string, - workflowId: string, - runId: string, - taskId: string, - taskTryNumber: string -) => Promise> = (workspace, workflowId, runId, taskId, taskTryNumber) => { - return dominoApiClient.get(getWorkflowRunTaskLogsUrl(workspace, workflowId, runId, taskId, taskTryNumber)) -} + workspace: string, + workflowId: string, + runId: string, + taskId: string, + taskTryNumber: string, +) => Promise> = async ( + workspace, + workflowId, + runId, + taskId, + taskTryNumber, +) => { + return await dominoApiClient.get( + getWorkflowRunTaskLogsUrl( + workspace, + workflowId, + runId, + taskId, + taskTryNumber, + ), + ); +}; /** * Get workflow runs * @returns runs as swr response */ export const useAuthenticatedGetWorkflowRunTaskLogs = () => { - const { workspace } = useWorkspaces() - if (!workspace) throw new Error('Impossible to fetch workflows without specifying a workspace') + const { workspace } = useWorkspaces(); + if (!workspace) + throw new Error( + "Impossible to fetch workflows without specifying a workspace", + ); - return (params: IGetWorkflowRunTaskLogsParams) => getWorkflowRunTaskLogs( - workspace.id, - params.workflowId, - params.runId, - params.taskId, - params.taskTryNumber - ).then(data => data.data) -} + return async (params: IGetWorkflowRunTaskLogsParams) => + await getWorkflowRunTaskLogs( + workspace.id, + params.workflowId, + params.runId, + params.taskId, + params.taskTryNumber, + ).then((data) => data.data); +}; diff --git a/frontend/src/services/requests/runs/get-workflow-run-task-result.request.ts b/frontend/src/services/requests/runs/get-workflow-run-task-result.request.ts index df36e91e..dbf11b77 100644 --- a/frontend/src/services/requests/runs/get-workflow-run-task-result.request.ts +++ b/frontend/src/services/requests/runs/get-workflow-run-task-result.request.ts @@ -1,54 +1,71 @@ -import { AxiosResponse } from 'axios' -import { useWorkspaces } from 'context/workspaces/workspaces.context' +import { type AxiosResponse } from "axios"; +import { useWorkspaces } from "context/workspaces/workspaces.context"; +import { dominoApiClient } from "../../clients/domino.client"; -import { dominoApiClient } from '../../clients/domino.client' -import { IGetWorkflowRunTasksResponseInterface } from './runs.interface' - +import { type IGetWorkflowRunTasksResponseInterface } from "./runs.interface"; export interface IGetWorkflowRunTaskResultParams { - workflowId: string - runId: string - taskId: string - taskTryNumber: string + workflowId: string; + runId: string; + taskId: string; + taskTryNumber: string; } - const getWorkflowRunTaskResultUrl = ( - workspace: string, - workflowId: string, - runId: string, - taskId: string, - taskTryNumber: string -) => `/workspaces/${workspace}/workflows/${workflowId}/runs/${runId}/tasks/${taskId}/${taskTryNumber}/result` + workspace: string, + workflowId: string, + runId: string, + taskId: string, + taskTryNumber: string, +) => + `/workspaces/${workspace}/workflows/${workflowId}/runs/${runId}/tasks/${taskId}/${taskTryNumber}/result`; /** * Get workflows using GET /workflows * @returns workflow */ const getWorkflowRunTaskResult: ( - workspace: string, - workflowId: string, - runId: string, - taskId: string, - taskTryNumber: string -) => Promise> = (workspace, workflowId, runId, taskId, taskTryNumber) => { - return dominoApiClient.get(getWorkflowRunTaskResultUrl(workspace, workflowId, runId, taskId, taskTryNumber)) -} + workspace: string, + workflowId: string, + runId: string, + taskId: string, + taskTryNumber: string, +) => Promise> = async ( + workspace, + workflowId, + runId, + taskId, + taskTryNumber, +) => { + return await dominoApiClient.get( + getWorkflowRunTaskResultUrl( + workspace, + workflowId, + runId, + taskId, + taskTryNumber, + ), + ); +}; /** * Get workflow runs * @returns runs as swr response */ export const useAuthenticatedGetWorkflowRunTaskResult = () => { - const { workspace } = useWorkspaces() - if (!workspace) throw new Error('Impossible to fetch workflows without specifying a workspace') + const { workspace } = useWorkspaces(); + if (!workspace) + throw new Error( + "Impossible to fetch workflows without specifying a workspace", + ); - return (params: IGetWorkflowRunTaskResultParams) => getWorkflowRunTaskResult( - workspace.id, - params.workflowId, - params.runId, - params.taskId, - params.taskTryNumber - ).then(data => data.data) -} + return async (params: IGetWorkflowRunTaskResultParams) => + await getWorkflowRunTaskResult( + workspace.id, + params.workflowId, + params.runId, + params.taskId, + params.taskTryNumber, + ).then((data) => data.data); +}; diff --git a/frontend/src/services/requests/runs/get-workflow-run-tasks.request.ts b/frontend/src/services/requests/runs/get-workflow-run-tasks.request.ts index a6b022e6..9e25a463 100644 --- a/frontend/src/services/requests/runs/get-workflow-run-tasks.request.ts +++ b/frontend/src/services/requests/runs/get-workflow-run-tasks.request.ts @@ -1,52 +1,65 @@ -import { AxiosResponse } from 'axios' -import { useWorkspaces } from 'context/workspaces/workspaces.context' -import { dominoApiClient } from '../../clients/domino.client' -import { IGetWorkflowRunTasksResponseInterface } from './runs.interface' +import { type AxiosResponse } from "axios"; +import { useWorkspaces } from "context/workspaces/workspaces.context"; +import { dominoApiClient } from "../../clients/domino.client"; + +import { type IGetWorkflowRunTasksResponseInterface } from "./runs.interface"; export interface IGetWorkflowRunTasksParams { - workflowId: string - runId: string - page: number - pageSize: number + workflowId: string; + runId: string; + page: number; + pageSize: number; } - const getWorkflowRunTasksUrl = ( - workspace: string, - workflowId: string, - runId: string, - page: number, - pageSize: number -) => `/workspaces/${workspace}/workflows/${workflowId}/runs/${runId}/tasks?page=${page}&page_size=${pageSize}` + workspace: string, + workflowId: string, + runId: string, + page: number, + pageSize: number, +) => + `/workspaces/${workspace}/workflows/${workflowId}/runs/${runId}/tasks?page=${page}&page_size=${pageSize}`; /** * Get workflows using GET /workflows * @returns workflow */ const getWorkflowRunTasks: ( - workspace: string, - workflowId: string, - runId: string, - page: number, - pageSize: number -) => Promise> = (workspace, workflowId, runId, page, pageSize) => { - return dominoApiClient.get(getWorkflowRunTasksUrl(workspace, workflowId, runId, page, pageSize)) -} + workspace: string, + workflowId: string, + runId: string, + page: number, + pageSize: number, +) => Promise> = async ( + workspace, + workflowId, + runId, + page, + pageSize, +) => { + return await dominoApiClient.get( + getWorkflowRunTasksUrl(workspace, workflowId, runId, page, pageSize), + ); +}; /** * Get workflow runs * @returns runs as swr response */ export const useAuthenticatedGetWorkflowRunTasks = () => { - const { workspace } = useWorkspaces() - if (!workspace) throw new Error('Impossible to fetch workflows without specifying a workspace') + const { workspace } = useWorkspaces(); + if (!workspace) + throw new Error( + "Impossible to fetch workflows without specifying a workspace", + ); - return (params: IGetWorkflowRunTasksParams,) => getWorkflowRunTasks( - workspace.id, - params.workflowId, - params.runId, - params.page, - params.pageSize - ).then(data => data.data) -} + return async (params: IGetWorkflowRunTasksParams) => + await getWorkflowRunTasks( + workspace.id, + params.workflowId, + params.runId, + params.page, + params.pageSize, + ).then((data) => data.data); +}; diff --git a/frontend/src/services/requests/runs/get-workflow-runs.request.ts b/frontend/src/services/requests/runs/get-workflow-runs.request.ts index 94662f17..185c8be9 100644 --- a/frontend/src/services/requests/runs/get-workflow-runs.request.ts +++ b/frontend/src/services/requests/runs/get-workflow-runs.request.ts @@ -1,57 +1,89 @@ -import { AxiosResponse } from 'axios' -import useSWR from 'swr' -import { useWorkspaces } from 'context/workspaces/workspaces.context' +import { type AxiosResponse } from "axios"; +import { useWorkspaces } from "context/workspaces/workspaces.context"; +import useSWR from "swr"; -import { dominoApiClient } from '../../clients/domino.client' -import { IGetWorkflowRunsResponseInterface } from './runs.interface' +import { dominoApiClient } from "../../clients/domino.client"; +import { type IGetWorkflowRunsResponseInterface } from "./runs.interface"; interface IGetWorkflowRunParams { - workflowId: string - page: number - pageSize: number + workflowId: string; + page: number; + pageSize: number; } - -const getWorkflowRunsUrl = (workspace: string, workflowId: string, page: number, pageSize: number) => `/workspaces/${workspace}/workflows/${workflowId}/runs?page=${page}&page_size=${pageSize}` +const getWorkflowRunsUrl = ( + workspace: string, + workflowId: string, + page: number, + pageSize: number, +) => + `/workspaces/${workspace}/workflows/${workflowId}/runs?page=${page}&page_size=${pageSize}`; /** * Get workflows using GET /workflows * @returns workflow */ const getWorkflowRuns: ( - workspace: string, - workflowId: string, - page: number, - pageSize: number -) => Promise> = (workspace, workflowId, page, pageSize) => { - - return dominoApiClient.get(getWorkflowRunsUrl(workspace, workflowId, page, pageSize)) -} + workspace: string, + workflowId: string, + page: number, + pageSize: number, +) => Promise> = async ( + workspace, + workflowId, + page, + pageSize, +) => { + return await dominoApiClient.get( + getWorkflowRunsUrl(workspace, workflowId, page, pageSize), + ); +}; export const useAuthenticatedGetWorkflowRunFetcher = () => { - const { workspace } = useWorkspaces() - if (!workspace) throw new Error('Impossible to fetch workflows without specifying a workspace') + const { workspace } = useWorkspaces(); + if (!workspace) + throw new Error( + "Impossible to fetch workflows without specifying a workspace", + ); - return (params: IGetWorkflowRunParams,) => getWorkflowRuns(workspace.id, params.workflowId, params.page, params.pageSize).then(data => data.data) -} + return async (params: IGetWorkflowRunParams) => + await getWorkflowRuns( + workspace.id, + params.workflowId, + params.page, + params.pageSize, + ).then((data) => data.data); +}; /** * Get workflow runs * @returns runs as swr response */ -export const useAuthenticatedGetWorkflowRuns = (params: IGetWorkflowRunParams) => { - const { workspace } = useWorkspaces() - if (!workspace) throw new Error('Impossible to fetch workflows without specifying a workspace') - - const fetcher = useAuthenticatedGetWorkflowRunFetcher() - - return useSWR( - params.workflowId ? getWorkflowRunsUrl(workspace.id, params.workflowId, params.page, params.pageSize) : null, - () => fetcher(params), - { - revalidateOnFocus: false, - revalidateOnReconnect: false - } - ) -} +export const useAuthenticatedGetWorkflowRuns = ( + params: IGetWorkflowRunParams, +) => { + const { workspace } = useWorkspaces(); + if (!workspace) + throw new Error( + "Impossible to fetch workflows without specifying a workspace", + ); + + const fetcher = useAuthenticatedGetWorkflowRunFetcher(); + + return useSWR( + params.workflowId + ? getWorkflowRunsUrl( + workspace.id, + params.workflowId, + params.page, + params.pageSize, + ) + : null, + async () => await fetcher(params), + { + revalidateOnFocus: false, + revalidateOnReconnect: false, + }, + ); +}; diff --git a/frontend/src/services/requests/runs/index.ts b/frontend/src/services/requests/runs/index.ts index bcaf05da..e8803f5c 100644 --- a/frontend/src/services/requests/runs/index.ts +++ b/frontend/src/services/requests/runs/index.ts @@ -1,5 +1,5 @@ -export * from './get-workflow-runs.request' -export * from './get-workflow-run-tasks.request' -export * from './get-workflow-run-task-logs.request' -export * from './get-workflow-run-task-result.request' -export * from './runs.interface' \ No newline at end of file +export * from "./get-workflow-runs.request"; +export * from "./get-workflow-run-tasks.request"; +export * from "./get-workflow-run-task-logs.request"; +export * from "./get-workflow-run-task-result.request"; +export * from "./runs.interface"; diff --git a/frontend/src/services/requests/runs/runs.interface.ts b/frontend/src/services/requests/runs/runs.interface.ts index e9ee54f4..29d5707a 100644 --- a/frontend/src/services/requests/runs/runs.interface.ts +++ b/frontend/src/services/requests/runs/runs.interface.ts @@ -1,62 +1,61 @@ interface IPaginationMetadata { - page: number - last_page: number - records: number - total: number + page: number; + last_page: number; + records: number; + total: number; } enum RunState { - success = 'success', - failed = 'failed', - running = 'running', - queued = 'queued', + success = "success", + failed = "failed", + running = "running", + queued = "queued", } enum TaskState { - success = 'success', - running = 'running', - failed = 'failed', - upstream_failed = 'upstream_failed', - skipped = 'skipped', - up_for_retry = 'up_for_retry', - up_for_reschedule = 'up_for_reschedule', - queued = 'queued', - none = 'none', - scheduled = 'scheduled', - deferred = 'deferred', - removed = 'removed', - restarting = 'restarting', + success = "success", + running = "running", + failed = "failed", + upstream_failed = "upstream_failed", + skipped = "skipped", + up_for_retry = "up_for_retry", + up_for_reschedule = "up_for_reschedule", + queued = "queued", + none = "none", + scheduled = "scheduled", + deferred = "deferred", + removed = "removed", + restarting = "restarting", } - export interface IWorkflowRuns { - workflow_uuid: string - workflow_run_id: string - start_date: string - end_date: string - execution_date: string - state: RunState + workflow_uuid: string; + workflow_run_id: string; + start_date: string; + end_date: string; + execution_date: string; + state: RunState; } export interface IWorkflowRunTasks { - workflow_uuid: string - workflow_run_id: string - duration: number - start_date: string - end_date: string - execution_date: string - docker_image: string - task_id: string - try_number: number - state: TaskState + workflow_uuid: string; + workflow_run_id: string; + duration: number; + start_date: string; + end_date: string; + execution_date: string; + docker_image: string; + task_id: string; + try_number: number; + state: TaskState; } -export type IGetWorkflowRunsResponseInterface = { - data?: IWorkflowRuns[] - metadata?: IPaginationMetadata +export interface IGetWorkflowRunsResponseInterface { + data?: IWorkflowRuns[]; + metadata?: IPaginationMetadata; } export interface IGetWorkflowRunTasksResponseInterface { - data?: IWorkflowRunTasks[] - metadata?: IPaginationMetadata -} \ No newline at end of file + data?: IWorkflowRunTasks[]; + metadata?: IPaginationMetadata; +} diff --git a/frontend/src/services/requests/workflow/delete-workflow-id.request.ts b/frontend/src/services/requests/workflow/delete-workflow-id.request.ts index b82560df..d5364696 100644 --- a/frontend/src/services/requests/workflow/delete-workflow-id.request.ts +++ b/frontend/src/services/requests/workflow/delete-workflow-id.request.ts @@ -1,10 +1,12 @@ -import { AxiosResponse } from 'axios' -import { dominoApiClient } from '../../clients/domino.client' -import { IDeleteWorkflowIdResponseInterface } from './workflow.interface' -import { useWorkspaces } from 'context/workspaces/workspaces.context' +import { type AxiosResponse } from "axios"; +import { useWorkspaces } from "context/workspaces/workspaces.context"; + +import { dominoApiClient } from "../../clients/domino.client"; + +import { type IDeleteWorkflowIdResponseInterface } from "./workflow.interface"; interface IDeleteWorkflowIdParams { - id: string + id: string; } /** @@ -13,25 +15,29 @@ interface IDeleteWorkflowIdParams { */ const deleteWorkflowId: ( workspaceId: string, - params: IDeleteWorkflowIdParams -) => Promise> = (workspaceId, params) => { - return dominoApiClient.delete(`/workspaces/${workspaceId}/workflows/${params.id}`) -} + params: IDeleteWorkflowIdParams, +) => Promise> = async ( + workspaceId, + params, +) => { + return await dominoApiClient.delete( + `/workspaces/${workspaceId}/workflows/${params.id}`, + ); +}; /** * Delete workflow by id - * @returns authenticated delete function + * @returns authenticated delete function */ export const useAuthenticatedDeleteWorkflowId = () => { - const { workspace } = useWorkspaces() + const { workspace } = useWorkspaces(); - if (!workspace) throw new Error('Impossible to fetch delete without specifying a workspace') + if (!workspace) + throw new Error( + "Impossible to fetch delete without specifying a workspace", + ); - const fetcher = (params: IDeleteWorkflowIdParams) => - deleteWorkflowId( - workspace.id as string, - params - ).then(data => data) - return fetcher - -} + const fetcher = async (params: IDeleteWorkflowIdParams) => + await deleteWorkflowId(workspace.id, params).then((data) => data); + return fetcher; +}; diff --git a/frontend/src/services/requests/workflow/get-workflow-id.request.ts b/frontend/src/services/requests/workflow/get-workflow-id.request.ts index 2aed36c8..4771a48c 100644 --- a/frontend/src/services/requests/workflow/get-workflow-id.request.ts +++ b/frontend/src/services/requests/workflow/get-workflow-id.request.ts @@ -1,13 +1,16 @@ -import { AxiosResponse } from 'axios' -import { useWorkspaces } from 'context/workspaces/workspaces.context' -import { dominoApiClient } from '../../clients/domino.client' -import { IGetWorkflowIdResponseInterface } from './workflow.interface' +import { type AxiosResponse } from "axios"; +import { useWorkspaces } from "context/workspaces/workspaces.context"; + +import { dominoApiClient } from "../../clients/domino.client"; + +import { type IGetWorkflowIdResponseInterface } from "./workflow.interface"; interface IGetWorkflowIdParams { - id: string + id: string; } -const getWorkflowUrl = (workspaceId: string, id: string) => `/workspaces/${workspaceId}/workflows/${id}` +const getWorkflowUrl = (workspaceId: string, id: string) => + `/workspaces/${workspaceId}/workflows/${id}`; /** * Get workflow by id using GET /workflow @@ -15,12 +18,13 @@ const getWorkflowUrl = (workspaceId: string, id: string) => `/workspaces/${works */ const getWorkflowId: ( workspaceId: string, - params: IGetWorkflowIdParams -) => Promise> = (workspaceId, params) => { - - return dominoApiClient.get(getWorkflowUrl(workspaceId, params.id)) -} - + params: IGetWorkflowIdParams, +) => Promise> = async ( + workspaceId, + params, +) => { + return await dominoApiClient.get(getWorkflowUrl(workspaceId, params.id)); +}; /** * Get workflow by id @@ -28,18 +32,17 @@ const getWorkflowId: ( * @returns workflow fetcher fn */ export const useAuthenticatedGetWorkflowId = () => { - const { workspace } = useWorkspaces() + const { workspace } = useWorkspaces(); - if (!workspace) throw new Error('Impossible to fetch workflows without specifying a workspace') + if (!workspace) + throw new Error( + "Impossible to fetch workflows without specifying a workspace", + ); // todo add swr ? - const fetcher = (params: IGetWorkflowIdParams) => { - return getWorkflowId( - workspace.id as string, - params - ).then(data => data.data) - } - - return fetcher + const fetcher = async (params: IGetWorkflowIdParams) => { + return await getWorkflowId(workspace.id, params).then((data) => data.data); + }; -} + return fetcher; +}; diff --git a/frontend/src/services/requests/workflow/get-workflow.request.ts b/frontend/src/services/requests/workflow/get-workflow.request.ts index be850ce1..4c1728ee 100644 --- a/frontend/src/services/requests/workflow/get-workflow.request.ts +++ b/frontend/src/services/requests/workflow/get-workflow.request.ts @@ -1,10 +1,13 @@ -import { AxiosResponse } from 'axios' -import useSWR from 'swr' -import { useWorkspaces } from 'context/workspaces/workspaces.context' -import { dominoApiClient } from '../../clients/domino.client' -import { IGetWorkflowResponseInterface } from './workflow.interface' +import { type AxiosResponse } from "axios"; +import { useWorkspaces } from "context/workspaces/workspaces.context"; +import useSWR from "swr"; -const getWorkflowsUrl = (workspace: string, page: number, pageSize: number) => `/workspaces/${workspace}/workflows?page=${page}&page_size=${pageSize}` +import { dominoApiClient } from "../../clients/domino.client"; + +import { type IGetWorkflowResponseInterface } from "./workflow.interface"; + +const getWorkflowsUrl = (workspace: string, page: number, pageSize: number) => + `/workspaces/${workspace}/workflows?page=${page}&page_size=${pageSize}`; /** * Get workflows using GET /workflows @@ -14,29 +17,39 @@ const getWorkflowsUrl = (workspace: string, page: number, pageSize: number) => ` const getWorkflows: ( workspace: string, page: number, - pageSize: number -) => Promise> = (workspace, page, pageSize) => { - - return dominoApiClient.get(getWorkflowsUrl(workspace, page, pageSize)) -} + pageSize: number, +) => Promise> = async ( + workspace, + page, + pageSize, +) => { + return await dominoApiClient.get(getWorkflowsUrl(workspace, page, pageSize)); +}; /** * Get workflow * @returns workflow as swr response */ -export const useAuthenticatedGetWorkflows = (page: number = 0, pageSize: number = 5) => { - const { workspace } = useWorkspaces() +export const useAuthenticatedGetWorkflows = ( + page: number = 0, + pageSize: number = 5, +) => { + const { workspace } = useWorkspaces(); - if (!workspace) throw new Error('Impossible to fetch workflows without specifying a workspace') + if (!workspace) + throw new Error( + "Impossible to fetch workflows without specifying a workspace", + ); - const fetcher = () => getWorkflows(workspace.id, page, pageSize).then(data => data.data) + const fetcher = async () => + await getWorkflows(workspace.id, page, pageSize).then((data) => data.data); return useSWR( getWorkflowsUrl(workspace.id, page, pageSize), - () => fetcher(), + async () => await fetcher(), { revalidateOnFocus: false, - revalidateOnReconnect: false - } - ) -} + revalidateOnReconnect: false, + }, + ); +}; diff --git a/frontend/src/services/requests/workflow/index.ts b/frontend/src/services/requests/workflow/index.ts index 0cf38508..3195869d 100644 --- a/frontend/src/services/requests/workflow/index.ts +++ b/frontend/src/services/requests/workflow/index.ts @@ -1,6 +1,6 @@ -export * from './delete-workflow-id.request' -export * from './get-workflow-id.request' -export * from './get-workflow.request' -export * from './post-workflow-run-id.request' -export * from './post-workflow.request' -export * from './workflow.interface' +export * from "./delete-workflow-id.request"; +export * from "./get-workflow-id.request"; +export * from "./get-workflow.request"; +export * from "./post-workflow-run-id.request"; +export * from "./post-workflow.request"; +export * from "./workflow.interface"; diff --git a/frontend/src/services/requests/workflow/post-workflow-run-id.request.ts b/frontend/src/services/requests/workflow/post-workflow-run-id.request.ts index 12f46894..4e487382 100644 --- a/frontend/src/services/requests/workflow/post-workflow-run-id.request.ts +++ b/frontend/src/services/requests/workflow/post-workflow-run-id.request.ts @@ -1,14 +1,17 @@ // TODO move to /runs -import { AxiosResponse } from 'axios' -import { useWorkspaces } from 'context/workspaces/workspaces.context' -import { dominoApiClient } from '../../clients/domino.client' -import { IPostWorkflowRunIdResponseInterface } from './workflow.interface' +import { type AxiosResponse } from "axios"; +import { useWorkspaces } from "context/workspaces/workspaces.context"; + +import { dominoApiClient } from "../../clients/domino.client"; + +import { type IPostWorkflowRunIdResponseInterface } from "./workflow.interface"; interface IPostWorkflowRunIdParams { - id: string + id: string; } -const postWorkflowRunUrl = (workspaceId: string, id: string) => `/workspaces/${workspaceId}/workflows/${id}/runs` +const postWorkflowRunUrl = (workspaceId: string, id: string) => + `/workspaces/${workspaceId}/workflows/${id}/runs`; /** * Run workflow by id using /workflow/run/:id @@ -16,29 +19,31 @@ const postWorkflowRunUrl = (workspaceId: string, id: string) => `/workspaces/${w */ const postWorkflowRunId: ( workspaceId: string, - params: IPostWorkflowRunIdParams -) => Promise> = (workspaceId, params) => { - - return dominoApiClient.post(postWorkflowRunUrl(workspaceId, params.id), null) -} + params: IPostWorkflowRunIdParams, +) => Promise> = async ( + workspaceId, + params, +) => { + return await dominoApiClient.post( + postWorkflowRunUrl(workspaceId, params.id), + null, + ); +}; /** * Run workflow by id fetcher fn * @param params `{ id: string }` */ export const useAuthenticatedPostWorkflowRunId = () => { - const { workspace } = useWorkspaces() - - if (!workspace) throw new Error('Impossible to run workflows without specifying a workspace') - - const fetcher = (params: IPostWorkflowRunIdParams) => - postWorkflowRunId( - workspace.id as string, - params - ).then(data => data) - - return fetcher -} + const { workspace } = useWorkspaces(); + if (!workspace) + throw new Error( + "Impossible to run workflows without specifying a workspace", + ); + const fetcher = async (params: IPostWorkflowRunIdParams) => + await postWorkflowRunId(workspace.id, params).then((data) => data); + return fetcher; +}; diff --git a/frontend/src/services/requests/workflow/post-workflow.request.ts b/frontend/src/services/requests/workflow/post-workflow.request.ts index cb1831a0..effdc4da 100644 --- a/frontend/src/services/requests/workflow/post-workflow.request.ts +++ b/frontend/src/services/requests/workflow/post-workflow.request.ts @@ -1,10 +1,12 @@ -import { AxiosResponse } from 'axios' -import { dominoApiClient } from '../../clients/domino.client' -import { IPostWorkflowResponseInterface } from './workflow.interface' -import { CreateWorkflowRequest } from 'context/workflows/types' +import { type AxiosResponse } from "axios"; +import { type CreateWorkflowRequest } from "context/workflows/types"; + +import { dominoApiClient } from "../../clients/domino.client"; + +import { type IPostWorkflowResponseInterface } from "./workflow.interface"; export interface IPostWorkflowParams extends CreateWorkflowRequest { - workspace_id: string + workspace_id: string; } /** @@ -12,11 +14,15 @@ export interface IPostWorkflowParams extends CreateWorkflowRequest { * @returns ? */ const postWorkflow: ( - payload: IPostWorkflowParams -) => Promise> = (payload) => { - - return dominoApiClient.post(`/workspaces/${payload.workspace_id}/workflows`, payload) -} + payload: IPostWorkflowParams, +) => Promise> = async ( + payload, +) => { + return await dominoApiClient.post( + `/workspaces/${payload.workspace_id}/workflows`, + payload, + ); +}; /** * Create authenticated workflow @@ -24,10 +30,8 @@ const postWorkflow: ( * @returns crate workflow function */ export const useAuthenticatedPostWorkflow = () => { - const fetcher = (params: IPostWorkflowParams) => - postWorkflow( - params - ).then(data => data.data) + const fetcher = async (params: IPostWorkflowParams) => + await postWorkflow(params).then((data) => data.data); - return fetcher -} + return fetcher; +}; diff --git a/frontend/src/services/requests/workflow/workflow.interface.ts b/frontend/src/services/requests/workflow/workflow.interface.ts index d5da5355..15ab0ea2 100644 --- a/frontend/src/services/requests/workflow/workflow.interface.ts +++ b/frontend/src/services/requests/workflow/workflow.interface.ts @@ -1,12 +1,12 @@ export interface IWorkflowElement { - id: string - type?: string + id: string; + type?: string; data: { - name: string - handleOrientation: "horizontal" | "vertical" - style: any - } - position: { x: number, y: number } + name: string; + handleOrientation: "horizontal" | "vertical"; + style: any; + }; + position: { x: number; y: number }; } enum WorkflowStatus { @@ -16,93 +16,88 @@ enum WorkflowStatus { } export interface IWorkflow { - id: number - name: string - created_at: string - schema: IWorkflowSchema - ui_schema: IWorkDominoSchema - last_changed_at: string - last_changed_by: number // todo will change to username probably - created_by: number // todo will change to username probably - workspace_id: number - is_paused: boolean - is_active: boolean - status: WorkflowStatus - is_subdag: boolean - last_pickled: string - schedule_interval: string - max_active_tasks: number - max_active_runs: number - has_task_concurrency_limits: boolean - has_import_errors: boolean - next_dagrun: string - next_dagrun_data_interval_start: string - next_dagrun_data_interval_end: string + id: number; + name: string; + created_at: string; + schema: IWorkflowSchema; + ui_schema: IWorkDominoSchema; + last_changed_at: string; + last_changed_by: number; // todo will change to username probably + created_by: number; // todo will change to username probably + workspace_id: number; + is_paused: boolean; + is_active: boolean; + status: WorkflowStatus; + is_subdag: boolean; + last_pickled: string; + schedule_interval: string; + max_active_tasks: number; + max_active_runs: number; + has_task_concurrency_limits: boolean; + has_import_errors: boolean; + next_dagrun: string; + next_dagrun_data_interval_start: string; + next_dagrun_data_interval_end: string; } interface IPaginationMetadata { - page: number - last_page: number - records: number - total: number + page: number; + last_page: number; + records: number; + total: number; } - export interface IWorkflowSchema { - workflow_config: IWorkflowConfig - tasks: Record + workflow_config: IWorkflowConfig; + tasks: Record; } export interface IWorkDominoSchema { - nodes: Record - edges: any[] + nodes: Record; + edges: any[]; } export interface IWorkflowConfig { - name: string - start_date: string - end_date: string - schedule_interval: string - catchup: boolean - generate_report: string - description: string + name: string; + start_date: string; + end_date: string; + schedule_interval: string; + catchup: boolean; + generate_report: string; + description: string; } /** * Get Workflow response interface */ -export type IGetWorkflowResponseInterface = { - data?: IWorkflow[] - metadata?: IPaginationMetadata +export interface IGetWorkflowResponseInterface { + data?: IWorkflow[]; + metadata?: IPaginationMetadata; } /** * Get Workflow by id response interface */ -export type IGetWorkflowIdResponseInterface = IWorkflow +export type IGetWorkflowIdResponseInterface = IWorkflow; /** * Post Workflow response interface */ export interface IPostWorkflowResponseInterface { - id: number - name: string - created_at: string - schema: IWorkflowSchema + id: number; + name: string; + created_at: string; + schema: IWorkflowSchema; } /** * Delete Workflow by id response interface * @todo type properly */ -export interface IDeleteWorkflowIdResponseInterface { - [x: string]: any -} +export type IDeleteWorkflowIdResponseInterface = Record; /** * Post Workflow run by id response interface * @todo type properly */ -export interface IPostWorkflowRunIdResponseInterface { - [x: string]: any -} +export type IPostWorkflowRunIdResponseInterface = Record; diff --git a/frontend/src/services/requests/workspaces/accept-workspace-invite.request.ts b/frontend/src/services/requests/workspaces/accept-workspace-invite.request.ts index 5457e1c4..9cf887f7 100644 --- a/frontend/src/services/requests/workspaces/accept-workspace-invite.request.ts +++ b/frontend/src/services/requests/workspaces/accept-workspace-invite.request.ts @@ -1,37 +1,35 @@ // TODO move to /runs -import { AxiosResponse } from 'axios' -import { dominoApiClient } from '../../clients/domino.client' +import { type AxiosResponse } from "axios"; +import { dominoApiClient } from "../../clients/domino.client"; interface acceptWorkspaceInviteParams { - workspaceId: string + workspaceId: string; } -const acceptWorkspaceInviteUrl = (workspaceId: string) => `/workspaces/${workspaceId}/invites/accept` +const acceptWorkspaceInviteUrl = (workspaceId: string) => + `/workspaces/${workspaceId}/invites/accept`; /** * Run workflow by id using /workflow/run/:id * @returns workflow run result */ const acceptWorkspaceInvite: ( - params: acceptWorkspaceInviteParams -) => Promise = (params) => { - return dominoApiClient.post( - acceptWorkspaceInviteUrl(params.workspaceId), null - ) -} + params: acceptWorkspaceInviteParams, +) => Promise = async (params) => { + return await dominoApiClient.post( + acceptWorkspaceInviteUrl(params.workspaceId), + null, + ); +}; /** * Run workflow by id fetcher fn * @param params `{ id: string }` */ export const useAuthenticatedAcceptWorkspaceInvite = () => { + const fetcher = async (params: acceptWorkspaceInviteParams) => + await acceptWorkspaceInvite(params).then((data) => data); - const fetcher = (params: acceptWorkspaceInviteParams) => - acceptWorkspaceInvite(params).then(data => data) - - return fetcher -} - - - + return fetcher; +}; diff --git a/frontend/src/services/requests/workspaces/delete-user-workspace.request.ts b/frontend/src/services/requests/workspaces/delete-user-workspace.request.ts index 063ba82b..b3cee2c2 100644 --- a/frontend/src/services/requests/workspaces/delete-user-workspace.request.ts +++ b/frontend/src/services/requests/workspaces/delete-user-workspace.request.ts @@ -1,37 +1,35 @@ // TODO move to /runs -import { AxiosResponse } from 'axios' -import { dominoApiClient } from '../../clients/domino.client' +import { type AxiosResponse } from "axios"; +import { dominoApiClient } from "../../clients/domino.client"; interface removeUserWorkspaceParams { - workspaceId: string - userId: string + workspaceId: string; + userId: string; } -const removeUserWorkspaceUrl = (workspaceId: string, userId: string) => `/workspaces/${workspaceId}/users/${userId}` +const removeUserWorkspaceUrl = (workspaceId: string, userId: string) => + `/workspaces/${workspaceId}/users/${userId}`; /** * Run workflow by id using /workflow/run/:id * @returns workflow run result */ const removeUserWorkspace: ( - params: removeUserWorkspaceParams -) => Promise = (params) => { - return dominoApiClient.delete( - removeUserWorkspaceUrl(params.workspaceId, params.userId) - ) -} + params: removeUserWorkspaceParams, +) => Promise = async (params) => { + return await dominoApiClient.delete( + removeUserWorkspaceUrl(params.workspaceId, params.userId), + ); +}; /** * Run workflow by id fetcher fn * @param params `{ id: string }` */ export const useAuthenticatedRemoveUserWorkspace = () => { - const fetcher = (params: removeUserWorkspaceParams) => - removeUserWorkspace(params).then(data => data) - - return fetcher -} - - + const fetcher = async (params: removeUserWorkspaceParams) => + await removeUserWorkspace(params).then((data) => data); + return fetcher; +}; diff --git a/frontend/src/services/requests/workspaces/delete-workspace.request.ts b/frontend/src/services/requests/workspaces/delete-workspace.request.ts index d8e232ae..69f669e7 100644 --- a/frontend/src/services/requests/workspaces/delete-workspace.request.ts +++ b/frontend/src/services/requests/workspaces/delete-workspace.request.ts @@ -1,11 +1,12 @@ -import { AxiosResponse } from 'axios' -import { dominoApiClient } from '../../clients/domino.client' -import { useCallback } from 'react' +import { type AxiosResponse } from "axios"; +import { useCallback } from "react"; -interface IDeleteWorkspacesResponseInterface { } +import { dominoApiClient } from "../../clients/domino.client"; + +type IDeleteWorkspacesResponseInterface = unknown; export interface IDeleteWorkspacesParams { - id: string + id: string; } /** @@ -13,13 +14,21 @@ export interface IDeleteWorkspacesParams { * @returns ? */ const deleteWorkspace: ( - params: IDeleteWorkspacesParams -) => Promise> = (params) => { - return dominoApiClient.delete(`/workspaces/${params.id}`) -} + params: IDeleteWorkspacesParams, +) => Promise> = async ( + params, +) => { + return await dominoApiClient.delete(`/workspaces/${params.id}`); +}; export const useAuthenticatedDeleteWorkspaces = () => { - const fetcher = useCallback((params: IDeleteWorkspacesParams) => deleteWorkspace(params).then(data => { return data }), []) + const fetcher = useCallback( + async (params: IDeleteWorkspacesParams) => + await deleteWorkspace(params).then((data) => { + return data; + }), + [], + ); - return fetcher -} + return fetcher; +}; diff --git a/frontend/src/services/requests/workspaces/get-workspace-id.request.ts b/frontend/src/services/requests/workspaces/get-workspace-id.request.ts index c360eb6f..4e136e8d 100644 --- a/frontend/src/services/requests/workspaces/get-workspace-id.request.ts +++ b/frontend/src/services/requests/workspaces/get-workspace-id.request.ts @@ -1,10 +1,11 @@ -import { AxiosResponse } from 'axios' -import useSWR from 'swr' -import { dominoApiClient } from 'services/clients/domino.client' -import { IGetWorkspaceIdResponseInterface } from './workspaces.interface' +import { type AxiosResponse } from "axios"; +import { dominoApiClient } from "services/clients/domino.client"; +import useSWR from "swr"; + +import { type IGetWorkspaceIdResponseInterface } from "./workspaces.interface"; interface IGetWorkspaceIdParams { - id: string + id: string; } /** @@ -13,10 +14,12 @@ interface IGetWorkspaceIdParams { * @returns workspace */ const getWorkspaceId: ( - params: IGetWorkspaceIdParams -) => Promise> = (params) => { - return dominoApiClient.get(`/workspaces/${params.id}`) -} + params: IGetWorkspaceIdParams, +) => Promise> = async ( + params, +) => { + return await dominoApiClient.get(`/workspaces/${params.id}`); +}; /** * Authenticated fetcher function that gets workspace by id @@ -24,17 +27,18 @@ const getWorkspaceId: ( * @returns workspace fetcher fn */ export const useAuthenticatedGetWorkspaceIdFetcher = () => { - return (params: IGetWorkspaceIdParams) => getWorkspaceId(params).then(data => data.data) -} + return async (params: IGetWorkspaceIdParams) => + await getWorkspaceId(params).then((data) => data.data); +}; /** * Get workspace data * @returns workspace data as swr response */ export const useAuthenticatedGetWorkspace = (params: IGetWorkspaceIdParams) => { - const fetcher = useAuthenticatedGetWorkspaceIdFetcher() - return useSWR(`/workspaces/${params.id}`, () => fetcher(params), { + const fetcher = useAuthenticatedGetWorkspaceIdFetcher(); + return useSWR(`/workspaces/${params.id}`, async () => await fetcher(params), { revalidateOnFocus: false, - revalidateOnReconnect: false - }) -} + revalidateOnReconnect: false, + }); +}; diff --git a/frontend/src/services/requests/workspaces/get-workspace-members.request.ts b/frontend/src/services/requests/workspaces/get-workspace-members.request.ts index 007a91a5..58b483d9 100644 --- a/frontend/src/services/requests/workspaces/get-workspace-members.request.ts +++ b/frontend/src/services/requests/workspaces/get-workspace-members.request.ts @@ -1,14 +1,15 @@ -import { useCallback } from 'react' -import { AxiosResponse } from 'axios' -import useSWR from 'swr' -import { dominoApiClient } from 'services/clients/domino.client' -import { IGetWorkspaceUsersResponse } from './workspaces.interface' -import { useAuthentication } from 'context/authentication' +import { type AxiosResponse } from "axios"; +import { useAuthentication } from "context/authentication"; +import { useCallback } from "react"; +import { dominoApiClient } from "services/clients/domino.client"; +import useSWR from "swr"; + +import { type IGetWorkspaceUsersResponse } from "./workspaces.interface"; interface IGetWorkspaceMembers { - workspaceId: string - page: number - pageSize: number + workspaceId: string; + page: number; + pageSize: number; } /** @@ -16,33 +17,50 @@ interface IGetWorkspaceMembers { * @returns workspaces */ const getWorkspaceUsers: ( - workspaceId: string, - page: number, - pageSize: number -) => Promise> = (workspaceId, page, pageSize) => { - return dominoApiClient.get(`/workspaces/${workspaceId}/users?page=${page}&page_size=${pageSize}`) -} + workspaceId: string, + page: number, + pageSize: number, +) => Promise> = async ( + workspaceId, + page, + pageSize, +) => { + return await dominoApiClient.get( + `/workspaces/${workspaceId}/users?page=${page}&page_size=${pageSize}`, + ); +}; /** * Get workspaces * @returns workspaces as swr response */ -export const useAuthenticatedGetWorkspaceUsers = (params: IGetWorkspaceMembers) => { +export const useAuthenticatedGetWorkspaceUsers = ( + params: IGetWorkspaceMembers, +) => { + const fetcher = useCallback(async (params: IGetWorkspaceMembers) => { + return await getWorkspaceUsers( + params.workspaceId, + params.page, + params.pageSize, + ).then((data) => data.data); + }, []); - const fetcher = useCallback(async (params: IGetWorkspaceMembers) => { - return getWorkspaceUsers(params.workspaceId, params.page, params.pageSize).then(data => data.data) - }, []) + const auth = useAuthentication(); - const auth = useAuthentication() - - if (!params.page){ - params.page = 0 - } - if (!params.pageSize){ - params.pageSize = 10 - } - return useSWR((auth.isLogged && params.workspaceId) ? `/workspaces/${params.workspaceId}/users?page=${params.page}&page_size=${params.pageSize}` : null, () => fetcher(params), { - revalidateOnFocus: false, - revalidateOnReconnect: false - }) -} + if (!params.page) { + params.page = 0; + } + if (!params.pageSize) { + params.pageSize = 10; + } + return useSWR( + auth.isLogged && params.workspaceId + ? `/workspaces/${params.workspaceId}/users?page=${params.page}&page_size=${params.pageSize}` + : null, + async () => await fetcher(params), + { + revalidateOnFocus: false, + revalidateOnReconnect: false, + }, + ); +}; diff --git a/frontend/src/services/requests/workspaces/get-workspaces.request.ts b/frontend/src/services/requests/workspaces/get-workspaces.request.ts index 9d7e0cf5..0c111686 100644 --- a/frontend/src/services/requests/workspaces/get-workspaces.request.ts +++ b/frontend/src/services/requests/workspaces/get-workspaces.request.ts @@ -1,33 +1,38 @@ -import { useCallback } from 'react' -import { AxiosResponse } from 'axios' -import useSWR from 'swr' -import { dominoApiClient } from 'services/clients/domino.client' -import { IGetWorkspacesResponseInterface } from './workspaces.interface' -import { useAuthentication } from 'context/authentication' +import { type AxiosResponse } from "axios"; +import { useAuthentication } from "context/authentication"; +import { useCallback } from "react"; +import { dominoApiClient } from "services/clients/domino.client"; +import useSWR from "swr"; + +import { type IGetWorkspacesResponseInterface } from "./workspaces.interface"; /** * Get workspaces using GET /workspaces * @returns workspaces */ -const getWorkspaces: ( -) => Promise> = () => { - return dominoApiClient.get('/workspaces',) -} +const getWorkspaces: () => Promise< + AxiosResponse +> = async () => { + return await dominoApiClient.get("/workspaces"); +}; /** * Get workspaces * @returns workspaces as swr response */ export const useAuthenticatedGetWorkspaces = () => { - const fetcher = useCallback(async () => { - return getWorkspaces().then(data => data.data) - }, []) + return await getWorkspaces().then((data) => data.data); + }, []); - const auth = useAuthentication() + const auth = useAuthentication(); - return useSWR(auth.isLogged ? `/workspaces` : null, () => fetcher(), { - revalidateOnFocus: false, - revalidateOnReconnect: false - }) -} + return useSWR( + auth.isLogged ? `/workspaces` : null, + async () => await fetcher(), + { + revalidateOnFocus: false, + revalidateOnReconnect: false, + }, + ); +}; diff --git a/frontend/src/services/requests/workspaces/index.ts b/frontend/src/services/requests/workspaces/index.ts index 2a43b66e..265adafc 100644 --- a/frontend/src/services/requests/workspaces/index.ts +++ b/frontend/src/services/requests/workspaces/index.ts @@ -1,12 +1,12 @@ -export * from './get-workspace-id.request' -export * from './get-workspaces.request' -export * from './post-operators-repositories.request' -export * from './post-workspaces.request' -export * from './delete-workspace.request' -export * from './workspaces.interface' -export * from './patch-workspace.reques' -export * from './accept-workspace-invite.request' -export * from './reject-workspace-invite.request' -export * from './invite-workspace.request' -export * from './delete-user-workspace.request' -export * from './get-workspace-members.request' \ No newline at end of file +export * from "./get-workspace-id.request"; +export * from "./get-workspaces.request"; +export * from "./post-operators-repositories.request"; +export * from "./post-workspaces.request"; +export * from "./delete-workspace.request"; +export * from "./workspaces.interface"; +export * from "./patch-workspace.reques"; +export * from "./accept-workspace-invite.request"; +export * from "./reject-workspace-invite.request"; +export * from "./invite-workspace.request"; +export * from "./delete-user-workspace.request"; +export * from "./get-workspace-members.request"; diff --git a/frontend/src/services/requests/workspaces/invite-workspace.request.ts b/frontend/src/services/requests/workspaces/invite-workspace.request.ts index 316acb85..41f0acf0 100644 --- a/frontend/src/services/requests/workspaces/invite-workspace.request.ts +++ b/frontend/src/services/requests/workspaces/invite-workspace.request.ts @@ -1,42 +1,37 @@ // TODO move to /runs -import { AxiosResponse } from 'axios' -import { dominoApiClient } from '../../clients/domino.client' +import { type AxiosResponse } from "axios"; +import { dominoApiClient } from "../../clients/domino.client"; interface inviteWorkspaceParams { - workspaceId: string - userEmail: string - permission: string + workspaceId: string; + userEmail: string; + permission: string; } -const inviteWorkspaceUrl = (workspaceId: string) => `/workspaces/${workspaceId}/invites` +const inviteWorkspaceUrl = (workspaceId: string) => + `/workspaces/${workspaceId}/invites`; /** * Run workflow by id using /workflow/run/:id * @returns workflow run result */ const inviteWorkspace: ( - params: inviteWorkspaceParams -) => Promise = (params) => { - return dominoApiClient.post( - inviteWorkspaceUrl(params.workspaceId), { - user_email: params.userEmail, - permission: params.permission - } - ) -} + params: inviteWorkspaceParams, +) => Promise = async (params) => { + return await dominoApiClient.post(inviteWorkspaceUrl(params.workspaceId), { + user_email: params.userEmail, + permission: params.permission, + }); +}; /** * Run workflow by id fetcher fn * @param params `{ id: string }` */ export const useAuthenticatedWorkspaceInvite = () => { + const fetcher = async (params: inviteWorkspaceParams) => + await inviteWorkspace(params).then((data) => data); - const fetcher = (params: inviteWorkspaceParams) => - inviteWorkspace(params).then(data => data) - - return fetcher -} - - - + return fetcher; +}; diff --git a/frontend/src/services/requests/workspaces/patch-workspace.reques.ts b/frontend/src/services/requests/workspaces/patch-workspace.reques.ts index e3b9bcec..6329cfae 100644 --- a/frontend/src/services/requests/workspaces/patch-workspace.reques.ts +++ b/frontend/src/services/requests/workspaces/patch-workspace.reques.ts @@ -1,47 +1,46 @@ // TODO move to /runs -import { AxiosResponse } from 'axios' -import { useWorkspaces } from 'context/workspaces/workspaces.context' - - -import { dominoApiClient } from '../../clients/domino.client' +import { type AxiosResponse } from "axios"; +import { useWorkspaces } from "context/workspaces/workspaces.context"; +import { dominoApiClient } from "../../clients/domino.client"; interface patchWorkspaceParams { - workspaceId: string - payload: { - name?: string | null - github_access_token?: string | null - } + workspaceId: string; + payload: { + name?: string | null; + github_access_token?: string | null; + }; } -const patchWorkspaceUrl = (workspaceId: string) => `/workspaces/${workspaceId}` +const patchWorkspaceUrl = (workspaceId: string) => `/workspaces/${workspaceId}`; /** * Run workflow by id using /workflow/run/:id * @returns workflow run result */ const patchWorkspace: ( - params: patchWorkspaceParams -) => Promise = (params) => { - return dominoApiClient.patch( - patchWorkspaceUrl(params.workspaceId), params.payload - ) -} + params: patchWorkspaceParams, +) => Promise = async (params) => { + return await dominoApiClient.patch( + patchWorkspaceUrl(params.workspaceId), + params.payload, + ); +}; /** * Run workflow by id fetcher fn * @param params `{ id: string }` */ export const useAuthenticatedPatchWorkspace = () => { - const { workspace } = useWorkspaces() - - if (!workspace) throw new Error('Impossible to run workflows without specifying a workspace') - - const fetcher = (params: patchWorkspaceParams) => - patchWorkspace(params).then(data => data) - - return fetcher -} + const { workspace } = useWorkspaces(); + if (!workspace) + throw new Error( + "Impossible to run workflows without specifying a workspace", + ); + const fetcher = async (params: patchWorkspaceParams) => + await patchWorkspace(params).then((data) => data); + return fetcher; +}; diff --git a/frontend/src/services/requests/workspaces/post-operators-repositories.request.ts b/frontend/src/services/requests/workspaces/post-operators-repositories.request.ts index 42808471..7e704ca5 100644 --- a/frontend/src/services/requests/workspaces/post-operators-repositories.request.ts +++ b/frontend/src/services/requests/workspaces/post-operators-repositories.request.ts @@ -1,22 +1,23 @@ -import { AxiosResponse } from 'axios' -import { dominoApiClient } from 'services/clients/domino.client' +import { type AxiosResponse } from "axios"; +import { dominoApiClient } from "services/clients/domino.client"; + import { - IPostWorkspaceRepositoryParams, - IPostWorkspaceRepositoryPayload, - IPostWorkspaceRepositoryResponseInterface -} from './workspaces.interface' + type IPostWorkspaceRepositoryParams, + type IPostWorkspaceRepositoryPayload, + type IPostWorkspaceRepositoryResponseInterface, +} from "./workspaces.interface"; /** * Create workspacesidoperatorsrepositories using POST /workspacesidoperatorsrepositories * @returns ? */ const postOperatorsRepository: ( - params: IPostWorkspaceRepositoryParams -) => Promise> = ( - params + params: IPostWorkspaceRepositoryParams, +) => Promise> = async ( + params, ) => { - return dominoApiClient.post('/pieces-repositories', params.data) - } + return await dominoApiClient.post("/pieces-repositories", params.data); +}; /** * Create authenticated workspacesidoperatorsrepositories @@ -24,16 +25,16 @@ const postOperatorsRepository: ( * @returns crate workspacesidoperatorsrepositories function */ export const useAuthenticatedPostOperatorsRepository = (params: { - workspace: string + workspace: string; }) => { if (!params?.workspace) - throw new Error('Impossible to add repositories without a workspace!') + throw new Error("Impossible to add repositories without a workspace!"); - const fetcher = (payload: IPostWorkspaceRepositoryPayload) => - postOperatorsRepository({ + const fetcher = async (payload: IPostWorkspaceRepositoryPayload) => + await postOperatorsRepository({ id: params.workspace, - data: payload - }).then((data) => data.data) + data: payload, + }).then((data) => data.data); - return fetcher -} + return fetcher; +}; diff --git a/frontend/src/services/requests/workspaces/post-workspaces.request.ts b/frontend/src/services/requests/workspaces/post-workspaces.request.ts index 6f4add7f..e5b0eccc 100644 --- a/frontend/src/services/requests/workspaces/post-workspaces.request.ts +++ b/frontend/src/services/requests/workspaces/post-workspaces.request.ts @@ -1,13 +1,12 @@ -import { AxiosResponse } from 'axios' -import { dominoApiClient } from '../../clients/domino.client' -import { useCallback } from 'react' +import { type AxiosResponse } from "axios"; +import { useCallback } from "react"; -interface IPostWorkspacesResponseInterface { - [x: string]: any -} +import { dominoApiClient } from "../../clients/domino.client"; + +type IPostWorkspacesResponseInterface = Record; export interface IPostWorkspacesParams { - name: string + name: string; } /** @@ -15,10 +14,12 @@ export interface IPostWorkspacesParams { * @returns ? */ const postWorkspaces: ( - params: IPostWorkspacesParams -) => Promise> = (params) => { - return dominoApiClient.post(`/workspaces`, params) -} + params: IPostWorkspacesParams, +) => Promise> = async ( + params, +) => { + return await dominoApiClient.post(`/workspaces`, params); +}; /** * Create authenticated workspaces @@ -27,10 +28,12 @@ const postWorkspaces: ( */ export const useAuthenticatedPostWorkspaces = () => { const fetcher = useCallback( - (params: IPostWorkspacesParams) => postWorkspaces(params) - .then(data => { - return data.data - }), []) + async (params: IPostWorkspacesParams) => + await postWorkspaces(params).then((data) => { + return data.data; + }), + [], + ); - return fetcher -} + return fetcher; +}; diff --git a/frontend/src/services/requests/workspaces/reject-workspace-invite.request.ts b/frontend/src/services/requests/workspaces/reject-workspace-invite.request.ts index d85acd44..aaabfbba 100644 --- a/frontend/src/services/requests/workspaces/reject-workspace-invite.request.ts +++ b/frontend/src/services/requests/workspaces/reject-workspace-invite.request.ts @@ -1,37 +1,35 @@ // TODO move to /runs -import { AxiosResponse } from 'axios' -import { dominoApiClient } from '../../clients/domino.client' +import { type AxiosResponse } from "axios"; +import { dominoApiClient } from "../../clients/domino.client"; interface rejectWorkspaceInviteParams { - workspaceId: string + workspaceId: string; } -const rejectWorkspaceInviteUrl = (workspaceId: string) => `/workspaces/${workspaceId}/invites/reject` +const rejectWorkspaceInviteUrl = (workspaceId: string) => + `/workspaces/${workspaceId}/invites/reject`; /** * Run workflow by id using /workflow/run/:id * @returns workflow run result */ const rejectWorkspaceInvite: ( - params: rejectWorkspaceInviteParams -) => Promise = (params) => { - return dominoApiClient.post( - rejectWorkspaceInviteUrl(params.workspaceId), null - ) -} + params: rejectWorkspaceInviteParams, +) => Promise = async (params) => { + return await dominoApiClient.post( + rejectWorkspaceInviteUrl(params.workspaceId), + null, + ); +}; /** * Run workflow by id fetcher fn * @param params `{ id: string }` */ export const useAuthenticatedRejectWorkspaceInvite = () => { + const fetcher = async (params: rejectWorkspaceInviteParams) => + await rejectWorkspaceInvite(params).then((data) => data); - const fetcher = (params: rejectWorkspaceInviteParams) => - rejectWorkspaceInvite(params).then(data => data) - - return fetcher -} - - - + return fetcher; +}; diff --git a/frontend/src/services/requests/workspaces/workspaces.interface.ts b/frontend/src/services/requests/workspaces/workspaces.interface.ts index bec28320..8fb390db 100644 --- a/frontend/src/services/requests/workspaces/workspaces.interface.ts +++ b/frontend/src/services/requests/workspaces/workspaces.interface.ts @@ -1,4 +1,4 @@ -import { ERepositorySource } from "common/interfaces/repository-source.enum" +import { type ERepositorySource } from "common/interfaces/repository-source.enum"; // Workspace status enum with values (pending, accepted and rejected) export enum EWorkspaceStatus { @@ -8,24 +8,24 @@ export enum EWorkspaceStatus { } interface IPaginationMetadata { - page: number - records: number - total: number - last_page: number + page: number; + records: number; + total: number; + last_page: number; } export interface IWorkspaceSummary { - id: string - workspace_name: string - user_permission: string - status: EWorkspaceStatus - github_access_token_filled: boolean + id: string; + workspace_name: string; + user_permission: string; + status: EWorkspaceStatus; + github_access_token_filled: boolean; } export interface IWorkspaceDetails { - id: string - workspace_name: string - github_access_token_filled: string + id: string; + workspace_name: string; + github_access_token_filled: string; // users: { user_id: string, permission: string }[] // operators_repositories: { // repository_id: string @@ -34,30 +34,32 @@ export interface IWorkspaceDetails { // }[] } -export type IGetWorkspacesResponseInterface = IWorkspaceSummary[] -export type IGetWorkspaceIdResponseInterface = IWorkspaceSummary -export type IGetWorkspaceUsersResponse = { - data: [{ - user_id: number - user_email: string - user_permission: string, - status: EWorkspaceStatus - }], - metadata: IPaginationMetadata +export type IGetWorkspacesResponseInterface = IWorkspaceSummary[]; +export type IGetWorkspaceIdResponseInterface = IWorkspaceSummary; +export interface IGetWorkspaceUsersResponse { + data: [ + { + user_id: number; + user_email: string; + user_permission: string; + status: EWorkspaceStatus; + }, + ]; + metadata: IPaginationMetadata; } /** * @todo type properly */ -export type IPostWorkspaceRepositoryResponseInterface = Record +export type IPostWorkspaceRepositoryResponseInterface = Record; export interface IPostWorkspaceRepositoryPayload { - workspace_id: string - source: ERepositorySource | string - path: string - version: string + workspace_id: string; + source: ERepositorySource | string; + path: string; + version: string; } export interface IPostWorkspaceRepositoryParams { - id: string - data: IPostWorkspaceRepositoryPayload + id: string; + data: IPostWorkspaceRepositoryPayload; } diff --git a/frontend/src/utils/create-custom-context.function.ts b/frontend/src/utils/create-custom-context.function.ts index 9a623928..e7feab6f 100644 --- a/frontend/src/utils/create-custom-context.function.ts +++ b/frontend/src/utils/create-custom-context.function.ts @@ -1,30 +1,30 @@ -import { Context, createContext, useContext } from 'react' +import { type Context, createContext, useContext } from "react"; /** * Creates a context without having to deal with pointless default values and null checks * @param T context interface * @param displayName (optional) devtools display name * @returns the context and its custom hook in an array: `[Context, useCustomContext]` - * + * * @author rafasilveira */ export function createCustomContext( /** The name that you want to display on the devtools */ - displayName?: string + displayName?: string, ): [Context, () => T] { - const Context = createContext(null) + const Context = createContext(null); if (displayName) { - Context.displayName = displayName + Context.displayName = displayName; } function useCustomContext() { - const context = useContext(Context) + const context = useContext(Context); if (context === null) { throw new Error( - `This hook must we used within ${displayName ?? "it's"} provider` - ) + `This hook must we used within ${displayName ?? "it's"} provider`, + ); } else { - return context + return context; } } - return [Context, useCustomContext] + return [Context, useCustomContext]; } diff --git a/frontend/src/utils/fetch-from-object.ts b/frontend/src/utils/fetchFromObject.ts similarity index 60% rename from frontend/src/utils/fetch-from-object.ts rename to frontend/src/utils/fetchFromObject.ts index 71f9de9e..d2471434 100644 --- a/frontend/src/utils/fetch-from-object.ts +++ b/frontend/src/utils/fetchFromObject.ts @@ -1,12 +1,11 @@ export function fetchFromObject(obj: any, prop: string): any { - - if (typeof obj === 'undefined') { + if (typeof obj === "undefined") { return; } - var _index = prop.indexOf('.') + const _index = prop.indexOf("."); if (_index > -1) { - const newObj = obj[prop.substring(0, _index)] + const newObj = obj[prop.substring(0, _index)]; return fetchFromObject(newObj, prop.substr(_index + 1)); } diff --git a/frontend/src/utils/generateTaskName.ts b/frontend/src/utils/generateTaskName.ts index 01c155bb..b0d8881d 100644 --- a/frontend/src/utils/generateTaskName.ts +++ b/frontend/src/utils/generateTaskName.ts @@ -1,8 +1,8 @@ -import { getUuid } from "./getUuidSlice" +import { getUuid } from "./getUuidSlice"; -export function generateTaskName(pieceName:string,pieceId:string){ - const hashId = getUuid(pieceId).replaceAll('-', '') - const pieceNameTrunk = pieceName.slice(0,9) - const taskName = `${pieceNameTrunk}_${hashId}` - return taskName +export function generateTaskName(pieceName: string, pieceId: string) { + const hashId = getUuid(pieceId).replaceAll("-", ""); + const pieceNameTrunk = pieceName.slice(0, 9); + const taskName = `${pieceNameTrunk}_${hashId}`; + return taskName; } diff --git a/frontend/src/utils/getDefinition.ts b/frontend/src/utils/getDefinition.ts index b63feb36..fd57183f 100644 --- a/frontend/src/utils/getDefinition.ts +++ b/frontend/src/utils/getDefinition.ts @@ -1,13 +1,16 @@ -export function getDefinition(schema: InputSchemaProperty | SimpleInputSchemaProperty | 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] +export function getDefinition( + schema: InputSchemaProperty | SimpleInputSchemaProperty | 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 + return schema.items; } else { - return schema + return schema; } } diff --git a/frontend/src/utils/getFromUpstream.ts b/frontend/src/utils/getFromUpstream.ts index a2758935..91292d0a 100644 --- a/frontend/src/utils/getFromUpstream.ts +++ b/frontend/src/utils/getFromUpstream.ts @@ -1,53 +1,68 @@ -function isEnum(schema: SimpleInputSchemaProperty | InputSchemaProperty | Definition): boolean { - if("allOf" in schema || "enum" in schema){ - return true +function isEnum( + schema: SimpleInputSchemaProperty | InputSchemaProperty | Definition, +): boolean { + if ("allOf" in schema || "enum" in schema) { + return true; } - return false + return false; } -function getFromUpstream(itemSchema: SimpleInputSchemaProperty | InputSchemaProperty): boolean; -function getFromUpstream(itemSchema: InputSchemaProperty | EnumDefinition, definitions: Definitions, key:string): boolean; +function getFromUpstream( + itemSchema: SimpleInputSchemaProperty | InputSchemaProperty, +): boolean; +function getFromUpstream( + itemSchema: InputSchemaProperty | EnumDefinition, + definitions: Definitions, + key: string, +): boolean; -function getFromUpstream(itemSchema: SimpleInputSchemaProperty | InputSchemaProperty | EnumDefinition, definitions?: any, key?: string): boolean { +function getFromUpstream( + itemSchema: SimpleInputSchemaProperty | InputSchemaProperty | EnumDefinition, + definitions?: any, + key?: string, +): boolean { // Enum type cant be from upstream - if(isEnum(itemSchema)){ - return false + if (isEnum(itemSchema)) { + return false; } if (definitions && "items" in itemSchema && "$ref" in itemSchema.items) { - const name = itemSchema.items.$ref.split("/").pop() as string - const definition = (definitions as Definitions)[name] + const name = itemSchema.items.$ref.split("/").pop() as string; + const definition = (definitions as Definitions)[name]; // Enum type cant be from upstream - if(isEnum(definition)){ - return false - } else if(definition.type === "object") { - const schema = definition.properties[key as string] + if (isEnum(definition)) { + return false; + } else if (definition.type === "object") { + const schema = definition.properties[key as string]; - if("allOf" in schema || "enum" in schema){ - return false + if ("allOf" in schema || "enum" in schema) { + return false; } - switch ((schema)?.from_upstream) { + switch (schema?.from_upstream) { case "always": return true; case "allowed": case "never": default: - return false + return false; } } } - switch ((itemSchema as SimpleInputSchemaProperty | InputSchemaProperty)?.from_upstream) { + switch ( + (itemSchema as SimpleInputSchemaProperty | InputSchemaProperty) + ?.from_upstream + ) { case "always": return true; case "allowed": case "never": default: - return false + return false; } } -export { getFromUpstream } +export { getFromUpstream }; diff --git a/frontend/src/utils/getUuidSlice.ts b/frontend/src/utils/getUuidSlice.ts index 5024e13a..6218f759 100644 --- a/frontend/src/utils/getUuidSlice.ts +++ b/frontend/src/utils/getUuidSlice.ts @@ -1,13 +1,15 @@ -type WorkflowPieceID = `${number}_${string}-${string}-${string}-${string}-${string}` | string +type WorkflowPieceID = + | `${number}_${string}-${string}-${string}-${string}-${string}` + | string; -export function getUuidSlice(workflowPieceID: WorkflowPieceID){ - return workflowPieceID.split("_")[1].split("-")[0] +export function getUuidSlice(workflowPieceID: WorkflowPieceID) { + return workflowPieceID.split("_")[1].split("-")[0]; } -export function getUuid(workflowPieceID: WorkflowPieceID){ - return workflowPieceID.split("_")[1] +export function getUuid(workflowPieceID: WorkflowPieceID) { + return workflowPieceID.split("_")[1]; } -export function getIdSlice(workflowPieceID: WorkflowPieceID){ - return parseInt(workflowPieceID.split("_")[0]) +export function getIdSlice(workflowPieceID: WorkflowPieceID) { + return parseInt(workflowPieceID.split("_")[0]); } diff --git a/frontend/src/utils/index.ts b/frontend/src/utils/index.ts index 77c403ca..626dc245 100644 --- a/frontend/src/utils/index.ts +++ b/frontend/src/utils/index.ts @@ -1,8 +1,8 @@ -export { extractDefaultValues, extractDefaultInputValues } from './jsonSchema' -export { createCustomContext } from './create-custom-context.function' -export { fetchFromObject } from "./fetch-from-object" -export { yupResolver } from "./validationResolver" -export { getIdSlice, getUuidSlice, getUuid } from "./getUuidSlice" -export { generateTaskName } from "./generateTaskName" -export { getDefinition } from "./getDefinition" -export { getFromUpstream } from "./getFromUpstream" +export { extractDefaultValues, extractDefaultInputValues } from "./jsonSchema"; +export { createCustomContext } from "./create-custom-context.function"; +export { fetchFromObject } from "./fetchFromObject"; +export { yupResolver } from "./validationResolver"; +export { getIdSlice, getUuidSlice, getUuid } from "./getUuidSlice"; +export { generateTaskName } from "./generateTaskName"; +export { getDefinition } from "./getDefinition"; +export { getFromUpstream } from "./getFromUpstream"; diff --git a/frontend/src/utils/jsonSchema.ts b/frontend/src/utils/jsonSchema.ts index a4d5ff8f..c584bf69 100644 --- a/frontend/src/utils/jsonSchema.ts +++ b/frontend/src/utils/jsonSchema.ts @@ -1,98 +1,104 @@ // Extract default values from Schema -import { IWorkflowPieceData } from "context/workflows/types"; +import { type IWorkflowPieceData } from "context/workflows/types"; + import { getFromUpstream } from "./getFromUpstream"; export const extractDefaultInputValues = (pieceSchema: PieceSchema) => { - const schema = pieceSchema.input_schema.properties - const definitions = pieceSchema.input_schema.definitions - const defaultData = extractDefaultValues(pieceSchema.input_schema) + const schema = pieceSchema.input_schema.properties; + const definitions = pieceSchema.input_schema.definitions; + const defaultData = extractDefaultValues(pieceSchema.input_schema); - const defaultInputs: IWorkflowPieceData["inputs"] = {} + const defaultInputs: IWorkflowPieceData["inputs"] = {}; for (const key in defaultData) { - const fromUpstream = getFromUpstream(schema[key]) + const fromUpstream = getFromUpstream(schema[key]); - var defaultValues = defaultData[key] + let defaultValues = defaultData[key]; if (Array.isArray(defaultData[key])) { - const auxDefaultValues = [] + const auxDefaultValues = []; for (const element of defaultData[key]) { - let newValue: any = {} - if (typeof element === 'object') { + let newValue: any = {}; + if (typeof element === "object") { newValue = { fromUpstream: {}, upstreamId: {}, upstreamArgument: {}, upstreamValue: {}, - value: {} - } + value: {}, + }; for (const [_key, _value] of Object.entries(element)) { - const fromUpstream = getFromUpstream(schema[key],definitions,_key) + const fromUpstream = getFromUpstream( + schema[key], + definitions, + _key, + ); newValue.fromUpstream = { ...newValue.fromUpstream, - [_key]: fromUpstream - } + [_key]: fromUpstream, + }; newValue.upstreamId = { ...newValue.upstreamId, - [_key]: "" - } + [_key]: "", + }; newValue.upstreamArgument = { ...newValue.upstreamArgument, - [_key]: "" - } + [_key]: "", + }; newValue.upstreamValue = { ...newValue.upstreamValue, - [_key]: "" - } + [_key]: "", + }; newValue.value = { ...newValue.value, - [_key]: _value - } + [_key]: _value, + }; } - auxDefaultValues.push(newValue) + auxDefaultValues.push(newValue); } else { newValue = { - fromUpstream: fromUpstream, + fromUpstream, upstreamId: "", upstreamArgument: "", upstreamValue: "", - value: element - } - auxDefaultValues.push(newValue) + value: element, + }; + auxDefaultValues.push(newValue); } } - defaultValues = auxDefaultValues + defaultValues = auxDefaultValues; } defaultInputs[key] = { fromUpstream, upstreamId: "", upstreamArgument: "", upstreamValue: "", - value: ( - defaultValues === null || defaultValues === undefined - ) ? null : defaultValues - } + value: defaultValues ?? null, + }; } - return defaultInputs -} + return defaultInputs; +}; -export const extractDefaultValues = (schema: InputSchema, output: any | null = null) => { - output = output === null ? {} : output +export const extractDefaultValues = ( + schema: InputSchema, + output: any | null = null, +) => { + output = output === null ? {} : output; if (schema) { - const properties = schema['properties'] + const properties = schema.properties; for (const [key, value] of Object.entries(properties)) { - if(value?.from_upstream === "always"){ - output[key] = "" + if (value?.from_upstream === "always") { + output[key] = ""; } - if ('default' in value) { - output[key] = value['default'] - } else if ('properties' in value) { - output[key] = extractDefaultValues(value as any, output[key]) + if ("default" in value) { + output[key] = value.default; + } else if ("properties" in value) { + output[key] = extractDefaultValues(value as any, output[key]); } } } - return output -} + return output; +}; diff --git a/frontend/src/utils/validationResolver.ts b/frontend/src/utils/validationResolver.ts index 20b2ae67..4c7d4cbb 100644 --- a/frontend/src/utils/validationResolver.ts +++ b/frontend/src/utils/validationResolver.ts @@ -1,9 +1,10 @@ -import { FieldErrors, FieldValues } from 'react-hook-form'; -import { ObjectSchema, ValidationError } from 'yup'; +import { type FieldErrors, type FieldValues } from "react-hook-form"; +import { type ObjectSchema, ValidationError } from "yup"; -const isNullOrUndefined = (value: unknown): value is null | undefined => value == null +const isNullOrUndefined = (value: unknown): value is null | undefined => + value == null; -const isObjectType = (value: unknown) => typeof value === 'object'; +const isObjectType = (value: unknown) => typeof value === "object"; const isDateObject = (value: unknown): value is Date => value instanceof Date; @@ -18,18 +19,14 @@ function compact(value: TValue[]) { } function stringToPath(input: string): string[] { - return compact(input.replace(/["|']|\]/g, '').split(/\.|\[/)); + return compact(input.replace(/["|']|\]/g, "").split(/\.|\[/)); } function isKey(value: string) { return /^\w*$/.test(value); } -function set( - object: FieldValues, - path: string, - value?: unknown, -) { +function set(object: FieldValues, path: string, value?: unknown) { let index = -1; const tempPath = isKey(path) ? [path] : stringToPath(path); const length = tempPath.length; @@ -45,8 +42,8 @@ function set( isObject(objValue) || Array.isArray(objValue) ? objValue : !isNaN(+tempPath[index + 1]) - ? [] - : {}; + ? [] + : {}; } object[key] = newValue; object = object[key]; @@ -57,54 +54,47 @@ function set( const toNestError = ( errors: FieldErrors, ): FieldErrors => { - const fieldErrors = {} as FieldErrors; + const fieldErrors: FieldErrors = {}; for (const path in errors) { - set( - fieldErrors, - path, - Object.assign(errors[path] || {}), - ); + set(fieldErrors, path, Object.assign(errors[path] ?? {})); } return fieldErrors; }; -export const yupResolver = ( - validationSchema: ObjectSchema> -) => async (data: any) => { - try { - const values = await validationSchema.validate(data, { - abortEarly: false, - }); - - return { - values, - errors: {}, - }; - } catch (e) { - if (e instanceof ValidationError) { - const errors = e.inner.reduce( - (allErrors, currentError) => { +export const yupResolver = + (validationSchema: ObjectSchema>) => + async (data: any) => { + try { + const values = await validationSchema.validate(data, { + abortEarly: false, + }); + + return { + values, + errors: {}, + }; + } catch (e) { + if (e instanceof ValidationError) { + const errors = e.inner.reduce((allErrors, currentError) => { const path = (currentError.path as string) ?.replaceAll("[", ".") - .replaceAll("]", "") + .replaceAll("]", ""); return { ...allErrors, [path]: { - type: currentError.type ?? 'validation', + type: currentError.type ?? "validation", message: currentError.message, }, - } - }, - {} - ) + }; + }, {}); - return { - values: {}, - errors: toNestError(errors), - }; - } + return { + values: {}, + errors: toNestError(errors), + }; + } - throw new Error('Error trying to validate form schema'); - } -} + throw new Error("Error trying to validate form schema"); + } + }; diff --git a/frontend/tsconfig.json b/frontend/tsconfig.json index 6e766843..aaebe058 100644 --- a/frontend/tsconfig.json +++ b/frontend/tsconfig.json @@ -1,6 +1,6 @@ { "compilerOptions": { - "target": "esnext", + "target": "es5", "lib": [ "dom", "dom.iterable", @@ -23,5 +23,8 @@ }, "include": [ "src" + ], + "exclude": [ + "node_modules" ] -} \ No newline at end of file +} diff --git a/frontend/yarn.lock b/frontend/yarn.lock index 3c0bf93b..3f2c1236 100644 --- a/frontend/yarn.lock +++ b/frontend/yarn.lock @@ -2,12 +2,22 @@ # yarn lockfile v1 -"@ampproject/remapping@^2.1.0": - version "2.2.0" - resolved "https://registry.yarnpkg.com/@ampproject/remapping/-/remapping-2.2.0.tgz#56c133824780de3174aed5ab6834f3026790154d" - integrity sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w== +"@aashutoshrathi/word-wrap@^1.2.3": + version "1.2.6" + resolved "https://registry.yarnpkg.com/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz#bd9154aec9983f77b3a034ecaa015c2e4201f6cf" + integrity sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA== + +"@alloc/quick-lru@^5.2.0": + version "5.2.0" + resolved "https://registry.yarnpkg.com/@alloc/quick-lru/-/quick-lru-5.2.0.tgz#7bf68b20c0a350f936915fcae06f58e32007ce30" + integrity sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw== + +"@ampproject/remapping@^2.2.0": + version "2.2.1" + resolved "https://registry.yarnpkg.com/@ampproject/remapping/-/remapping-2.2.1.tgz#99e8e11851128b8702cd57c33684f1d0f260b630" + integrity sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg== dependencies: - "@jridgewell/gen-mapping" "^0.1.0" + "@jridgewell/gen-mapping" "^0.3.0" "@jridgewell/trace-mapping" "^0.3.9" "@apideck/better-ajv-errors@^0.3.1": @@ -19,299 +29,279 @@ jsonpointer "^5.0.0" leven "^3.1.0" -"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.10.4", "@babel/code-frame@^7.12.13", "@babel/code-frame@^7.16.0", "@babel/code-frame@^7.18.6", "@babel/code-frame@^7.8.3": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.18.6.tgz#3b25d38c89600baa2dcc219edfa88a74eb2c427a" - integrity sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q== +"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.10.4", "@babel/code-frame@^7.12.13", "@babel/code-frame@^7.16.0", "@babel/code-frame@^7.22.10", "@babel/code-frame@^7.22.5", "@babel/code-frame@^7.8.3": + version "7.22.13" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.22.13.tgz#e3c1c099402598483b7a8c46a721d1038803755e" + integrity sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w== dependencies: - "@babel/highlight" "^7.18.6" + "@babel/highlight" "^7.22.13" + chalk "^2.4.2" -"@babel/compat-data@^7.17.7", "@babel/compat-data@^7.20.0", "@babel/compat-data@^7.20.1": - version "7.20.5" - resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.20.5.tgz#86f172690b093373a933223b4745deeb6049e733" - integrity sha512-KZXo2t10+/jxmkhNXc7pZTqRvSOIvVv/+lJwHS+B2rErwOyjuVRh60yVpb7liQ1U5t7lLJ1bz+t8tSypUZdm0g== +"@babel/compat-data@^7.22.6", "@babel/compat-data@^7.22.9": + version "7.22.9" + resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.22.9.tgz#71cdb00a1ce3a329ce4cbec3a44f9fef35669730" + integrity sha512-5UamI7xkUcJ3i9qVDS+KFDEK8/7oJ55/sJMB1Ge7IEapr7KfdfV/HErR+koZwOfd+SgtFKOKRhRakdg++DcJpQ== "@babel/core@^7.1.0", "@babel/core@^7.11.1", "@babel/core@^7.12.3", "@babel/core@^7.16.0", "@babel/core@^7.20.5", "@babel/core@^7.7.2", "@babel/core@^7.8.0": - version "7.20.5" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.20.5.tgz#45e2114dc6cd4ab167f81daf7820e8fa1250d113" - integrity sha512-UdOWmk4pNWTm/4DlPUl/Pt4Gz4rcEMb7CY0Y3eJl5Yz1vI8ZJGmHWaVE55LoxRjdpx0z259GE9U5STA9atUinQ== - dependencies: - "@ampproject/remapping" "^2.1.0" - "@babel/code-frame" "^7.18.6" - "@babel/generator" "^7.20.5" - "@babel/helper-compilation-targets" "^7.20.0" - "@babel/helper-module-transforms" "^7.20.2" - "@babel/helpers" "^7.20.5" - "@babel/parser" "^7.20.5" - "@babel/template" "^7.18.10" - "@babel/traverse" "^7.20.5" - "@babel/types" "^7.20.5" + version "7.22.11" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.22.11.tgz#8033acaa2aa24c3f814edaaa057f3ce0ba559c24" + integrity sha512-lh7RJrtPdhibbxndr6/xx0w8+CVlY5FJZiaSz908Fpy+G0xkBFTvwLcKJFF4PJxVfGhVWNebikpWGnOoC71juQ== + dependencies: + "@ampproject/remapping" "^2.2.0" + "@babel/code-frame" "^7.22.10" + "@babel/generator" "^7.22.10" + "@babel/helper-compilation-targets" "^7.22.10" + "@babel/helper-module-transforms" "^7.22.9" + "@babel/helpers" "^7.22.11" + "@babel/parser" "^7.22.11" + "@babel/template" "^7.22.5" + "@babel/traverse" "^7.22.11" + "@babel/types" "^7.22.11" convert-source-map "^1.7.0" debug "^4.1.0" gensync "^1.0.0-beta.2" - json5 "^2.2.1" - semver "^6.3.0" + json5 "^2.2.3" + semver "^6.3.1" "@babel/eslint-parser@^7.16.3": - version "7.19.1" - resolved "https://registry.yarnpkg.com/@babel/eslint-parser/-/eslint-parser-7.19.1.tgz#4f68f6b0825489e00a24b41b6a1ae35414ecd2f4" - integrity sha512-AqNf2QWt1rtu2/1rLswy6CDP7H9Oh3mMhk177Y67Rg8d7RD9WfOLLv8CGn6tisFvS2htm86yIe1yLF6I1UDaGQ== + version "7.22.11" + resolved "https://registry.yarnpkg.com/@babel/eslint-parser/-/eslint-parser-7.22.11.tgz#cceb8c7989c241a16dd14e12a6cd725618f3f58b" + integrity sha512-YjOYZ3j7TjV8OhLW6NCtyg8G04uStATEUe5eiLuCZaXz2VSDQ3dsAtm2D+TuQyAqNMUK2WacGo0/uma9Pein1w== dependencies: "@nicolo-ribaudo/eslint-scope-5-internals" "5.1.1-v1" eslint-visitor-keys "^2.1.0" - semver "^6.3.0" + semver "^6.3.1" -"@babel/generator@^7.20.5", "@babel/generator@^7.7.2": - version "7.20.5" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.20.5.tgz#cb25abee3178adf58d6814b68517c62bdbfdda95" - integrity sha512-jl7JY2Ykn9S0yj4DQP82sYvPU+T3g0HFcWTqDLqiuA9tGRNIj9VfbtXGAYTTkyNEnQk1jkMGOdYka8aG/lulCA== +"@babel/generator@^7.22.10", "@babel/generator@^7.7.2": + version "7.22.10" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.22.10.tgz#c92254361f398e160645ac58831069707382b722" + integrity sha512-79KIf7YiWjjdZ81JnLujDRApWtl7BxTqWD88+FFdQEIOG8LJ0etDOM7CXuIgGJa55sGOwZVwuEsaLEm0PJ5/+A== dependencies: - "@babel/types" "^7.20.5" + "@babel/types" "^7.22.10" "@jridgewell/gen-mapping" "^0.3.2" + "@jridgewell/trace-mapping" "^0.3.17" jsesc "^2.5.1" -"@babel/helper-annotate-as-pure@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.18.6.tgz#eaa49f6f80d5a33f9a5dd2276e6d6e451be0a6bb" - integrity sha512-duORpUiYrEpzKIop6iNbjnwKLAKnJ47csTyRACyEmWj0QdUrm5aqNJGHSSEQSUAvNW0ojX0dOmK9dZduvkfeXA== - dependencies: - "@babel/types" "^7.18.6" - -"@babel/helper-builder-binary-assignment-operator-visitor@^7.18.6": - version "7.18.9" - resolved "https://registry.yarnpkg.com/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.18.9.tgz#acd4edfd7a566d1d51ea975dff38fd52906981bb" - integrity sha512-yFQ0YCHoIqarl8BCRwBL8ulYUaZpz3bNsA7oFepAzee+8/+ImtADXNOmO5vJvsPff3qi+hvpkY/NYBTrBQgdNw== - dependencies: - "@babel/helper-explode-assignable-expression" "^7.18.6" - "@babel/types" "^7.18.9" - -"@babel/helper-compilation-targets@^7.17.7", "@babel/helper-compilation-targets@^7.18.9", "@babel/helper-compilation-targets@^7.20.0": - version "7.20.0" - resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.20.0.tgz#6bf5374d424e1b3922822f1d9bdaa43b1a139d0a" - integrity sha512-0jp//vDGp9e8hZzBc6N/KwA5ZK3Wsm/pfm4CrY7vzegkVxc65SgSn6wYOnwHe9Js9HRQ1YTCKLGPzDtaS3RoLQ== - dependencies: - "@babel/compat-data" "^7.20.0" - "@babel/helper-validator-option" "^7.18.6" - browserslist "^4.21.3" - semver "^6.3.0" - -"@babel/helper-create-class-features-plugin@^7.18.6", "@babel/helper-create-class-features-plugin@^7.20.2", "@babel/helper-create-class-features-plugin@^7.20.5": - version "7.20.5" - resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.20.5.tgz#327154eedfb12e977baa4ecc72e5806720a85a06" - integrity sha512-3RCdA/EmEaikrhayahwToF0fpweU/8o2p8vhc1c/1kftHOdTKuC65kik/TLc+qfbS8JKw4qqJbne4ovICDhmww== - dependencies: - "@babel/helper-annotate-as-pure" "^7.18.6" - "@babel/helper-environment-visitor" "^7.18.9" - "@babel/helper-function-name" "^7.19.0" - "@babel/helper-member-expression-to-functions" "^7.18.9" - "@babel/helper-optimise-call-expression" "^7.18.6" - "@babel/helper-replace-supers" "^7.19.1" - "@babel/helper-split-export-declaration" "^7.18.6" - -"@babel/helper-create-regexp-features-plugin@^7.18.6", "@babel/helper-create-regexp-features-plugin@^7.20.5": - version "7.20.5" - resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.20.5.tgz#5ea79b59962a09ec2acf20a963a01ab4d076ccca" - integrity sha512-m68B1lkg3XDGX5yCvGO0kPx3v9WIYLnzjKfPcQiwntEQa5ZeRkPmo2X/ISJc8qxWGfwUr+kvZAeEzAwLec2r2w== - dependencies: - "@babel/helper-annotate-as-pure" "^7.18.6" - regexpu-core "^5.2.1" - -"@babel/helper-define-polyfill-provider@^0.3.3": - version "0.3.3" - resolved "https://registry.yarnpkg.com/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.3.3.tgz#8612e55be5d51f0cd1f36b4a5a83924e89884b7a" - integrity sha512-z5aQKU4IzbqCC1XH0nAqfsFLMVSo22SBKUc0BxGrLkolTdPTructy0ToNnlO2zA4j9Q/7pjMZf0DSY+DSTYzww== - dependencies: - "@babel/helper-compilation-targets" "^7.17.7" - "@babel/helper-plugin-utils" "^7.16.7" +"@babel/helper-annotate-as-pure@^7.18.6", "@babel/helper-annotate-as-pure@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.22.5.tgz#e7f06737b197d580a01edf75d97e2c8be99d3882" + integrity sha512-LvBTxu8bQSQkcyKOU+a1btnNFQ1dMAd0R6PyW3arXes06F6QLWLIrd681bxRPIXlrMGR3XYnW9JyML7dP3qgxg== + dependencies: + "@babel/types" "^7.22.5" + +"@babel/helper-builder-binary-assignment-operator-visitor@^7.22.5": + version "7.22.10" + resolved "https://registry.yarnpkg.com/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.22.10.tgz#573e735937e99ea75ea30788b57eb52fab7468c9" + integrity sha512-Av0qubwDQxC56DoUReVDeLfMEjYYSN1nZrTUrWkXd7hpU73ymRANkbuDm3yni9npkn+RXy9nNbEJZEzXr7xrfQ== + dependencies: + "@babel/types" "^7.22.10" + +"@babel/helper-compilation-targets@^7.22.10", "@babel/helper-compilation-targets@^7.22.5", "@babel/helper-compilation-targets@^7.22.6": + version "7.22.10" + resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.10.tgz#01d648bbc25dd88f513d862ee0df27b7d4e67024" + integrity sha512-JMSwHD4J7SLod0idLq5PKgI+6g/hLD/iuWBq08ZX49xE14VpVEojJ5rHWptpirV2j020MvypRLAXAO50igCJ5Q== + dependencies: + "@babel/compat-data" "^7.22.9" + "@babel/helper-validator-option" "^7.22.5" + browserslist "^4.21.9" + lru-cache "^5.1.1" + semver "^6.3.1" + +"@babel/helper-create-class-features-plugin@^7.18.6", "@babel/helper-create-class-features-plugin@^7.21.0", "@babel/helper-create-class-features-plugin@^7.22.10", "@babel/helper-create-class-features-plugin@^7.22.11", "@babel/helper-create-class-features-plugin@^7.22.5": + version "7.22.11" + resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.22.11.tgz#4078686740459eeb4af3494a273ac09148dfb213" + integrity sha512-y1grdYL4WzmUDBRGK0pDbIoFd7UZKoDurDzWEoNMYoj1EL+foGRQNyPWDcC+YyegN5y1DUsFFmzjGijB3nSVAQ== + dependencies: + "@babel/helper-annotate-as-pure" "^7.22.5" + "@babel/helper-environment-visitor" "^7.22.5" + "@babel/helper-function-name" "^7.22.5" + "@babel/helper-member-expression-to-functions" "^7.22.5" + "@babel/helper-optimise-call-expression" "^7.22.5" + "@babel/helper-replace-supers" "^7.22.9" + "@babel/helper-skip-transparent-expression-wrappers" "^7.22.5" + "@babel/helper-split-export-declaration" "^7.22.6" + semver "^6.3.1" + +"@babel/helper-create-regexp-features-plugin@^7.18.6", "@babel/helper-create-regexp-features-plugin@^7.22.5": + version "7.22.9" + resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.22.9.tgz#9d8e61a8d9366fe66198f57c40565663de0825f6" + integrity sha512-+svjVa/tFwsNSG4NEy1h85+HQ5imbT92Q5/bgtS7P0GTQlP8WuFdqsiABmQouhiFGyV66oGxZFpeYHza1rNsKw== + dependencies: + "@babel/helper-annotate-as-pure" "^7.22.5" + regexpu-core "^5.3.1" + semver "^6.3.1" + +"@babel/helper-define-polyfill-provider@^0.4.2": + version "0.4.2" + resolved "https://registry.yarnpkg.com/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.4.2.tgz#82c825cadeeeee7aad237618ebbe8fa1710015d7" + integrity sha512-k0qnnOqHn5dK9pZpfD5XXZ9SojAITdCKRn2Lp6rnDGzIbaP0rHyMPk/4wsSxVBVz4RfN0q6VpXWP2pDGIoQ7hw== + dependencies: + "@babel/helper-compilation-targets" "^7.22.6" + "@babel/helper-plugin-utils" "^7.22.5" debug "^4.1.1" lodash.debounce "^4.0.8" resolve "^1.14.2" - semver "^6.1.2" -"@babel/helper-environment-visitor@^7.18.9": - version "7.18.9" - resolved "https://registry.yarnpkg.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz#0c0cee9b35d2ca190478756865bb3528422f51be" - integrity sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg== +"@babel/helper-environment-visitor@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.5.tgz#f06dd41b7c1f44e1f8da6c4055b41ab3a09a7e98" + integrity sha512-XGmhECfVA/5sAt+H+xpSg0mfrHq6FzNr9Oxh7PSEBBRUb/mL7Kz3NICXb194rCqAEdxkhPT1a88teizAFyvk8Q== -"@babel/helper-explode-assignable-expression@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.18.6.tgz#41f8228ef0a6f1a036b8dfdfec7ce94f9a6bc096" - integrity sha512-eyAYAsQmB80jNfg4baAtLeWAQHfHFiR483rzFK+BhETlGZaQC9bsfrugfXDCbRHLQbIA7U5NxhhOxN7p/dWIcg== +"@babel/helper-function-name@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.22.5.tgz#ede300828905bb15e582c037162f99d5183af1be" + integrity sha512-wtHSq6jMRE3uF2otvfuD3DIvVhOsSNshQl0Qrd7qC9oQJzHvOL4qQXlQn2916+CXGywIjpGuIkoyZRRxHPiNQQ== dependencies: - "@babel/types" "^7.18.6" + "@babel/template" "^7.22.5" + "@babel/types" "^7.22.5" -"@babel/helper-function-name@^7.18.9", "@babel/helper-function-name@^7.19.0": - version "7.19.0" - resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.19.0.tgz#941574ed5390682e872e52d3f38ce9d1bef4648c" - integrity sha512-WAwHBINyrpqywkUH0nTnNgI5ina5TFn85HKS0pbPDfxFfhyR/aNQEn4hGi1P1JyT//I0t4OgXUlofzWILRvS5w== +"@babel/helper-hoist-variables@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz#c01a007dac05c085914e8fb652b339db50d823bb" + integrity sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw== dependencies: - "@babel/template" "^7.18.10" - "@babel/types" "^7.19.0" + "@babel/types" "^7.22.5" -"@babel/helper-hoist-variables@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz#d4d2c8fb4baeaa5c68b99cc8245c56554f926678" - integrity sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q== +"@babel/helper-member-expression-to-functions@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.22.5.tgz#0a7c56117cad3372fbf8d2fb4bf8f8d64a1e76b2" + integrity sha512-aBiH1NKMG0H2cGZqspNvsaBe6wNGjbJjuLy29aU+eDZjSbbN53BaxlpB02xm9v34pLTZ1nIQPFYn2qMZoa5BQQ== dependencies: - "@babel/types" "^7.18.6" + "@babel/types" "^7.22.5" -"@babel/helper-member-expression-to-functions@^7.18.9": - version "7.18.9" - resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.18.9.tgz#1531661e8375af843ad37ac692c132841e2fd815" - integrity sha512-RxifAh2ZoVU67PyKIO4AMi1wTenGfMR/O/ae0CCRqwgBAt5v7xjdtRw7UoSbsreKrQn5t7r89eruK/9JjYHuDg== +"@babel/helper-module-imports@^7.10.4", "@babel/helper-module-imports@^7.16.7", "@babel/helper-module-imports@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.22.5.tgz#1a8f4c9f4027d23f520bd76b364d44434a72660c" + integrity sha512-8Dl6+HD/cKifutF5qGd/8ZJi84QeAKh+CEe1sBzz8UayBBGg1dAIJrdHOcOM5b2MpzWL2yuotJTtGjETq0qjXg== dependencies: - "@babel/types" "^7.18.9" + "@babel/types" "^7.22.5" -"@babel/helper-module-imports@^7.10.4", "@babel/helper-module-imports@^7.16.7", "@babel/helper-module-imports@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.18.6.tgz#1e3ebdbbd08aad1437b428c50204db13c5a3ca6e" - integrity sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA== - dependencies: - "@babel/types" "^7.18.6" - -"@babel/helper-module-transforms@^7.18.6", "@babel/helper-module-transforms@^7.19.6", "@babel/helper-module-transforms@^7.20.2": - version "7.20.2" - resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.20.2.tgz#ac53da669501edd37e658602a21ba14c08748712" - integrity sha512-zvBKyJXRbmK07XhMuujYoJ48B5yvvmM6+wcpv6Ivj4Yg6qO7NOZOSnvZN9CRl1zz1Z4cKf8YejmCMh8clOoOeA== - dependencies: - "@babel/helper-environment-visitor" "^7.18.9" - "@babel/helper-module-imports" "^7.18.6" - "@babel/helper-simple-access" "^7.20.2" - "@babel/helper-split-export-declaration" "^7.18.6" - "@babel/helper-validator-identifier" "^7.19.1" - "@babel/template" "^7.18.10" - "@babel/traverse" "^7.20.1" - "@babel/types" "^7.20.2" - -"@babel/helper-optimise-call-expression@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.18.6.tgz#9369aa943ee7da47edab2cb4e838acf09d290ffe" - integrity sha512-HP59oD9/fEHQkdcbgFCnbmgH5vIQTJbxh2yf+CdM89/glUNnuzr87Q8GIjGEnOktTROemO0Pe0iPAYbqZuOUiA== +"@babel/helper-module-transforms@^7.22.5", "@babel/helper-module-transforms@^7.22.9": + version "7.22.9" + resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.22.9.tgz#92dfcb1fbbb2bc62529024f72d942a8c97142129" + integrity sha512-t+WA2Xn5K+rTeGtC8jCsdAH52bjggG5TKRuRrAGNM/mjIbO4GxvlLMFOEz9wXY5I2XQ60PMFsAG2WIcG82dQMQ== dependencies: - "@babel/types" "^7.18.6" - -"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.14.5", "@babel/helper-plugin-utils@^7.16.7", "@babel/helper-plugin-utils@^7.18.6", "@babel/helper-plugin-utils@^7.18.9", "@babel/helper-plugin-utils@^7.19.0", "@babel/helper-plugin-utils@^7.20.2", "@babel/helper-plugin-utils@^7.8.0", "@babel/helper-plugin-utils@^7.8.3": - version "7.20.2" - resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.20.2.tgz#d1b9000752b18d0877cff85a5c376ce5c3121629" - integrity sha512-8RvlJG2mj4huQ4pZ+rU9lqKi9ZKiRmuvGuM2HlWmkmgOhbs6zEAw6IEiJ5cQqGbDzGZOhwuOQNtZMi/ENLjZoQ== + "@babel/helper-environment-visitor" "^7.22.5" + "@babel/helper-module-imports" "^7.22.5" + "@babel/helper-simple-access" "^7.22.5" + "@babel/helper-split-export-declaration" "^7.22.6" + "@babel/helper-validator-identifier" "^7.22.5" -"@babel/helper-remap-async-to-generator@^7.18.6", "@babel/helper-remap-async-to-generator@^7.18.9": - version "7.18.9" - resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.18.9.tgz#997458a0e3357080e54e1d79ec347f8a8cd28519" - integrity sha512-dI7q50YKd8BAv3VEfgg7PS7yD3Rtbi2J1XMXaalXO0W0164hYLnh8zpjRS0mte9MfVp/tltvr/cfdXPvJr1opA== +"@babel/helper-optimise-call-expression@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.22.5.tgz#f21531a9ccbff644fdd156b4077c16ff0c3f609e" + integrity sha512-HBwaojN0xFRx4yIvpwGqxiV2tUfl7401jlok564NgB9EHS1y6QT17FmKWm4ztqjeVdXLuC4fSvHc5ePpQjoTbw== dependencies: - "@babel/helper-annotate-as-pure" "^7.18.6" - "@babel/helper-environment-visitor" "^7.18.9" - "@babel/helper-wrap-function" "^7.18.9" - "@babel/types" "^7.18.9" + "@babel/types" "^7.22.5" -"@babel/helper-replace-supers@^7.18.6", "@babel/helper-replace-supers@^7.19.1": - version "7.19.1" - resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.19.1.tgz#e1592a9b4b368aa6bdb8784a711e0bcbf0612b78" - integrity sha512-T7ahH7wV0Hfs46SFh5Jz3s0B6+o8g3c+7TMxu7xKfmHikg7EAZ3I2Qk9LFhjxXq8sL7UkP5JflezNwoZa8WvWw== - dependencies: - "@babel/helper-environment-visitor" "^7.18.9" - "@babel/helper-member-expression-to-functions" "^7.18.9" - "@babel/helper-optimise-call-expression" "^7.18.6" - "@babel/traverse" "^7.19.1" - "@babel/types" "^7.19.0" +"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.14.5", "@babel/helper-plugin-utils@^7.18.6", "@babel/helper-plugin-utils@^7.20.2", "@babel/helper-plugin-utils@^7.22.5", "@babel/helper-plugin-utils@^7.8.0", "@babel/helper-plugin-utils@^7.8.3": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz#dd7ee3735e8a313b9f7b05a773d892e88e6d7295" + integrity sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg== -"@babel/helper-simple-access@^7.19.4", "@babel/helper-simple-access@^7.20.2": - version "7.20.2" - resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.20.2.tgz#0ab452687fe0c2cfb1e2b9e0015de07fc2d62dd9" - integrity sha512-+0woI/WPq59IrqDYbVGfshjT5Dmk/nnbdpcF8SnMhhXObpTq2KNBdLFRFrkVdbDOyUmHBCxzm5FHV1rACIkIbA== +"@babel/helper-remap-async-to-generator@^7.22.5", "@babel/helper-remap-async-to-generator@^7.22.9": + version "7.22.9" + resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.22.9.tgz#53a25b7484e722d7efb9c350c75c032d4628de82" + integrity sha512-8WWC4oR4Px+tr+Fp0X3RHDVfINGpF3ad1HIbrc8A77epiR6eMMc6jsgozkzT2uDiOOdoS9cLIQ+XD2XvI2WSmQ== dependencies: - "@babel/types" "^7.20.2" + "@babel/helper-annotate-as-pure" "^7.22.5" + "@babel/helper-environment-visitor" "^7.22.5" + "@babel/helper-wrap-function" "^7.22.9" -"@babel/helper-skip-transparent-expression-wrappers@^7.18.9": - version "7.20.0" - resolved "https://registry.yarnpkg.com/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.20.0.tgz#fbe4c52f60518cab8140d77101f0e63a8a230684" - integrity sha512-5y1JYeNKfvnT8sZcK9DVRtpTbGiomYIHviSP3OQWmDPU3DeH4a1ZlT/N2lyQ5P8egjcRaT/Y9aNqUxK0WsnIIg== +"@babel/helper-replace-supers@^7.22.5", "@babel/helper-replace-supers@^7.22.9": + version "7.22.9" + resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.22.9.tgz#cbdc27d6d8d18cd22c81ae4293765a5d9afd0779" + integrity sha512-LJIKvvpgPOPUThdYqcX6IXRuIcTkcAub0IaDRGCZH0p5GPUp7PhRU9QVgFcDDd51BaPkk77ZjqFwh6DZTAEmGg== dependencies: - "@babel/types" "^7.20.0" + "@babel/helper-environment-visitor" "^7.22.5" + "@babel/helper-member-expression-to-functions" "^7.22.5" + "@babel/helper-optimise-call-expression" "^7.22.5" -"@babel/helper-split-export-declaration@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz#7367949bc75b20c6d5a5d4a97bba2824ae8ef075" - integrity sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA== +"@babel/helper-simple-access@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.22.5.tgz#4938357dc7d782b80ed6dbb03a0fba3d22b1d5de" + integrity sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w== dependencies: - "@babel/types" "^7.18.6" - -"@babel/helper-string-parser@^7.19.4": - version "7.19.4" - resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.19.4.tgz#38d3acb654b4701a9b77fb0615a96f775c3a9e63" - integrity sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw== + "@babel/types" "^7.22.5" -"@babel/helper-validator-identifier@^7.18.6", "@babel/helper-validator-identifier@^7.19.1": - version "7.19.1" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz#7eea834cf32901ffdc1a7ee555e2f9c27e249ca2" - integrity sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w== - -"@babel/helper-validator-option@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.18.6.tgz#bf0d2b5a509b1f336099e4ff36e1a63aa5db4db8" - integrity sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw== - -"@babel/helper-wrap-function@^7.18.9": - version "7.20.5" - resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.20.5.tgz#75e2d84d499a0ab3b31c33bcfe59d6b8a45f62e3" - integrity sha512-bYMxIWK5mh+TgXGVqAtnu5Yn1un+v8DDZtqyzKRLUzrh70Eal2O3aZ7aPYiMADO4uKlkzOiRiZ6GX5q3qxvW9Q== +"@babel/helper-skip-transparent-expression-wrappers@^7.20.0", "@babel/helper-skip-transparent-expression-wrappers@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.22.5.tgz#007f15240b5751c537c40e77abb4e89eeaaa8847" + integrity sha512-tK14r66JZKiC43p8Ki33yLBVJKlQDFoA8GYN67lWCDCqoL6EMMSuM9b+Iff2jHaM/RRFYl7K+iiru7hbRqNx8Q== dependencies: - "@babel/helper-function-name" "^7.19.0" - "@babel/template" "^7.18.10" - "@babel/traverse" "^7.20.5" - "@babel/types" "^7.20.5" + "@babel/types" "^7.22.5" -"@babel/helpers@^7.20.5": - version "7.20.6" - resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.20.6.tgz#e64778046b70e04779dfbdf924e7ebb45992c763" - integrity sha512-Pf/OjgfgFRW5bApskEz5pvidpim7tEDPlFtKcNRXWmfHGn9IEI2W2flqRQXTFb7gIPTyK++N6rVHuwKut4XK6w== +"@babel/helper-split-export-declaration@^7.22.6": + version "7.22.6" + resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz#322c61b7310c0997fe4c323955667f18fcefb91c" + integrity sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g== dependencies: - "@babel/template" "^7.18.10" - "@babel/traverse" "^7.20.5" - "@babel/types" "^7.20.5" + "@babel/types" "^7.22.5" -"@babel/highlight@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.18.6.tgz#81158601e93e2563795adcbfbdf5d64be3f2ecdf" - integrity sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g== - dependencies: - "@babel/helper-validator-identifier" "^7.18.6" - chalk "^2.0.0" - js-tokens "^4.0.0" +"@babel/helper-string-parser@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz#533f36457a25814cf1df6488523ad547d784a99f" + integrity sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw== -"@babel/parser@^7.1.0", "@babel/parser@^7.14.7", "@babel/parser@^7.18.10", "@babel/parser@^7.20.5": - version "7.20.5" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.20.5.tgz#7f3c7335fe417665d929f34ae5dceae4c04015e8" - integrity sha512-r27t/cy/m9uKLXQNWWebeCUHgnAZq0CpG1OwKRxzJMP1vpSU4bSIK2hq+/cp0bQxetkXx38n09rNu8jVkcK/zA== +"@babel/helper-validator-identifier@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.5.tgz#9544ef6a33999343c8740fa51350f30eeaaaf193" + integrity sha512-aJXu+6lErq8ltp+JhkJUfk1MTGyuA4v7f3pA+BJ5HLfNC6nAQ0Cpi9uOquUj8Hehg0aUiHzWQbOVJGao6ztBAQ== -"@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.18.6.tgz#da5b8f9a580acdfbe53494dba45ea389fb09a4d2" - integrity sha512-Dgxsyg54Fx1d4Nge8UnvTrED63vrwOdPmyvPzlNN/boaliRP54pm3pGzZD1SJUwrBA+Cs/xdG8kXX6Mn/RfISQ== - dependencies: - "@babel/helper-plugin-utils" "^7.18.6" +"@babel/helper-validator-option@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.22.5.tgz#de52000a15a177413c8234fa3a8af4ee8102d0ac" + integrity sha512-R3oB6xlIVKUnxNUxbmgq7pKjxpru24zlimpE8WK47fACIlM0II/Hm1RS8IaOI7NgCr6LNS+jl5l75m20npAziw== + +"@babel/helper-wrap-function@^7.22.9": + version "7.22.10" + resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.22.10.tgz#d845e043880ed0b8c18bd194a12005cb16d2f614" + integrity sha512-OnMhjWjuGYtdoO3FmsEFWvBStBAe2QOgwOLsLNDjN+aaiMD8InJk1/O3HSD8lkqTjCgg5YI34Tz15KNNA3p+nQ== + dependencies: + "@babel/helper-function-name" "^7.22.5" + "@babel/template" "^7.22.5" + "@babel/types" "^7.22.10" + +"@babel/helpers@^7.22.11": + version "7.22.11" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.22.11.tgz#b02f5d5f2d7abc21ab59eeed80de410ba70b056a" + integrity sha512-vyOXC8PBWaGc5h7GMsNx68OH33cypkEDJCHvYVVgVbbxJDROYVtexSk0gK5iCF1xNjRIN2s8ai7hwkWDq5szWg== + dependencies: + "@babel/template" "^7.22.5" + "@babel/traverse" "^7.22.11" + "@babel/types" "^7.22.11" + +"@babel/highlight@^7.22.13": + version "7.22.13" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.22.13.tgz#9cda839e5d3be9ca9e8c26b6dd69e7548f0cbf16" + integrity sha512-C/BaXcnnvBCmHTpz/VGZ8jgtE2aYlW4hxDhseJAWZb7gqGM/qtCK6iZUb0TyKFf7BOUsBH7Q7fkRsDRhg1XklQ== + dependencies: + "@babel/helper-validator-identifier" "^7.22.5" + chalk "^2.4.2" + js-tokens "^4.0.0" + +"@babel/parser@^7.1.0", "@babel/parser@^7.14.7", "@babel/parser@^7.20.7", "@babel/parser@^7.22.11", "@babel/parser@^7.22.5": + version "7.22.14" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.22.14.tgz#c7de58e8de106e88efca42ce17f0033209dfd245" + integrity sha512-1KucTHgOvaw/LzCVrEOAyXkr9rQlp0A1HiHRYnSUE9dmb8PvPW7o5sscg+5169r54n3vGlbx6GevTE/Iw/P3AQ== -"@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@^7.18.9": - version "7.18.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.18.9.tgz#a11af19aa373d68d561f08e0a57242350ed0ec50" - integrity sha512-AHrP9jadvH7qlOj6PINbgSuphjQUAK7AOT7DPjBo9EHoLhQTnnK5u45e1Hd4DbSQEO9nqPWtQ89r+XEOWFScKg== +"@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.22.5.tgz#87245a21cd69a73b0b81bcda98d443d6df08f05e" + integrity sha512-NP1M5Rf+u2Gw9qfSO4ihjcTGW5zXTi36ITLd4/EoAcEhIZ0yjMqmftDNl3QC19CX7olhrjpyU454g/2W7X0jvQ== dependencies: - "@babel/helper-plugin-utils" "^7.18.9" - "@babel/helper-skip-transparent-expression-wrappers" "^7.18.9" - "@babel/plugin-proposal-optional-chaining" "^7.18.9" + "@babel/helper-plugin-utils" "^7.22.5" -"@babel/plugin-proposal-async-generator-functions@^7.20.1": - version "7.20.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.20.1.tgz#352f02baa5d69f4e7529bdac39aaa02d41146af9" - integrity sha512-Gh5rchzSwE4kC+o/6T8waD0WHEQIsDmjltY8WnWRXHUdH8axZhuH86Ov9M72YhJfDrZseQwuuWaaIT/TmePp3g== +"@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.22.5.tgz#fef09f9499b1f1c930da8a0c419db42167d792ca" + integrity sha512-31Bb65aZaUwqCbWMnZPduIZxCBngHFlzyN6Dq6KAJjtx+lx6ohKHubc61OomYi7XwVD4Ol0XCVz4h+pYFR048g== dependencies: - "@babel/helper-environment-visitor" "^7.18.9" - "@babel/helper-plugin-utils" "^7.19.0" - "@babel/helper-remap-async-to-generator" "^7.18.9" - "@babel/plugin-syntax-async-generators" "^7.8.4" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-skip-transparent-expression-wrappers" "^7.22.5" + "@babel/plugin-transform-optional-chaining" "^7.22.5" -"@babel/plugin-proposal-class-properties@^7.16.0", "@babel/plugin-proposal-class-properties@^7.18.6": +"@babel/plugin-proposal-class-properties@^7.16.0": version "7.18.6" resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.18.6.tgz#b110f59741895f7ec21a6fff696ec46265c446a3" integrity sha512-cumfXOF0+nzZrrN8Rf0t7M+tF6sZc7vhQwYQck9q1/5w2OExlD+b4v4RpMJFaV1Z7WcDRgO6FqvxqxGlwo+RHQ== @@ -319,59 +309,18 @@ "@babel/helper-create-class-features-plugin" "^7.18.6" "@babel/helper-plugin-utils" "^7.18.6" -"@babel/plugin-proposal-class-static-block@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-static-block/-/plugin-proposal-class-static-block-7.18.6.tgz#8aa81d403ab72d3962fc06c26e222dacfc9b9020" - integrity sha512-+I3oIiNxrCpup3Gi8n5IGMwj0gOCAjcJUSQEcotNnCCPMEnixawOQ+KeJPlgfjzx+FKQ1QSyZOWe7wmoJp7vhw== - dependencies: - "@babel/helper-create-class-features-plugin" "^7.18.6" - "@babel/helper-plugin-utils" "^7.18.6" - "@babel/plugin-syntax-class-static-block" "^7.14.5" - "@babel/plugin-proposal-decorators@^7.16.4": - version "7.20.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.20.5.tgz#28ba1a0e5044664a512967a19407d7fc26925394" - integrity sha512-Lac7PpRJXcC3s9cKsBfl+uc+DYXU5FD06BrTFunQO6QIQT+DwyzDPURAowI3bcvD1dZF/ank1Z5rstUJn3Hn4Q== - dependencies: - "@babel/helper-create-class-features-plugin" "^7.20.5" - "@babel/helper-plugin-utils" "^7.20.2" - "@babel/helper-replace-supers" "^7.19.1" - "@babel/helper-split-export-declaration" "^7.18.6" - "@babel/plugin-syntax-decorators" "^7.19.0" - -"@babel/plugin-proposal-dynamic-import@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.18.6.tgz#72bcf8d408799f547d759298c3c27c7e7faa4d94" - integrity sha512-1auuwmK+Rz13SJj36R+jqFPMJWyKEDd7lLSdOj4oJK0UTgGueSAtkrCvz9ewmgyU/P941Rv2fQwZJN8s6QruXw== - dependencies: - "@babel/helper-plugin-utils" "^7.18.6" - "@babel/plugin-syntax-dynamic-import" "^7.8.3" - -"@babel/plugin-proposal-export-namespace-from@^7.18.9": - version "7.18.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.18.9.tgz#5f7313ab348cdb19d590145f9247540e94761203" - integrity sha512-k1NtHyOMvlDDFeb9G5PhUXuGj8m/wiwojgQVEhJ/fsVsMCpLyOP4h0uGEjYJKrRI+EVPlb5Jk+Gt9P97lOGwtA== + version "7.22.10" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.22.10.tgz#d6a8c3a9018e1b13e6647f869c5ea56ff2b585d4" + integrity sha512-KxN6TqZzcFi4uD3UifqXElBTBNLAEH1l3vzMQj6JwJZbL2sZlThxSViOKCYY+4Ah4V4JhQ95IVB7s/Y6SJSlMQ== dependencies: - "@babel/helper-plugin-utils" "^7.18.9" - "@babel/plugin-syntax-export-namespace-from" "^7.8.3" + "@babel/helper-create-class-features-plugin" "^7.22.10" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-replace-supers" "^7.22.9" + "@babel/helper-split-export-declaration" "^7.22.6" + "@babel/plugin-syntax-decorators" "^7.22.10" -"@babel/plugin-proposal-json-strings@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.18.6.tgz#7e8788c1811c393aff762817e7dbf1ebd0c05f0b" - integrity sha512-lr1peyn9kOdbYc0xr0OdHTZ5FMqS6Di+H0Fz2I/JwMzGmzJETNeOFq2pBySw6X/KFL5EWDjlJuMsUGRFb8fQgQ== - dependencies: - "@babel/helper-plugin-utils" "^7.18.6" - "@babel/plugin-syntax-json-strings" "^7.8.3" - -"@babel/plugin-proposal-logical-assignment-operators@^7.18.9": - version "7.18.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.18.9.tgz#8148cbb350483bf6220af06fa6db3690e14b2e23" - integrity sha512-128YbMpjCrP35IOExw2Fq+x55LMP42DzhOhX2aNNIdI9avSWl2PI0yuBWarr3RYpZBSPtabfadkH2yeRiMD61Q== - dependencies: - "@babel/helper-plugin-utils" "^7.18.9" - "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4" - -"@babel/plugin-proposal-nullish-coalescing-operator@^7.16.0", "@babel/plugin-proposal-nullish-coalescing-operator@^7.18.6": +"@babel/plugin-proposal-nullish-coalescing-operator@^7.16.0": version "7.18.6" resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.18.6.tgz#fdd940a99a740e577d6c753ab6fbb43fdb9467e1" integrity sha512-wQxQzxYeJqHcfppzBDnm1yAY0jSRkUXR2z8RePZYrKwMKgMlE8+Z6LUno+bd6LvbGh8Gltvy74+9pIYkr+XkKA== @@ -379,7 +328,7 @@ "@babel/helper-plugin-utils" "^7.18.6" "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" -"@babel/plugin-proposal-numeric-separator@^7.16.0", "@babel/plugin-proposal-numeric-separator@^7.18.6": +"@babel/plugin-proposal-numeric-separator@^7.16.0": version "7.18.6" resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.18.6.tgz#899b14fbafe87f053d2c5ff05b36029c62e13c75" integrity sha512-ozlZFogPqoLm8WBr5Z8UckIoE4YQ5KESVcNudyXOR8uqIkliTEgJ3RoketfG6pmzLdeZF0H/wjE9/cCEitBl7Q== @@ -387,35 +336,16 @@ "@babel/helper-plugin-utils" "^7.18.6" "@babel/plugin-syntax-numeric-separator" "^7.10.4" -"@babel/plugin-proposal-object-rest-spread@^7.20.2": - version "7.20.2" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.20.2.tgz#a556f59d555f06961df1e572bb5eca864c84022d" - integrity sha512-Ks6uej9WFK+fvIMesSqbAto5dD8Dz4VuuFvGJFKgIGSkJuRGcrwGECPA1fDgQK3/DbExBJpEkTeYeB8geIFCSQ== +"@babel/plugin-proposal-optional-chaining@^7.16.0": + version "7.21.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.21.0.tgz#886f5c8978deb7d30f678b2e24346b287234d3ea" + integrity sha512-p4zeefM72gpmEe2fkUr/OnOXpWEf8nAgk7ZYVqqfFiyIG7oFfVZcCrU64hWn5xp4tQ9LkV4bTIa5rD0KANpKNA== dependencies: - "@babel/compat-data" "^7.20.1" - "@babel/helper-compilation-targets" "^7.20.0" "@babel/helper-plugin-utils" "^7.20.2" - "@babel/plugin-syntax-object-rest-spread" "^7.8.3" - "@babel/plugin-transform-parameters" "^7.20.1" - -"@babel/plugin-proposal-optional-catch-binding@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.18.6.tgz#f9400d0e6a3ea93ba9ef70b09e72dd6da638a2cb" - integrity sha512-Q40HEhs9DJQyaZfUjjn6vE8Cv4GmMHCYuMGIWUnlxH6400VGxOuwWsPt4FxXxJkC/5eOzgn0z21M9gMT4MOhbw== - dependencies: - "@babel/helper-plugin-utils" "^7.18.6" - "@babel/plugin-syntax-optional-catch-binding" "^7.8.3" - -"@babel/plugin-proposal-optional-chaining@^7.16.0", "@babel/plugin-proposal-optional-chaining@^7.18.9": - version "7.18.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.18.9.tgz#e8e8fe0723f2563960e4bf5e9690933691915993" - integrity sha512-v5nwt4IqBXihxGsW2QmCWMDS3B3bzGIk/EQVZz2ei7f3NJl8NzAJVvUmpDW5q1CRNY+Beb/k58UAH1Km1N411w== - dependencies: - "@babel/helper-plugin-utils" "^7.18.9" - "@babel/helper-skip-transparent-expression-wrappers" "^7.18.9" + "@babel/helper-skip-transparent-expression-wrappers" "^7.20.0" "@babel/plugin-syntax-optional-chaining" "^7.8.3" -"@babel/plugin-proposal-private-methods@^7.16.0", "@babel/plugin-proposal-private-methods@^7.18.6": +"@babel/plugin-proposal-private-methods@^7.16.0": version "7.18.6" resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.18.6.tgz#5209de7d213457548a98436fa2882f52f4be6bea" integrity sha512-nutsvktDItsNn4rpGItSNV2sz1XwS+nfU0Rg8aCx3W3NOKVzdMjJRu0O5OkgDp3ZGICSTbgRpxZoWsxoKRvbeA== @@ -423,24 +353,21 @@ "@babel/helper-create-class-features-plugin" "^7.18.6" "@babel/helper-plugin-utils" "^7.18.6" -"@babel/plugin-proposal-private-property-in-object@^7.18.6": - version "7.20.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.20.5.tgz#309c7668f2263f1c711aa399b5a9a6291eef6135" - integrity sha512-Vq7b9dUA12ByzB4EjQTPo25sFhY+08pQDBSZRtUAkj7lb7jahaHR5igera16QZ+3my1nYR4dKsNdYj5IjPHilQ== +"@babel/plugin-proposal-private-property-in-object@7.21.0-placeholder-for-preset-env.2": + version "7.21.0-placeholder-for-preset-env.2" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0-placeholder-for-preset-env.2.tgz#7844f9289546efa9febac2de4cfe358a050bd703" + integrity sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w== + +"@babel/plugin-proposal-private-property-in-object@^7.21.11": + version "7.21.11" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.11.tgz#69d597086b6760c4126525cfa154f34631ff272c" + integrity sha512-0QZ8qP/3RLDVBwBFoWAwCtgcDZJVwA5LUJRZU8x2YFfKNuFq161wK3cuGrALu5yiPu+vzwTAg/sMWVNeWeNyaw== dependencies: "@babel/helper-annotate-as-pure" "^7.18.6" - "@babel/helper-create-class-features-plugin" "^7.20.5" + "@babel/helper-create-class-features-plugin" "^7.21.0" "@babel/helper-plugin-utils" "^7.20.2" "@babel/plugin-syntax-private-property-in-object" "^7.14.5" -"@babel/plugin-proposal-unicode-property-regex@^7.18.6", "@babel/plugin-proposal-unicode-property-regex@^7.4.4": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.18.6.tgz#af613d2cd5e643643b65cded64207b15c85cb78e" - integrity sha512-2BShG/d5yoZyXZfVePH91urL5wTG6ASZU9M4o03lKK8u8UW1y08OMttBSOADTcJrnPMpvDXRG3G8fyLh4ovs8w== - dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.18.6" - "@babel/helper-plugin-utils" "^7.18.6" - "@babel/plugin-syntax-async-generators@^7.8.4": version "7.8.4" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz#a983fb1aeb2ec3f6ed042a210f640e90e786fe0d" @@ -469,12 +396,12 @@ dependencies: "@babel/helper-plugin-utils" "^7.14.5" -"@babel/plugin-syntax-decorators@^7.19.0": - version "7.19.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.19.0.tgz#5f13d1d8fce96951bea01a10424463c9a5b3a599" - integrity sha512-xaBZUEDntt4faL1yN8oIFlhfXeQAWJW7CLKYsHTUqriCUbj8xOra8bfxxKGi/UwExPFBuPdH4XfHc9rGQhrVkQ== +"@babel/plugin-syntax-decorators@^7.22.10": + version "7.22.10" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.22.10.tgz#7d83ea04d893c442b78ebf4c3cbac59a7211deff" + integrity sha512-z1KTVemBjnz+kSEilAsI4lbkPOl5TvJH7YDSY1CTIzvLWJ+KHXp+mRe8VPmfnyvqOPqar1V2gid2PleKzRUstQ== dependencies: - "@babel/helper-plugin-utils" "^7.19.0" + "@babel/helper-plugin-utils" "^7.22.5" "@babel/plugin-syntax-dynamic-import@^7.8.3": version "7.8.3" @@ -490,21 +417,28 @@ dependencies: "@babel/helper-plugin-utils" "^7.8.3" -"@babel/plugin-syntax-flow@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.18.6.tgz#774d825256f2379d06139be0c723c4dd444f3ca1" - integrity sha512-LUbR+KNTBWCUAqRG9ex5Gnzu2IOkt8jRJbHHXFT9q+L9zm7M/QQbEqXyw1n1pohYvOyWC8CjeyjrSaIwiYjK7A== +"@babel/plugin-syntax-flow@^7.18.6", "@babel/plugin-syntax-flow@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.22.5.tgz#163b820b9e7696ce134df3ee716d9c0c98035859" + integrity sha512-9RdCl0i+q0QExayk2nOS7853w08yLucnnPML6EN9S8fgMPVtdLDCdx/cOQ/i44Lb9UeQX9A35yaqBBOMMZxPxQ== dependencies: - "@babel/helper-plugin-utils" "^7.18.6" + "@babel/helper-plugin-utils" "^7.22.5" -"@babel/plugin-syntax-import-assertions@^7.20.0": - version "7.20.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.20.0.tgz#bb50e0d4bea0957235390641209394e87bdb9cc4" - integrity sha512-IUh1vakzNoWalR8ch/areW7qFopR2AEw03JlG7BbrDqmQ4X3q9uuipQwSGrUn7oGiemKjtSLDhNtQHzMHr1JdQ== +"@babel/plugin-syntax-import-assertions@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.22.5.tgz#07d252e2aa0bc6125567f742cd58619cb14dce98" + integrity sha512-rdV97N7KqsRzeNGoWUOK6yUsWarLjE5Su/Snk9IYPU9CwkWHs4t+rTGOvffTR8XGkJMTAdLfO0xVnXm8wugIJg== dependencies: - "@babel/helper-plugin-utils" "^7.19.0" + "@babel/helper-plugin-utils" "^7.22.5" -"@babel/plugin-syntax-import-meta@^7.8.3": +"@babel/plugin-syntax-import-attributes@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.22.5.tgz#ab840248d834410b829f569f5262b9e517555ecb" + integrity sha512-KwvoWDeNKPETmozyFE0P2rOLqh39EoQHNjqizrI5B8Vt0ZNS7M56s7dAiAqbYfiAYOuIzIh96z3iR2ktgu3tEg== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-syntax-import-meta@^7.10.4", "@babel/plugin-syntax-import-meta@^7.8.3": version "7.10.4" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz#ee601348c370fa334d2207be158777496521fd51" integrity sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g== @@ -518,12 +452,12 @@ dependencies: "@babel/helper-plugin-utils" "^7.8.0" -"@babel/plugin-syntax-jsx@^7.17.12", "@babel/plugin-syntax-jsx@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.18.6.tgz#a8feef63b010150abd97f1649ec296e849943ca0" - integrity sha512-6mmljtAedFGTWu2p/8WIORGwy+61PLgOMPOdazc7YoJ9ZCWUyFy3A6CpPkRKLKD1ToAesxX8KGEViAiLo9N+7Q== +"@babel/plugin-syntax-jsx@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.22.5.tgz#a6b68e84fb76e759fc3b93e901876ffabbe1d918" + integrity sha512-gvyP4hZrgrs/wWMaocvxZ44Hw0b3W8Pe+cMxc8V1ULQ07oh8VNbIRaoD1LRZVTvD+0nieDKjfgKg89sD7rrKrg== dependencies: - "@babel/helper-plugin-utils" "^7.18.6" + "@babel/helper-plugin-utils" "^7.22.5" "@babel/plugin-syntax-logical-assignment-operators@^7.10.4", "@babel/plugin-syntax-logical-assignment-operators@^7.8.3": version "7.10.4" @@ -581,364 +515,499 @@ dependencies: "@babel/helper-plugin-utils" "^7.14.5" -"@babel/plugin-syntax-typescript@^7.20.0", "@babel/plugin-syntax-typescript@^7.7.2": - version "7.20.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.20.0.tgz#4e9a0cfc769c85689b77a2e642d24e9f697fc8c7" - integrity sha512-rd9TkG+u1CExzS4SM1BlMEhMXwFLKVjOAFFCDx9PbX5ycJWDoWMcwdJH9RhkPu1dOgn5TrxLot/Gx6lWFuAUNQ== +"@babel/plugin-syntax-typescript@^7.22.5", "@babel/plugin-syntax-typescript@^7.7.2": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.22.5.tgz#aac8d383b062c5072c647a31ef990c1d0af90272" + integrity sha512-1mS2o03i7t1c6VzH6fdQ3OA8tcEIxwG18zIPRp+UY1Ihv6W+XZzBCVxExF9upussPXJ0xE9XRHwMoNs1ep/nRQ== dependencies: - "@babel/helper-plugin-utils" "^7.19.0" + "@babel/helper-plugin-utils" "^7.22.5" -"@babel/plugin-transform-arrow-functions@^7.18.6": +"@babel/plugin-syntax-unicode-sets-regex@^7.18.6": version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.18.6.tgz#19063fcf8771ec7b31d742339dac62433d0611fe" - integrity sha512-9S9X9RUefzrsHZmKMbDXxweEH+YlE8JJEuat9FdvW9Qh1cw7W64jELCtWNkPBPX5En45uy28KGvA/AySqUh8CQ== + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-unicode-sets-regex/-/plugin-syntax-unicode-sets-regex-7.18.6.tgz#d49a3b3e6b52e5be6740022317580234a6a47357" + integrity sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg== dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.18.6" "@babel/helper-plugin-utils" "^7.18.6" -"@babel/plugin-transform-async-to-generator@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.18.6.tgz#ccda3d1ab9d5ced5265fdb13f1882d5476c71615" - integrity sha512-ARE5wZLKnTgPW7/1ftQmSi1CmkqqHo2DNmtztFhvgtOWSDfq0Cq9/9L+KnZNYSNrydBekhW3rwShduf59RoXag== +"@babel/plugin-transform-arrow-functions@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.22.5.tgz#e5ba566d0c58a5b2ba2a8b795450641950b71958" + integrity sha512-26lTNXoVRdAnsaDXPpvCNUq+OVWEVC6bx7Vvz9rC53F2bagUWW4u4ii2+h8Fejfh7RYqPxn+libeFBBck9muEw== dependencies: - "@babel/helper-module-imports" "^7.18.6" - "@babel/helper-plugin-utils" "^7.18.6" - "@babel/helper-remap-async-to-generator" "^7.18.6" + "@babel/helper-plugin-utils" "^7.22.5" -"@babel/plugin-transform-block-scoped-functions@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.18.6.tgz#9187bf4ba302635b9d70d986ad70f038726216a8" - integrity sha512-ExUcOqpPWnliRcPqves5HJcJOvHvIIWfuS4sroBUenPuMdmW+SMHDakmtS7qOo13sVppmUijqeTv7qqGsvURpQ== +"@babel/plugin-transform-async-generator-functions@^7.22.11": + version "7.22.11" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.22.11.tgz#dbe3b1ff5a52e2e5edc4b19a60d325a675ed2649" + integrity sha512-0pAlmeRJn6wU84zzZsEOx1JV1Jf8fqO9ok7wofIJwUnplYo247dcd24P+cMJht7ts9xkzdtB0EPHmOb7F+KzXw== dependencies: - "@babel/helper-plugin-utils" "^7.18.6" + "@babel/helper-environment-visitor" "^7.22.5" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-remap-async-to-generator" "^7.22.9" + "@babel/plugin-syntax-async-generators" "^7.8.4" -"@babel/plugin-transform-block-scoping@^7.20.2": - version "7.20.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.20.5.tgz#401215f9dc13dc5262940e2e527c9536b3d7f237" - integrity sha512-WvpEIW9Cbj9ApF3yJCjIEEf1EiNJLtXagOrL5LNWEZOo3jv8pmPoYTSNJQvqej8OavVlgOoOPw6/htGZro6IkA== +"@babel/plugin-transform-async-to-generator@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.22.5.tgz#c7a85f44e46f8952f6d27fe57c2ed3cc084c3775" + integrity sha512-b1A8D8ZzE/VhNDoV1MSJTnpKkCG5bJo+19R4o4oy03zM7ws8yEMK755j61Dc3EyvdysbqH5BOOTquJ7ZX9C6vQ== dependencies: - "@babel/helper-plugin-utils" "^7.20.2" + "@babel/helper-module-imports" "^7.22.5" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-remap-async-to-generator" "^7.22.5" + +"@babel/plugin-transform-block-scoped-functions@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.22.5.tgz#27978075bfaeb9fa586d3cb63a3d30c1de580024" + integrity sha512-tdXZ2UdknEKQWKJP1KMNmuF5Lx3MymtMN/pvA+p/VEkhK8jVcQ1fzSy8KM9qRYhAf2/lV33hoMPKI/xaI9sADA== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" -"@babel/plugin-transform-classes@^7.20.2": - version "7.20.2" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.20.2.tgz#c0033cf1916ccf78202d04be4281d161f6709bb2" - integrity sha512-9rbPp0lCVVoagvtEyQKSo5L8oo0nQS/iif+lwlAz29MccX2642vWDlSZK+2T2buxbopotId2ld7zZAzRfz9j1g== +"@babel/plugin-transform-block-scoping@^7.22.10": + version "7.22.10" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.22.10.tgz#88a1dccc3383899eb5e660534a76a22ecee64faa" + integrity sha512-1+kVpGAOOI1Albt6Vse7c8pHzcZQdQKW+wJH+g8mCaszOdDVwRXa/slHPqIw+oJAJANTKDMuM2cBdV0Dg618Vg== dependencies: - "@babel/helper-annotate-as-pure" "^7.18.6" - "@babel/helper-compilation-targets" "^7.20.0" - "@babel/helper-environment-visitor" "^7.18.9" - "@babel/helper-function-name" "^7.19.0" - "@babel/helper-optimise-call-expression" "^7.18.6" - "@babel/helper-plugin-utils" "^7.20.2" - "@babel/helper-replace-supers" "^7.19.1" - "@babel/helper-split-export-declaration" "^7.18.6" + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-class-properties@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.22.5.tgz#97a56e31ad8c9dc06a0b3710ce7803d5a48cca77" + integrity sha512-nDkQ0NfkOhPTq8YCLiWNxp1+f9fCobEjCb0n8WdbNUBc4IB5V7P1QnX9IjpSoquKrXF5SKojHleVNs2vGeHCHQ== + dependencies: + "@babel/helper-create-class-features-plugin" "^7.22.5" + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-class-static-block@^7.22.11": + version "7.22.11" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.22.11.tgz#dc8cc6e498f55692ac6b4b89e56d87cec766c974" + integrity sha512-GMM8gGmqI7guS/llMFk1bJDkKfn3v3C4KHK9Yg1ey5qcHcOlKb0QvcMrgzvxo+T03/4szNh5lghY+fEC98Kq9g== + dependencies: + "@babel/helper-create-class-features-plugin" "^7.22.11" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-syntax-class-static-block" "^7.14.5" + +"@babel/plugin-transform-classes@^7.22.6": + version "7.22.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.22.6.tgz#e04d7d804ed5b8501311293d1a0e6d43e94c3363" + integrity sha512-58EgM6nuPNG6Py4Z3zSuu0xWu2VfodiMi72Jt5Kj2FECmaYk1RrTXA45z6KBFsu9tRgwQDwIiY4FXTt+YsSFAQ== + dependencies: + "@babel/helper-annotate-as-pure" "^7.22.5" + "@babel/helper-compilation-targets" "^7.22.6" + "@babel/helper-environment-visitor" "^7.22.5" + "@babel/helper-function-name" "^7.22.5" + "@babel/helper-optimise-call-expression" "^7.22.5" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-replace-supers" "^7.22.5" + "@babel/helper-split-export-declaration" "^7.22.6" globals "^11.1.0" -"@babel/plugin-transform-computed-properties@^7.18.9": - version "7.18.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.18.9.tgz#2357a8224d402dad623caf6259b611e56aec746e" - integrity sha512-+i0ZU1bCDymKakLxn5srGHrsAPRELC2WIbzwjLhHW9SIE1cPYkLCL0NlnXMZaM1vhfgA2+M7hySk42VBvrkBRw== +"@babel/plugin-transform-computed-properties@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.22.5.tgz#cd1e994bf9f316bd1c2dafcd02063ec261bb3869" + integrity sha512-4GHWBgRf0krxPX+AaPtgBAlTgTeZmqDynokHOX7aqqAB4tHs3U2Y02zH6ETFdLZGcg9UQSD1WCmkVrE9ErHeOg== dependencies: - "@babel/helper-plugin-utils" "^7.18.9" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/template" "^7.22.5" -"@babel/plugin-transform-destructuring@^7.20.2": - version "7.20.2" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.20.2.tgz#c23741cfa44ddd35f5e53896e88c75331b8b2792" - integrity sha512-mENM+ZHrvEgxLTBXUiQ621rRXZes3KWUv6NdQlrnr1TkWVw+hUjQBZuP2X32qKlrlG2BzgR95gkuCRSkJl8vIw== +"@babel/plugin-transform-destructuring@^7.22.10": + version "7.22.10" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.22.10.tgz#38e2273814a58c810b6c34ea293be4973c4eb5e2" + integrity sha512-dPJrL0VOyxqLM9sritNbMSGx/teueHF/htMKrPT7DNxccXxRDPYqlgPFFdr8u+F+qUZOkZoXue/6rL5O5GduEw== dependencies: - "@babel/helper-plugin-utils" "^7.20.2" + "@babel/helper-plugin-utils" "^7.22.5" -"@babel/plugin-transform-dotall-regex@^7.18.6", "@babel/plugin-transform-dotall-regex@^7.4.4": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.18.6.tgz#b286b3e7aae6c7b861e45bed0a2fafd6b1a4fef8" - integrity sha512-6S3jpun1eEbAxq7TdjLotAsl4WpQI9DxfkycRcKrjhQYzU87qpXdknpBg/e+TdcMehqGnLFi7tnFUBR02Vq6wg== +"@babel/plugin-transform-dotall-regex@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.22.5.tgz#dbb4f0e45766eb544e193fb00e65a1dd3b2a4165" + integrity sha512-5/Yk9QxCQCl+sOIB1WelKnVRxTJDSAIxtJLL2/pqL14ZVlbH0fUQUZa/T5/UnQtBNgghR7mfB8ERBKyKPCi7Vw== dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.18.6" - "@babel/helper-plugin-utils" "^7.18.6" + "@babel/helper-create-regexp-features-plugin" "^7.22.5" + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-duplicate-keys@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.22.5.tgz#b6e6428d9416f5f0bba19c70d1e6e7e0b88ab285" + integrity sha512-dEnYD+9BBgld5VBXHnF/DbYGp3fqGMsyxKbtD1mDyIA7AkTSpKXFhCVuj/oQVOoALfBs77DudA0BE4d5mcpmqw== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" -"@babel/plugin-transform-duplicate-keys@^7.18.9": - version "7.18.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.18.9.tgz#687f15ee3cdad6d85191eb2a372c4528eaa0ae0e" - integrity sha512-d2bmXCtZXYc59/0SanQKbiWINadaJXqtvIQIzd4+hNwkWBgyCd5F/2t1kXoUdvPMrxzPvhK6EMQRROxsue+mfw== +"@babel/plugin-transform-dynamic-import@^7.22.11": + version "7.22.11" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.22.11.tgz#2c7722d2a5c01839eaf31518c6ff96d408e447aa" + integrity sha512-g/21plo58sfteWjaO0ZNVb+uEOkJNjAaHhbejrnBmu011l/eNDScmkbjCC3l4FKb10ViaGU4aOkFznSu2zRHgA== dependencies: - "@babel/helper-plugin-utils" "^7.18.9" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-syntax-dynamic-import" "^7.8.3" -"@babel/plugin-transform-exponentiation-operator@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.18.6.tgz#421c705f4521888c65e91fdd1af951bfefd4dacd" - integrity sha512-wzEtc0+2c88FVR34aQmiz56dxEkxr2g8DQb/KfaFa1JYXOFVsbhvAonFN6PwVWj++fKmku8NP80plJ5Et4wqHw== +"@babel/plugin-transform-exponentiation-operator@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.22.5.tgz#402432ad544a1f9a480da865fda26be653e48f6a" + integrity sha512-vIpJFNM/FjZ4rh1myqIya9jXwrwwgFRHPjT3DkUA9ZLHuzox8jiXkOLvwm1H+PQIP3CqfC++WPKeuDi0Sjdj1g== dependencies: - "@babel/helper-builder-binary-assignment-operator-visitor" "^7.18.6" - "@babel/helper-plugin-utils" "^7.18.6" + "@babel/helper-builder-binary-assignment-operator-visitor" "^7.22.5" + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-export-namespace-from@^7.22.11": + version "7.22.11" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.22.11.tgz#b3c84c8f19880b6c7440108f8929caf6056db26c" + integrity sha512-xa7aad7q7OiT8oNZ1mU7NrISjlSkVdMbNxn9IuLZyL9AJEhs1Apba3I+u5riX1dIkdptP5EKDG5XDPByWxtehw== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-syntax-export-namespace-from" "^7.8.3" "@babel/plugin-transform-flow-strip-types@^7.16.0": - version "7.19.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.19.0.tgz#e9e8606633287488216028719638cbbb2f2dde8f" - integrity sha512-sgeMlNaQVbCSpgLSKP4ZZKfsJVnFnNQlUSk6gPYzR/q7tzCgQF2t8RBKAP6cKJeZdveei7Q7Jm527xepI8lNLg== + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.22.5.tgz#0bb17110c7bf5b35a60754b2f00c58302381dee2" + integrity sha512-tujNbZdxdG0/54g/oua8ISToaXTFBf8EnSb5PgQSciIXWOWKX3S4+JR7ZE9ol8FZwf9kxitzkGQ+QWeov/mCiA== dependencies: - "@babel/helper-plugin-utils" "^7.19.0" - "@babel/plugin-syntax-flow" "^7.18.6" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-syntax-flow" "^7.22.5" -"@babel/plugin-transform-for-of@^7.18.8": - version "7.18.8" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.18.8.tgz#6ef8a50b244eb6a0bdbad0c7c61877e4e30097c1" - integrity sha512-yEfTRnjuskWYo0k1mHUqrVWaZwrdq8AYbfrpqULOJOaucGSp4mNMVps+YtA8byoevxS/urwU75vyhQIxcCgiBQ== +"@babel/plugin-transform-for-of@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.22.5.tgz#ab1b8a200a8f990137aff9a084f8de4099ab173f" + integrity sha512-3kxQjX1dU9uudwSshyLeEipvrLjBCVthCgeTp6CzE/9JYrlAIaeekVxRpCWsDDfYTfRZRoCeZatCQvwo+wvK8A== dependencies: - "@babel/helper-plugin-utils" "^7.18.6" + "@babel/helper-plugin-utils" "^7.22.5" -"@babel/plugin-transform-function-name@^7.18.9": - version "7.18.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.18.9.tgz#cc354f8234e62968946c61a46d6365440fc764e0" - integrity sha512-WvIBoRPaJQ5yVHzcnJFor7oS5Ls0PYixlTYE63lCj2RtdQEl15M68FXQlxnG6wdraJIXRdR7KI+hQ7q/9QjrCQ== +"@babel/plugin-transform-function-name@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.22.5.tgz#935189af68b01898e0d6d99658db6b164205c143" + integrity sha512-UIzQNMS0p0HHiQm3oelztj+ECwFnj+ZRV4KnguvlsD2of1whUeM6o7wGNj6oLwcDoAXQ8gEqfgC24D+VdIcevg== dependencies: - "@babel/helper-compilation-targets" "^7.18.9" - "@babel/helper-function-name" "^7.18.9" - "@babel/helper-plugin-utils" "^7.18.9" + "@babel/helper-compilation-targets" "^7.22.5" + "@babel/helper-function-name" "^7.22.5" + "@babel/helper-plugin-utils" "^7.22.5" -"@babel/plugin-transform-literals@^7.18.9": - version "7.18.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.18.9.tgz#72796fdbef80e56fba3c6a699d54f0de557444bc" - integrity sha512-IFQDSRoTPnrAIrI5zoZv73IFeZu2dhu6irxQjY9rNjTT53VmKg9fenjvoiOWOkJ6mm4jKVPtdMzBY98Fp4Z4cg== +"@babel/plugin-transform-json-strings@^7.22.11": + version "7.22.11" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.22.11.tgz#689a34e1eed1928a40954e37f74509f48af67835" + integrity sha512-CxT5tCqpA9/jXFlme9xIBCc5RPtdDq3JpkkhgHQqtDdiTnTI0jtZ0QzXhr5DILeYifDPp2wvY2ad+7+hLMW5Pw== dependencies: - "@babel/helper-plugin-utils" "^7.18.9" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-syntax-json-strings" "^7.8.3" -"@babel/plugin-transform-member-expression-literals@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.18.6.tgz#ac9fdc1a118620ac49b7e7a5d2dc177a1bfee88e" - integrity sha512-qSF1ihLGO3q+/g48k85tUjD033C29TNTVB2paCwZPVmOsjn9pClvYYrM2VeJpBY2bcNkuny0YUyTNRyRxJ54KA== +"@babel/plugin-transform-literals@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.22.5.tgz#e9341f4b5a167952576e23db8d435849b1dd7920" + integrity sha512-fTLj4D79M+mepcw3dgFBTIDYpbcB9Sm0bpm4ppXPaO+U+PKFFyV9MGRvS0gvGw62sd10kT5lRMKXAADb9pWy8g== dependencies: - "@babel/helper-plugin-utils" "^7.18.6" + "@babel/helper-plugin-utils" "^7.22.5" -"@babel/plugin-transform-modules-amd@^7.19.6": - version "7.19.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.19.6.tgz#aca391801ae55d19c4d8d2ebfeaa33df5f2a2cbd" - integrity sha512-uG3od2mXvAtIFQIh0xrpLH6r5fpSQN04gIVovl+ODLdUMANokxQLZnPBHcjmv3GxRjnqwLuHvppjjcelqUFZvg== +"@babel/plugin-transform-logical-assignment-operators@^7.22.11": + version "7.22.11" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.22.11.tgz#24c522a61688bde045b7d9bc3c2597a4d948fc9c" + integrity sha512-qQwRTP4+6xFCDV5k7gZBF3C31K34ut0tbEcTKxlX/0KXxm9GLcO14p570aWxFvVzx6QAfPgq7gaeIHXJC8LswQ== dependencies: - "@babel/helper-module-transforms" "^7.19.6" - "@babel/helper-plugin-utils" "^7.19.0" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4" -"@babel/plugin-transform-modules-commonjs@^7.19.6": - version "7.19.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.19.6.tgz#25b32feef24df8038fc1ec56038917eacb0b730c" - integrity sha512-8PIa1ym4XRTKuSsOUXqDG0YaOlEuTVvHMe5JCfgBMOtHvJKw/4NGovEGN33viISshG/rZNVrACiBmPQLvWN8xQ== +"@babel/plugin-transform-member-expression-literals@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.22.5.tgz#4fcc9050eded981a468347dd374539ed3e058def" + integrity sha512-RZEdkNtzzYCFl9SE9ATaUMTj2hqMb4StarOJLrZRbqqU4HSBE7UlBw9WBWQiDzrJZJdUWiMTVDI6Gv/8DPvfew== dependencies: - "@babel/helper-module-transforms" "^7.19.6" - "@babel/helper-plugin-utils" "^7.19.0" - "@babel/helper-simple-access" "^7.19.4" + "@babel/helper-plugin-utils" "^7.22.5" -"@babel/plugin-transform-modules-systemjs@^7.19.6": - version "7.19.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.19.6.tgz#59e2a84064b5736a4471b1aa7b13d4431d327e0d" - integrity sha512-fqGLBepcc3kErfR9R3DnVpURmckXP7gj7bAlrTQyBxrigFqszZCkFkcoxzCp2v32XmwXLvbw+8Yq9/b+QqksjQ== +"@babel/plugin-transform-modules-amd@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.22.5.tgz#4e045f55dcf98afd00f85691a68fc0780704f526" + integrity sha512-R+PTfLTcYEmb1+kK7FNkhQ1gP4KgjpSO6HfH9+f8/yfp2Nt3ggBjiVpRwmwTlfqZLafYKJACy36yDXlEmI9HjQ== dependencies: - "@babel/helper-hoist-variables" "^7.18.6" - "@babel/helper-module-transforms" "^7.19.6" - "@babel/helper-plugin-utils" "^7.19.0" - "@babel/helper-validator-identifier" "^7.19.1" + "@babel/helper-module-transforms" "^7.22.5" + "@babel/helper-plugin-utils" "^7.22.5" -"@babel/plugin-transform-modules-umd@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.18.6.tgz#81d3832d6034b75b54e62821ba58f28ed0aab4b9" - integrity sha512-dcegErExVeXcRqNtkRU/z8WlBLnvD4MRnHgNs3MytRO1Mn1sHRyhbcpYbVMGclAqOjdW+9cfkdZno9dFdfKLfQ== +"@babel/plugin-transform-modules-commonjs@^7.22.11": + version "7.22.11" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.22.11.tgz#d7991d3abad199c03b68ee66a64f216c47ffdfae" + integrity sha512-o2+bg7GDS60cJMgz9jWqRUsWkMzLCxp+jFDeDUT5sjRlAxcJWZ2ylNdI7QQ2+CH5hWu7OnN+Cv3htt7AkSf96g== dependencies: - "@babel/helper-module-transforms" "^7.18.6" - "@babel/helper-plugin-utils" "^7.18.6" + "@babel/helper-module-transforms" "^7.22.9" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-simple-access" "^7.22.5" -"@babel/plugin-transform-named-capturing-groups-regex@^7.19.1": - version "7.20.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.20.5.tgz#626298dd62ea51d452c3be58b285d23195ba69a8" - integrity sha512-mOW4tTzi5iTLnw+78iEq3gr8Aoq4WNRGpmSlrogqaiCBoR1HFhpU4JkpQFOHfeYx3ReVIFWOQJS4aZBRvuZ6mA== +"@babel/plugin-transform-modules-systemjs@^7.22.11": + version "7.22.11" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.22.11.tgz#3386be5875d316493b517207e8f1931d93154bb1" + integrity sha512-rIqHmHoMEOhI3VkVf5jQ15l539KrwhzqcBO6wdCNWPWc/JWt9ILNYNUssbRpeq0qWns8svuw8LnMNCvWBIJ8wA== dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.20.5" - "@babel/helper-plugin-utils" "^7.20.2" + "@babel/helper-hoist-variables" "^7.22.5" + "@babel/helper-module-transforms" "^7.22.9" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-validator-identifier" "^7.22.5" -"@babel/plugin-transform-new-target@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.18.6.tgz#d128f376ae200477f37c4ddfcc722a8a1b3246a8" - integrity sha512-DjwFA/9Iu3Z+vrAn+8pBUGcjhxKguSMlsFqeCKbhb9BAV756v0krzVK04CRDi/4aqmk8BsHb4a/gFcaA5joXRw== +"@babel/plugin-transform-modules-umd@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.22.5.tgz#4694ae40a87b1745e3775b6a7fe96400315d4f98" + integrity sha512-+S6kzefN/E1vkSsKx8kmQuqeQsvCKCd1fraCM7zXm4SFoggI099Tr4G8U81+5gtMdUeMQ4ipdQffbKLX0/7dBQ== dependencies: - "@babel/helper-plugin-utils" "^7.18.6" + "@babel/helper-module-transforms" "^7.22.5" + "@babel/helper-plugin-utils" "^7.22.5" -"@babel/plugin-transform-object-super@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.18.6.tgz#fb3c6ccdd15939b6ff7939944b51971ddc35912c" - integrity sha512-uvGz6zk+pZoS1aTZrOvrbj6Pp/kK2mp45t2B+bTDre2UgsZZ8EZLSJtUg7m/no0zOJUWgFONpB7Zv9W2tSaFlA== +"@babel/plugin-transform-named-capturing-groups-regex@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.22.5.tgz#67fe18ee8ce02d57c855185e27e3dc959b2e991f" + integrity sha512-YgLLKmS3aUBhHaxp5hi1WJTgOUb/NCuDHzGT9z9WTt3YG+CPRhJs6nprbStx6DnWM4dh6gt7SU3sZodbZ08adQ== dependencies: - "@babel/helper-plugin-utils" "^7.18.6" - "@babel/helper-replace-supers" "^7.18.6" + "@babel/helper-create-regexp-features-plugin" "^7.22.5" + "@babel/helper-plugin-utils" "^7.22.5" -"@babel/plugin-transform-parameters@^7.20.1": - version "7.20.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.20.5.tgz#f8f9186c681d10c3de7620c916156d893c8a019e" - integrity sha512-h7plkOmcndIUWXZFLgpbrh2+fXAi47zcUX7IrOQuZdLD0I0KvjJ6cvo3BEcAOsDOcZhVKGJqv07mkSqK0y2isQ== +"@babel/plugin-transform-new-target@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.22.5.tgz#1b248acea54ce44ea06dfd37247ba089fcf9758d" + integrity sha512-AsF7K0Fx/cNKVyk3a+DW0JLo+Ua598/NxMRvxDnkpCIGFh43+h/v2xyhRUYf6oD8gE4QtL83C7zZVghMjHd+iw== dependencies: - "@babel/helper-plugin-utils" "^7.20.2" + "@babel/helper-plugin-utils" "^7.22.5" -"@babel/plugin-transform-property-literals@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.18.6.tgz#e22498903a483448e94e032e9bbb9c5ccbfc93a3" - integrity sha512-cYcs6qlgafTud3PAzrrRNbQtfpQ8+y/+M5tKmksS9+M1ckbH6kzY8MrexEM9mcA6JDsukE19iIRvAyYl463sMg== +"@babel/plugin-transform-nullish-coalescing-operator@^7.22.11": + version "7.22.11" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.22.11.tgz#debef6c8ba795f5ac67cd861a81b744c5d38d9fc" + integrity sha512-YZWOw4HxXrotb5xsjMJUDlLgcDXSfO9eCmdl1bgW4+/lAGdkjaEvOnQ4p5WKKdUgSzO39dgPl0pTnfxm0OAXcg== dependencies: - "@babel/helper-plugin-utils" "^7.18.6" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" + +"@babel/plugin-transform-numeric-separator@^7.22.11": + version "7.22.11" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.22.11.tgz#498d77dc45a6c6db74bb829c02a01c1d719cbfbd" + integrity sha512-3dzU4QGPsILdJbASKhF/V2TVP+gJya1PsueQCxIPCEcerqF21oEcrob4mzjsp2Py/1nLfF5m+xYNMDpmA8vffg== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-syntax-numeric-separator" "^7.10.4" + +"@babel/plugin-transform-object-rest-spread@^7.22.11": + version "7.22.11" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.22.11.tgz#dbbb06ce783cd994a8f430d8cefa553e9b42ca62" + integrity sha512-nX8cPFa6+UmbepISvlf5jhQyaC7ASs/7UxHmMkuJ/k5xSHvDPPaibMo+v3TXwU/Pjqhep/nFNpd3zn4YR59pnw== + dependencies: + "@babel/compat-data" "^7.22.9" + "@babel/helper-compilation-targets" "^7.22.10" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-syntax-object-rest-spread" "^7.8.3" + "@babel/plugin-transform-parameters" "^7.22.5" + +"@babel/plugin-transform-object-super@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.22.5.tgz#794a8d2fcb5d0835af722173c1a9d704f44e218c" + integrity sha512-klXqyaT9trSjIUrcsYIfETAzmOEZL3cBYqOYLJxBHfMFFggmXOv+NYSX/Jbs9mzMVESw/WycLFPRx8ba/b2Ipw== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-replace-supers" "^7.22.5" + +"@babel/plugin-transform-optional-catch-binding@^7.22.11": + version "7.22.11" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.22.11.tgz#461cc4f578a127bb055527b3e77404cad38c08e0" + integrity sha512-rli0WxesXUeCJnMYhzAglEjLWVDF6ahb45HuprcmQuLidBJFWjNnOzssk2kuc6e33FlLaiZhG/kUIzUMWdBKaQ== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-syntax-optional-catch-binding" "^7.8.3" + +"@babel/plugin-transform-optional-chaining@^7.22.12", "@babel/plugin-transform-optional-chaining@^7.22.5": + version "7.22.12" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.22.12.tgz#d7ebf6a88cd2f4d307b0e000ab630acd8124b333" + integrity sha512-7XXCVqZtyFWqjDsYDY4T45w4mlx1rf7aOgkc/Ww76xkgBiOlmjPkx36PBLHa1k1rwWvVgYMPsbuVnIamx2ZQJw== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-skip-transparent-expression-wrappers" "^7.22.5" + "@babel/plugin-syntax-optional-chaining" "^7.8.3" + +"@babel/plugin-transform-parameters@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.22.5.tgz#c3542dd3c39b42c8069936e48717a8d179d63a18" + integrity sha512-AVkFUBurORBREOmHRKo06FjHYgjrabpdqRSwq6+C7R5iTCZOsM4QbcB27St0a4U6fffyAOqh3s/qEfybAhfivg== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-private-methods@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.22.5.tgz#21c8af791f76674420a147ae62e9935d790f8722" + integrity sha512-PPjh4gyrQnGe97JTalgRGMuU4icsZFnWkzicB/fUtzlKUqvsWBKEpPPfr5a2JiyirZkHxnAqkQMO5Z5B2kK3fA== + dependencies: + "@babel/helper-create-class-features-plugin" "^7.22.5" + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-private-property-in-object@^7.22.11": + version "7.22.11" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.22.11.tgz#ad45c4fc440e9cb84c718ed0906d96cf40f9a4e1" + integrity sha512-sSCbqZDBKHetvjSwpyWzhuHkmW5RummxJBVbYLkGkaiTOWGxml7SXt0iWa03bzxFIx7wOj3g/ILRd0RcJKBeSQ== + dependencies: + "@babel/helper-annotate-as-pure" "^7.22.5" + "@babel/helper-create-class-features-plugin" "^7.22.11" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-syntax-private-property-in-object" "^7.14.5" + +"@babel/plugin-transform-property-literals@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.22.5.tgz#b5ddabd73a4f7f26cd0e20f5db48290b88732766" + integrity sha512-TiOArgddK3mK/x1Qwf5hay2pxI6wCZnvQqrFSqbtg1GLl2JcNMitVH/YnqjP+M31pLUeTfzY1HAXFDnUBV30rQ== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" "@babel/plugin-transform-react-constant-elements@^7.12.1": - version "7.20.2" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-constant-elements/-/plugin-transform-react-constant-elements-7.20.2.tgz#3f02c784e0b711970d7d8ccc96c4359d64e27ac7" - integrity sha512-KS/G8YI8uwMGKErLFOHS/ekhqdHhpEloxs43NecQHVgo2QuQSyJhGIY1fL8UGl9wy5ItVwwoUL4YxVqsplGq2g== + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-constant-elements/-/plugin-transform-react-constant-elements-7.22.5.tgz#6dfa7c1c37f7d7279e417ceddf5a04abb8bb9c29" + integrity sha512-BF5SXoO+nX3h5OhlN78XbbDrBOffv+AxPP2ENaJOVqjWCgBDeOY3WcaUcddutGSfoap+5NEQ/q/4I3WZIvgkXA== dependencies: - "@babel/helper-plugin-utils" "^7.20.2" + "@babel/helper-plugin-utils" "^7.22.5" -"@babel/plugin-transform-react-display-name@^7.16.0", "@babel/plugin-transform-react-display-name@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.18.6.tgz#8b1125f919ef36ebdfff061d664e266c666b9415" - integrity sha512-TV4sQ+T013n61uMoygyMRm+xf04Bd5oqFpv2jAEQwSZ8NwQA7zeRPg1LMVg2PWi3zWBz+CLKD+v5bcpZ/BS0aA== +"@babel/plugin-transform-react-display-name@^7.16.0", "@babel/plugin-transform-react-display-name@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.22.5.tgz#3c4326f9fce31c7968d6cb9debcaf32d9e279a2b" + integrity sha512-PVk3WPYudRF5z4GKMEYUrLjPl38fJSKNaEOkFuoprioowGuWN6w2RKznuFNSlJx7pzzXXStPUnNSOEO0jL5EVw== dependencies: - "@babel/helper-plugin-utils" "^7.18.6" + "@babel/helper-plugin-utils" "^7.22.5" -"@babel/plugin-transform-react-jsx-development@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.18.6.tgz#dbe5c972811e49c7405b630e4d0d2e1380c0ddc5" - integrity sha512-SA6HEjwYFKF7WDjWcMcMGUimmw/nhNRDWxr+KaLSCrkD/LMDBvWRmHAYgE1HDeF8KUuI8OAu+RT6EOtKxSW2qA== +"@babel/plugin-transform-react-jsx-development@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.22.5.tgz#e716b6edbef972a92165cd69d92f1255f7e73e87" + integrity sha512-bDhuzwWMuInwCYeDeMzyi7TaBgRQei6DqxhbyniL7/VG4RSS7HtSL2QbY4eESy1KJqlWt8g3xeEBGPuo+XqC8A== dependencies: - "@babel/plugin-transform-react-jsx" "^7.18.6" + "@babel/plugin-transform-react-jsx" "^7.22.5" -"@babel/plugin-transform-react-jsx@^7.18.6", "@babel/plugin-transform-react-jsx@^7.19.0": - version "7.19.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.19.0.tgz#b3cbb7c3a00b92ec8ae1027910e331ba5c500eb9" - integrity sha512-UVEvX3tXie3Szm3emi1+G63jyw1w5IcMY0FSKM+CRnKRI5Mr1YbCNgsSTwoTwKphQEG9P+QqmuRFneJPZuHNhg== +"@babel/plugin-transform-react-jsx@^7.19.0", "@babel/plugin-transform-react-jsx@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.22.5.tgz#932c291eb6dd1153359e2a90cb5e557dcf068416" + integrity sha512-rog5gZaVbUip5iWDMTYbVM15XQq+RkUKhET/IHR6oizR+JEoN6CAfTTuHcK4vwUyzca30qqHqEpzBOnaRMWYMA== dependencies: - "@babel/helper-annotate-as-pure" "^7.18.6" - "@babel/helper-module-imports" "^7.18.6" - "@babel/helper-plugin-utils" "^7.19.0" - "@babel/plugin-syntax-jsx" "^7.18.6" - "@babel/types" "^7.19.0" + "@babel/helper-annotate-as-pure" "^7.22.5" + "@babel/helper-module-imports" "^7.22.5" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-syntax-jsx" "^7.22.5" + "@babel/types" "^7.22.5" -"@babel/plugin-transform-react-pure-annotations@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.18.6.tgz#561af267f19f3e5d59291f9950fd7b9663d0d844" - integrity sha512-I8VfEPg9r2TRDdvnHgPepTKvuRomzA8+u+nhY7qSI1fR2hRNebasZEETLyM5mAUr0Ku56OkXJ0I7NHJnO6cJiQ== +"@babel/plugin-transform-react-pure-annotations@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.22.5.tgz#1f58363eef6626d6fa517b95ac66fe94685e32c0" + integrity sha512-gP4k85wx09q+brArVinTXhWiyzLl9UpmGva0+mWyKxk6JZequ05x3eUcIUE+FyttPKJFRRVtAvQaJ6YF9h1ZpA== dependencies: - "@babel/helper-annotate-as-pure" "^7.18.6" - "@babel/helper-plugin-utils" "^7.18.6" + "@babel/helper-annotate-as-pure" "^7.22.5" + "@babel/helper-plugin-utils" "^7.22.5" -"@babel/plugin-transform-regenerator@^7.18.6": - version "7.20.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.20.5.tgz#57cda588c7ffb7f4f8483cc83bdcea02a907f04d" - integrity sha512-kW/oO7HPBtntbsahzQ0qSE3tFvkFwnbozz3NWFhLGqH75vLEg+sCGngLlhVkePlCs3Jv0dBBHDzCHxNiFAQKCQ== +"@babel/plugin-transform-regenerator@^7.22.10": + version "7.22.10" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.22.10.tgz#8ceef3bd7375c4db7652878b0241b2be5d0c3cca" + integrity sha512-F28b1mDt8KcT5bUyJc/U9nwzw6cV+UmTeRlXYIl2TNqMMJif0Jeey9/RQ3C4NOd2zp0/TRsDns9ttj2L523rsw== dependencies: - "@babel/helper-plugin-utils" "^7.20.2" - regenerator-transform "^0.15.1" + "@babel/helper-plugin-utils" "^7.22.5" + regenerator-transform "^0.15.2" -"@babel/plugin-transform-reserved-words@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.18.6.tgz#b1abd8ebf8edaa5f7fe6bbb8d2133d23b6a6f76a" - integrity sha512-oX/4MyMoypzHjFrT1CdivfKZ+XvIPMFXwwxHp/r0Ddy2Vuomt4HDFGmft1TAY2yiTKiNSsh3kjBAzcM8kSdsjA== +"@babel/plugin-transform-reserved-words@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.22.5.tgz#832cd35b81c287c4bcd09ce03e22199641f964fb" + integrity sha512-DTtGKFRQUDm8svigJzZHzb/2xatPc6TzNvAIJ5GqOKDsGFYgAskjRulbR/vGsPKq3OPqtexnz327qYpP57RFyA== dependencies: - "@babel/helper-plugin-utils" "^7.18.6" + "@babel/helper-plugin-utils" "^7.22.5" "@babel/plugin-transform-runtime@^7.16.4": - version "7.19.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.19.6.tgz#9d2a9dbf4e12644d6f46e5e75bfbf02b5d6e9194" - integrity sha512-PRH37lz4JU156lYFW1p8OxE5i7d6Sl/zV58ooyr+q1J1lnQPyg5tIiXlIwNVhJaY4W3TmOtdc8jqdXQcB1v5Yw== - dependencies: - "@babel/helper-module-imports" "^7.18.6" - "@babel/helper-plugin-utils" "^7.19.0" - babel-plugin-polyfill-corejs2 "^0.3.3" - babel-plugin-polyfill-corejs3 "^0.6.0" - babel-plugin-polyfill-regenerator "^0.4.1" - semver "^6.3.0" + version "7.22.10" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.22.10.tgz#89eda6daf1d3af6f36fb368766553054c8d7cd46" + integrity sha512-RchI7HePu1eu0CYNKHHHQdfenZcM4nz8rew5B1VWqeRKdcwW5aQ5HeG9eTUbWiAS1UrmHVLmoxTWHt3iLD/NhA== + dependencies: + "@babel/helper-module-imports" "^7.22.5" + "@babel/helper-plugin-utils" "^7.22.5" + babel-plugin-polyfill-corejs2 "^0.4.5" + babel-plugin-polyfill-corejs3 "^0.8.3" + babel-plugin-polyfill-regenerator "^0.5.2" + semver "^6.3.1" + +"@babel/plugin-transform-shorthand-properties@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.22.5.tgz#6e277654be82b5559fc4b9f58088507c24f0c624" + integrity sha512-vM4fq9IXHscXVKzDv5itkO1X52SmdFBFcMIBZ2FRn2nqVYqw6dBexUgMvAjHW+KXpPPViD/Yo3GrDEBaRC0QYA== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" -"@babel/plugin-transform-shorthand-properties@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.18.6.tgz#6d6df7983d67b195289be24909e3f12a8f664dc9" - integrity sha512-eCLXXJqv8okzg86ywZJbRn19YJHU4XUa55oz2wbHhaQVn/MM+XhukiT7SYqp/7o00dg52Rj51Ny+Ecw4oyoygw== +"@babel/plugin-transform-spread@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.22.5.tgz#6487fd29f229c95e284ba6c98d65eafb893fea6b" + integrity sha512-5ZzDQIGyvN4w8+dMmpohL6MBo+l2G7tfC/O2Dg7/hjpgeWvUx8FzfeOKxGog9IimPa4YekaQ9PlDqTLOljkcxg== dependencies: - "@babel/helper-plugin-utils" "^7.18.6" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-skip-transparent-expression-wrappers" "^7.22.5" -"@babel/plugin-transform-spread@^7.19.0": - version "7.19.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.19.0.tgz#dd60b4620c2fec806d60cfaae364ec2188d593b6" - integrity sha512-RsuMk7j6n+r752EtzyScnWkQyuJdli6LdO5Klv8Yx0OfPVTcQkIUfS8clx5e9yHXzlnhOZF3CbQ8C2uP5j074w== +"@babel/plugin-transform-sticky-regex@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.22.5.tgz#295aba1595bfc8197abd02eae5fc288c0deb26aa" + integrity sha512-zf7LuNpHG0iEeiyCNwX4j3gDg1jgt1k3ZdXBKbZSoA3BbGQGvMiSvfbZRR3Dr3aeJe3ooWFZxOOG3IRStYp2Bw== dependencies: - "@babel/helper-plugin-utils" "^7.19.0" - "@babel/helper-skip-transparent-expression-wrappers" "^7.18.9" + "@babel/helper-plugin-utils" "^7.22.5" -"@babel/plugin-transform-sticky-regex@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.18.6.tgz#c6706eb2b1524028e317720339583ad0f444adcc" - integrity sha512-kfiDrDQ+PBsQDO85yj1icueWMfGfJFKN1KCkndygtu/C9+XUfydLC8Iv5UYJqRwy4zk8EcplRxEOeLyjq1gm6Q== +"@babel/plugin-transform-template-literals@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.22.5.tgz#8f38cf291e5f7a8e60e9f733193f0bcc10909bff" + integrity sha512-5ciOehRNf+EyUeewo8NkbQiUs4d6ZxiHo6BcBcnFlgiJfu16q0bQUw9Jvo0b0gBKFG1SMhDSjeKXSYuJLeFSMA== dependencies: - "@babel/helper-plugin-utils" "^7.18.6" + "@babel/helper-plugin-utils" "^7.22.5" -"@babel/plugin-transform-template-literals@^7.18.9": - version "7.18.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.18.9.tgz#04ec6f10acdaa81846689d63fae117dd9c243a5e" - integrity sha512-S8cOWfT82gTezpYOiVaGHrCbhlHgKhQt8XH5ES46P2XWmX92yisoZywf5km75wv5sYcXDUCLMmMxOLCtthDgMA== +"@babel/plugin-transform-typeof-symbol@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.22.5.tgz#5e2ba478da4b603af8673ff7c54f75a97b716b34" + integrity sha512-bYkI5lMzL4kPii4HHEEChkD0rkc+nvnlR6+o/qdqR6zrm0Sv/nodmyLhlq2DO0YKLUNd2VePmPRjJXSBh9OIdA== dependencies: - "@babel/helper-plugin-utils" "^7.18.9" + "@babel/helper-plugin-utils" "^7.22.5" -"@babel/plugin-transform-typeof-symbol@^7.18.9": - version "7.18.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.18.9.tgz#c8cea68263e45addcd6afc9091429f80925762c0" - integrity sha512-SRfwTtF11G2aemAZWivL7PD+C9z52v9EvMqH9BuYbabyPuKUvSWks3oCg6041pT925L4zVFqaVBeECwsmlguEw== +"@babel/plugin-transform-typescript@^7.22.11": + version "7.22.11" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.22.11.tgz#9f27fb5e51585729374bb767ab6a6d9005a23329" + integrity sha512-0E4/L+7gfvHub7wsbTv03oRtD69X31LByy44fGmFzbZScpupFByMcgCJ0VbBTkzyjSJKuRoGN8tcijOWKTmqOA== dependencies: - "@babel/helper-plugin-utils" "^7.18.9" + "@babel/helper-annotate-as-pure" "^7.22.5" + "@babel/helper-create-class-features-plugin" "^7.22.11" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-syntax-typescript" "^7.22.5" -"@babel/plugin-transform-typescript@^7.18.6": - version "7.20.2" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.20.2.tgz#91515527b376fc122ba83b13d70b01af8fe98f3f" - integrity sha512-jvS+ngBfrnTUBfOQq8NfGnSbF9BrqlR6hjJ2yVxMkmO5nL/cdifNbI30EfjRlN4g5wYWNnMPyj5Sa6R1pbLeag== +"@babel/plugin-transform-unicode-escapes@^7.22.10": + version "7.22.10" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.22.10.tgz#c723f380f40a2b2f57a62df24c9005834c8616d9" + integrity sha512-lRfaRKGZCBqDlRU3UIFovdp9c9mEvlylmpod0/OatICsSfuQ9YFthRo1tpTkGsklEefZdqlEFdY4A2dwTb6ohg== dependencies: - "@babel/helper-create-class-features-plugin" "^7.20.2" - "@babel/helper-plugin-utils" "^7.20.2" - "@babel/plugin-syntax-typescript" "^7.20.0" + "@babel/helper-plugin-utils" "^7.22.5" -"@babel/plugin-transform-unicode-escapes@^7.18.10": - version "7.18.10" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.18.10.tgz#1ecfb0eda83d09bbcb77c09970c2dd55832aa246" - integrity sha512-kKAdAI+YzPgGY/ftStBFXTI1LZFju38rYThnfMykS+IXy8BVx+res7s2fxf1l8I35DV2T97ezo6+SGrXz6B3iQ== +"@babel/plugin-transform-unicode-property-regex@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.22.5.tgz#098898f74d5c1e86660dc112057b2d11227f1c81" + integrity sha512-HCCIb+CbJIAE6sXn5CjFQXMwkCClcOfPCzTlilJ8cUatfzwHlWQkbtV0zD338u9dZskwvuOYTuuaMaA8J5EI5A== dependencies: - "@babel/helper-plugin-utils" "^7.18.9" + "@babel/helper-create-regexp-features-plugin" "^7.22.5" + "@babel/helper-plugin-utils" "^7.22.5" -"@babel/plugin-transform-unicode-regex@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.18.6.tgz#194317225d8c201bbae103364ffe9e2cea36cdca" - integrity sha512-gE7A6Lt7YLnNOL3Pb9BNeZvi+d8l7tcRrG4+pwJjK9hD2xX4mEvjlQW60G9EEmfXVYRPv9VRQcyegIVHCql/AA== +"@babel/plugin-transform-unicode-regex@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.22.5.tgz#ce7e7bb3ef208c4ff67e02a22816656256d7a183" + integrity sha512-028laaOKptN5vHJf9/Arr/HiJekMd41hOEZYvNsrsXqJ7YPYuX2bQxh31fkZzGmq3YqHRJzYFFAVYvKfMPKqyg== dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.18.6" - "@babel/helper-plugin-utils" "^7.18.6" + "@babel/helper-create-regexp-features-plugin" "^7.22.5" + "@babel/helper-plugin-utils" "^7.22.5" -"@babel/preset-env@^7.11.0", "@babel/preset-env@^7.12.1", "@babel/preset-env@^7.16.4": - version "7.20.2" - resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.20.2.tgz#9b1642aa47bb9f43a86f9630011780dab7f86506" - integrity sha512-1G0efQEWR1EHkKvKHqbG+IN/QdgwfByUpM5V5QroDzGV2t3S/WXNQd693cHiHTlCFMpr9B6FkPFXDA2lQcKoDg== +"@babel/plugin-transform-unicode-sets-regex@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.22.5.tgz#77788060e511b708ffc7d42fdfbc5b37c3004e91" + integrity sha512-lhMfi4FC15j13eKrh3DnYHjpGj6UKQHtNKTbtc1igvAhRy4+kLhV07OpLcsN0VgDEw/MjAvJO4BdMJsHwMhzCg== dependencies: - "@babel/compat-data" "^7.20.1" - "@babel/helper-compilation-targets" "^7.20.0" - "@babel/helper-plugin-utils" "^7.20.2" - "@babel/helper-validator-option" "^7.18.6" - "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression" "^7.18.6" - "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining" "^7.18.9" - "@babel/plugin-proposal-async-generator-functions" "^7.20.1" - "@babel/plugin-proposal-class-properties" "^7.18.6" - "@babel/plugin-proposal-class-static-block" "^7.18.6" - "@babel/plugin-proposal-dynamic-import" "^7.18.6" - "@babel/plugin-proposal-export-namespace-from" "^7.18.9" - "@babel/plugin-proposal-json-strings" "^7.18.6" - "@babel/plugin-proposal-logical-assignment-operators" "^7.18.9" - "@babel/plugin-proposal-nullish-coalescing-operator" "^7.18.6" - "@babel/plugin-proposal-numeric-separator" "^7.18.6" - "@babel/plugin-proposal-object-rest-spread" "^7.20.2" - "@babel/plugin-proposal-optional-catch-binding" "^7.18.6" - "@babel/plugin-proposal-optional-chaining" "^7.18.9" - "@babel/plugin-proposal-private-methods" "^7.18.6" - "@babel/plugin-proposal-private-property-in-object" "^7.18.6" - "@babel/plugin-proposal-unicode-property-regex" "^7.18.6" + "@babel/helper-create-regexp-features-plugin" "^7.22.5" + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/preset-env@^7.11.0", "@babel/preset-env@^7.12.1", "@babel/preset-env@^7.16.4": + version "7.22.14" + resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.22.14.tgz#1cbb468d899f64fa71c53446f13b7ff8c0005cc1" + integrity sha512-daodMIoVo+ol/g+//c/AH+szBkFj4STQUikvBijRGL72Ph+w+AMTSh55DUETe8KJlPlDT1k/mp7NBfOuiWmoig== + dependencies: + "@babel/compat-data" "^7.22.9" + "@babel/helper-compilation-targets" "^7.22.10" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-validator-option" "^7.22.5" + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression" "^7.22.5" + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining" "^7.22.5" + "@babel/plugin-proposal-private-property-in-object" "7.21.0-placeholder-for-preset-env.2" "@babel/plugin-syntax-async-generators" "^7.8.4" "@babel/plugin-syntax-class-properties" "^7.12.13" "@babel/plugin-syntax-class-static-block" "^7.14.5" "@babel/plugin-syntax-dynamic-import" "^7.8.3" "@babel/plugin-syntax-export-namespace-from" "^7.8.3" - "@babel/plugin-syntax-import-assertions" "^7.20.0" + "@babel/plugin-syntax-import-assertions" "^7.22.5" + "@babel/plugin-syntax-import-attributes" "^7.22.5" + "@babel/plugin-syntax-import-meta" "^7.10.4" "@babel/plugin-syntax-json-strings" "^7.8.3" "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4" "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" @@ -948,139 +1017,139 @@ "@babel/plugin-syntax-optional-chaining" "^7.8.3" "@babel/plugin-syntax-private-property-in-object" "^7.14.5" "@babel/plugin-syntax-top-level-await" "^7.14.5" - "@babel/plugin-transform-arrow-functions" "^7.18.6" - "@babel/plugin-transform-async-to-generator" "^7.18.6" - "@babel/plugin-transform-block-scoped-functions" "^7.18.6" - "@babel/plugin-transform-block-scoping" "^7.20.2" - "@babel/plugin-transform-classes" "^7.20.2" - "@babel/plugin-transform-computed-properties" "^7.18.9" - "@babel/plugin-transform-destructuring" "^7.20.2" - "@babel/plugin-transform-dotall-regex" "^7.18.6" - "@babel/plugin-transform-duplicate-keys" "^7.18.9" - "@babel/plugin-transform-exponentiation-operator" "^7.18.6" - "@babel/plugin-transform-for-of" "^7.18.8" - "@babel/plugin-transform-function-name" "^7.18.9" - "@babel/plugin-transform-literals" "^7.18.9" - "@babel/plugin-transform-member-expression-literals" "^7.18.6" - "@babel/plugin-transform-modules-amd" "^7.19.6" - "@babel/plugin-transform-modules-commonjs" "^7.19.6" - "@babel/plugin-transform-modules-systemjs" "^7.19.6" - "@babel/plugin-transform-modules-umd" "^7.18.6" - "@babel/plugin-transform-named-capturing-groups-regex" "^7.19.1" - "@babel/plugin-transform-new-target" "^7.18.6" - "@babel/plugin-transform-object-super" "^7.18.6" - "@babel/plugin-transform-parameters" "^7.20.1" - "@babel/plugin-transform-property-literals" "^7.18.6" - "@babel/plugin-transform-regenerator" "^7.18.6" - "@babel/plugin-transform-reserved-words" "^7.18.6" - "@babel/plugin-transform-shorthand-properties" "^7.18.6" - "@babel/plugin-transform-spread" "^7.19.0" - "@babel/plugin-transform-sticky-regex" "^7.18.6" - "@babel/plugin-transform-template-literals" "^7.18.9" - "@babel/plugin-transform-typeof-symbol" "^7.18.9" - "@babel/plugin-transform-unicode-escapes" "^7.18.10" - "@babel/plugin-transform-unicode-regex" "^7.18.6" - "@babel/preset-modules" "^0.1.5" - "@babel/types" "^7.20.2" - babel-plugin-polyfill-corejs2 "^0.3.3" - babel-plugin-polyfill-corejs3 "^0.6.0" - babel-plugin-polyfill-regenerator "^0.4.1" - core-js-compat "^3.25.1" - semver "^6.3.0" - -"@babel/preset-modules@^0.1.5": - version "0.1.5" - resolved "https://registry.yarnpkg.com/@babel/preset-modules/-/preset-modules-0.1.5.tgz#ef939d6e7f268827e1841638dc6ff95515e115d9" - integrity sha512-A57th6YRG7oR3cq/yt/Y84MvGgE0eJG2F1JLhKuyG+jFxEgrd/HAMJatiFtmOiZurz+0DkrvbheCLaV5f2JfjA== + "@babel/plugin-syntax-unicode-sets-regex" "^7.18.6" + "@babel/plugin-transform-arrow-functions" "^7.22.5" + "@babel/plugin-transform-async-generator-functions" "^7.22.11" + "@babel/plugin-transform-async-to-generator" "^7.22.5" + "@babel/plugin-transform-block-scoped-functions" "^7.22.5" + "@babel/plugin-transform-block-scoping" "^7.22.10" + "@babel/plugin-transform-class-properties" "^7.22.5" + "@babel/plugin-transform-class-static-block" "^7.22.11" + "@babel/plugin-transform-classes" "^7.22.6" + "@babel/plugin-transform-computed-properties" "^7.22.5" + "@babel/plugin-transform-destructuring" "^7.22.10" + "@babel/plugin-transform-dotall-regex" "^7.22.5" + "@babel/plugin-transform-duplicate-keys" "^7.22.5" + "@babel/plugin-transform-dynamic-import" "^7.22.11" + "@babel/plugin-transform-exponentiation-operator" "^7.22.5" + "@babel/plugin-transform-export-namespace-from" "^7.22.11" + "@babel/plugin-transform-for-of" "^7.22.5" + "@babel/plugin-transform-function-name" "^7.22.5" + "@babel/plugin-transform-json-strings" "^7.22.11" + "@babel/plugin-transform-literals" "^7.22.5" + "@babel/plugin-transform-logical-assignment-operators" "^7.22.11" + "@babel/plugin-transform-member-expression-literals" "^7.22.5" + "@babel/plugin-transform-modules-amd" "^7.22.5" + "@babel/plugin-transform-modules-commonjs" "^7.22.11" + "@babel/plugin-transform-modules-systemjs" "^7.22.11" + "@babel/plugin-transform-modules-umd" "^7.22.5" + "@babel/plugin-transform-named-capturing-groups-regex" "^7.22.5" + "@babel/plugin-transform-new-target" "^7.22.5" + "@babel/plugin-transform-nullish-coalescing-operator" "^7.22.11" + "@babel/plugin-transform-numeric-separator" "^7.22.11" + "@babel/plugin-transform-object-rest-spread" "^7.22.11" + "@babel/plugin-transform-object-super" "^7.22.5" + "@babel/plugin-transform-optional-catch-binding" "^7.22.11" + "@babel/plugin-transform-optional-chaining" "^7.22.12" + "@babel/plugin-transform-parameters" "^7.22.5" + "@babel/plugin-transform-private-methods" "^7.22.5" + "@babel/plugin-transform-private-property-in-object" "^7.22.11" + "@babel/plugin-transform-property-literals" "^7.22.5" + "@babel/plugin-transform-regenerator" "^7.22.10" + "@babel/plugin-transform-reserved-words" "^7.22.5" + "@babel/plugin-transform-shorthand-properties" "^7.22.5" + "@babel/plugin-transform-spread" "^7.22.5" + "@babel/plugin-transform-sticky-regex" "^7.22.5" + "@babel/plugin-transform-template-literals" "^7.22.5" + "@babel/plugin-transform-typeof-symbol" "^7.22.5" + "@babel/plugin-transform-unicode-escapes" "^7.22.10" + "@babel/plugin-transform-unicode-property-regex" "^7.22.5" + "@babel/plugin-transform-unicode-regex" "^7.22.5" + "@babel/plugin-transform-unicode-sets-regex" "^7.22.5" + "@babel/preset-modules" "0.1.6-no-external-plugins" + "@babel/types" "^7.22.11" + babel-plugin-polyfill-corejs2 "^0.4.5" + babel-plugin-polyfill-corejs3 "^0.8.3" + babel-plugin-polyfill-regenerator "^0.5.2" + core-js-compat "^3.31.0" + semver "^6.3.1" + +"@babel/preset-modules@0.1.6-no-external-plugins": + version "0.1.6-no-external-plugins" + resolved "https://registry.yarnpkg.com/@babel/preset-modules/-/preset-modules-0.1.6-no-external-plugins.tgz#ccb88a2c49c817236861fee7826080573b8a923a" + integrity sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA== dependencies: "@babel/helper-plugin-utils" "^7.0.0" - "@babel/plugin-proposal-unicode-property-regex" "^7.4.4" - "@babel/plugin-transform-dotall-regex" "^7.4.4" "@babel/types" "^7.4.4" esutils "^2.0.2" "@babel/preset-react@^7.12.5", "@babel/preset-react@^7.16.0": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/preset-react/-/preset-react-7.18.6.tgz#979f76d6277048dc19094c217b507f3ad517dd2d" - integrity sha512-zXr6atUmyYdiWRVLOZahakYmOBHtWc2WGCkP8PYTgZi0iJXDY2CN180TdrIW4OGOAdLc7TifzDIvtx6izaRIzg== + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/preset-react/-/preset-react-7.22.5.tgz#c4d6058fbf80bccad02dd8c313a9aaa67e3c3dd6" + integrity sha512-M+Is3WikOpEJHgR385HbuCITPTaPRaNkibTEa9oiofmJvIsrceb4yp9RL9Kb+TE8LznmeyZqpP+Lopwcx59xPQ== dependencies: - "@babel/helper-plugin-utils" "^7.18.6" - "@babel/helper-validator-option" "^7.18.6" - "@babel/plugin-transform-react-display-name" "^7.18.6" - "@babel/plugin-transform-react-jsx" "^7.18.6" - "@babel/plugin-transform-react-jsx-development" "^7.18.6" - "@babel/plugin-transform-react-pure-annotations" "^7.18.6" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-validator-option" "^7.22.5" + "@babel/plugin-transform-react-display-name" "^7.22.5" + "@babel/plugin-transform-react-jsx" "^7.22.5" + "@babel/plugin-transform-react-jsx-development" "^7.22.5" + "@babel/plugin-transform-react-pure-annotations" "^7.22.5" "@babel/preset-typescript@^7.16.0": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/preset-typescript/-/preset-typescript-7.18.6.tgz#ce64be3e63eddc44240c6358daefac17b3186399" - integrity sha512-s9ik86kXBAnD760aybBucdpnLsAt0jK1xqJn2juOn9lkOvSHV60os5hxoVJsPzMQxvnUJFAlkont2DvvaYEBtQ== + version "7.22.11" + resolved "https://registry.yarnpkg.com/@babel/preset-typescript/-/preset-typescript-7.22.11.tgz#f218cd0345524ac888aa3dc32f029de5b064b575" + integrity sha512-tWY5wyCZYBGY7IlalfKI1rLiGlIfnwsRHZqlky0HVv8qviwQ1Uo/05M6+s+TcTCVa6Bmoo2uJW5TMFX6Wa4qVg== dependencies: - "@babel/helper-plugin-utils" "^7.18.6" - "@babel/helper-validator-option" "^7.18.6" - "@babel/plugin-transform-typescript" "^7.18.6" - -"@babel/runtime-corejs3@^7.10.2": - version "7.20.6" - resolved "https://registry.yarnpkg.com/@babel/runtime-corejs3/-/runtime-corejs3-7.20.6.tgz#63dae945963539ab0ad578efbf3eff271e7067ae" - integrity sha512-tqeujPiuEfcH067mx+7otTQWROVMKHXEaOQcAeNV5dDdbPWvPcFA8/W9LXw2NfjNmOetqLl03dfnG2WALPlsRQ== - dependencies: - core-js-pure "^3.25.1" - regenerator-runtime "^0.13.11" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-validator-option" "^7.22.5" + "@babel/plugin-syntax-jsx" "^7.22.5" + "@babel/plugin-transform-modules-commonjs" "^7.22.11" + "@babel/plugin-transform-typescript" "^7.22.11" -"@babel/runtime@^7.10.2", "@babel/runtime@^7.11.2", "@babel/runtime@^7.12.5", "@babel/runtime@^7.16.3", "@babel/runtime@^7.18.3", "@babel/runtime@^7.18.9", "@babel/runtime@^7.20.6", "@babel/runtime@^7.3.1", "@babel/runtime@^7.4.4", "@babel/runtime@^7.5.5", "@babel/runtime@^7.8.3", "@babel/runtime@^7.8.4", "@babel/runtime@^7.8.7": - version "7.20.6" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.20.6.tgz#facf4879bfed9b5326326273a64220f099b0fce3" - integrity sha512-Q+8MqP7TiHMWzSfwiJwXCjyf4GYA4Dgw3emg/7xmwsdLJOZUp+nMqcOwOzzYheuM1rhDu8FSj2l0aoMygEuXuA== - dependencies: - regenerator-runtime "^0.13.11" +"@babel/regjsgen@^0.8.0": + version "0.8.0" + resolved "https://registry.yarnpkg.com/@babel/regjsgen/-/regjsgen-0.8.0.tgz#f0ba69b075e1f05fb2825b7fad991e7adbb18310" + integrity sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA== -"@babel/runtime@^7.18.6", "@babel/runtime@^7.20.13", "@babel/runtime@^7.21.0": - version "7.21.5" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.21.5.tgz#8492dddda9644ae3bda3b45eabe87382caee7200" - integrity sha512-8jI69toZqqcsnqGGqwGS4Qb1VwLOEp4hz+CXPywcvjs60u3B4Pom/U/7rm4W8tMOYEB+E9wgD0mW1l3r8qlI9Q== +"@babel/runtime@^7.11.2", "@babel/runtime@^7.12.5", "@babel/runtime@^7.16.3", "@babel/runtime@^7.18.3", "@babel/runtime@^7.18.6", "@babel/runtime@^7.18.9", "@babel/runtime@^7.20.13", "@babel/runtime@^7.20.7", "@babel/runtime@^7.21.0", "@babel/runtime@^7.22.10", "@babel/runtime@^7.22.11", "@babel/runtime@^7.3.1", "@babel/runtime@^7.4.4", "@babel/runtime@^7.5.5", "@babel/runtime@^7.8.3", "@babel/runtime@^7.8.4", "@babel/runtime@^7.8.7": + version "7.22.11" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.22.11.tgz#7a9ba3bbe406ad6f9e8dd4da2ece453eb23a77a4" + integrity sha512-ee7jVNlWN09+KftVOu9n7S8gQzD/Z6hN/I8VBRXW4P1+Xe7kJGXMwu8vds4aGIMHZnNbdpSWCfZZtinytpcAvA== dependencies: - regenerator-runtime "^0.13.11" + regenerator-runtime "^0.14.0" -"@babel/runtime@^7.22.5": +"@babel/template@^7.22.5", "@babel/template@^7.3.3": version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.22.5.tgz#8564dd588182ce0047d55d7a75e93921107b57ec" - integrity sha512-ecjvYlnAaZ/KVneE/OdKYBYfgXV3Ptu6zQWmgEF7vwKhQnvVS6bjMD2XYgj+SNvQ1GfK/pjgokfPkC/2CO8CuA== - dependencies: - regenerator-runtime "^0.13.11" - -"@babel/template@^7.18.10", "@babel/template@^7.3.3": - version "7.18.10" - resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.18.10.tgz#6f9134835970d1dbf0835c0d100c9f38de0c5e71" - integrity sha512-TI+rCtooWHr3QJ27kJxfjutghu44DLnasDMwpDqCXVTal9RLp3RSYNh4NdBrRP2cQAoG9A8juOQl6P6oZG4JxA== - dependencies: - "@babel/code-frame" "^7.18.6" - "@babel/parser" "^7.18.10" - "@babel/types" "^7.18.10" - -"@babel/traverse@^7.19.1", "@babel/traverse@^7.20.1", "@babel/traverse@^7.20.5", "@babel/traverse@^7.7.2": - version "7.20.5" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.20.5.tgz#78eb244bea8270fdda1ef9af22a5d5e5b7e57133" - integrity sha512-WM5ZNN3JITQIq9tFZaw1ojLU3WgWdtkxnhM1AegMS+PvHjkM5IXjmYEGY7yukz5XS4sJyEf2VzWjI8uAavhxBQ== - dependencies: - "@babel/code-frame" "^7.18.6" - "@babel/generator" "^7.20.5" - "@babel/helper-environment-visitor" "^7.18.9" - "@babel/helper-function-name" "^7.19.0" - "@babel/helper-hoist-variables" "^7.18.6" - "@babel/helper-split-export-declaration" "^7.18.6" - "@babel/parser" "^7.20.5" - "@babel/types" "^7.20.5" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.22.5.tgz#0c8c4d944509875849bd0344ff0050756eefc6ec" + integrity sha512-X7yV7eiwAxdj9k94NEylvbVHLiVG1nvzCV2EAowhxLTwODV1jl9UzZ48leOC0sH7OnuHrIkllaBgneUykIcZaw== + dependencies: + "@babel/code-frame" "^7.22.5" + "@babel/parser" "^7.22.5" + "@babel/types" "^7.22.5" + +"@babel/traverse@^7.22.11", "@babel/traverse@^7.7.2": + version "7.22.11" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.22.11.tgz#71ebb3af7a05ff97280b83f05f8865ac94b2027c" + integrity sha512-mzAenteTfomcB7mfPtyi+4oe5BZ6MXxWcn4CX+h4IRJ+OOGXBrWU6jDQavkQI9Vuc5P+donFabBfFCcmWka9lQ== + dependencies: + "@babel/code-frame" "^7.22.10" + "@babel/generator" "^7.22.10" + "@babel/helper-environment-visitor" "^7.22.5" + "@babel/helper-function-name" "^7.22.5" + "@babel/helper-hoist-variables" "^7.22.5" + "@babel/helper-split-export-declaration" "^7.22.6" + "@babel/parser" "^7.22.11" + "@babel/types" "^7.22.11" debug "^4.1.0" globals "^11.1.0" -"@babel/types@^7.0.0", "@babel/types@^7.12.6", "@babel/types@^7.18.10", "@babel/types@^7.18.6", "@babel/types@^7.18.9", "@babel/types@^7.19.0", "@babel/types@^7.20.0", "@babel/types@^7.20.2", "@babel/types@^7.20.5", "@babel/types@^7.3.0", "@babel/types@^7.3.3", "@babel/types@^7.4.4": - version "7.20.5" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.20.5.tgz#e206ae370b5393d94dfd1d04cd687cace53efa84" - integrity sha512-c9fst/h2/dcF7H+MJKZ2T0KjEQ8hY/BNnDk/H3XY8C4Aw/eWQXWn/lWntHF9ooUBnGmEvbfGrTgLWc+um0YDUg== +"@babel/types@^7.0.0", "@babel/types@^7.12.6", "@babel/types@^7.20.7", "@babel/types@^7.22.10", "@babel/types@^7.22.11", "@babel/types@^7.22.5", "@babel/types@^7.3.3", "@babel/types@^7.4.4": + version "7.22.11" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.22.11.tgz#0e65a6a1d4d9cbaa892b2213f6159485fe632ea2" + integrity sha512-siazHiGuZRz9aB9NpHy9GOs9xiQPKnMzgdr493iI1M67vRXpnEq8ZOOKzezC5q7zwuQ6sDhdSp4SD9ixKSqKZg== dependencies: - "@babel/helper-string-parser" "^7.19.4" - "@babel/helper-validator-identifier" "^7.19.1" + "@babel/helper-string-parser" "^7.22.5" + "@babel/helper-validator-identifier" "^7.22.5" to-fast-properties "^2.0.0" "@bcoe/v8-coverage@^0.2.3": @@ -1195,9 +1264,9 @@ integrity sha512-c8J4roPBILnelAsdLr4XOAR/GsTm0GJi4XpcfvoWk3U6KiTCqiFYc63KhRMQQX35jYMp4Ao8Ij9+IZRgMfJp1g== "@csstools/selector-specificity@^2.0.0", "@csstools/selector-specificity@^2.0.2": - version "2.0.2" - resolved "https://registry.yarnpkg.com/@csstools/selector-specificity/-/selector-specificity-2.0.2.tgz#1bfafe4b7ed0f3e4105837e056e0a89b108ebe36" - integrity sha512-IkpVW/ehM1hWKln4fCA3NzJU8KwD+kIOvPZA4cqxoJHtE21CCzjyp+Kxbu0i5I4tBNOlXPL9mjwnWlL0VEG4Fg== + version "2.2.0" + resolved "https://registry.yarnpkg.com/@csstools/selector-specificity/-/selector-specificity-2.2.0.tgz#2cbcf822bf3764c9658c4d2e568bd0c0cb748016" + integrity sha512-+OJ9konv95ClSTOJCmMZqpd5+YGsB2S+x6w3E1oaM8UuR5j8nTNHYSz8c9BEPGDOCMQYIEEGlVPj/VY64iTbGw== "@date-io/core@^1.3.13": version "1.3.13" @@ -1211,127 +1280,138 @@ dependencies: "@date-io/core" "^1.3.13" -"@emotion/babel-plugin@^11.10.5": - version "11.10.5" - resolved "https://registry.yarnpkg.com/@emotion/babel-plugin/-/babel-plugin-11.10.5.tgz#65fa6e1790ddc9e23cc22658a4c5dea423c55c3c" - integrity sha512-xE7/hyLHJac7D2Ve9dKroBBZqBT7WuPQmWcq7HSGb84sUuP4mlOWoB8dvVfD9yk5DHkU1m6RW7xSoDtnQHNQeA== +"@emotion/babel-plugin@^11.11.0": + version "11.11.0" + resolved "https://registry.yarnpkg.com/@emotion/babel-plugin/-/babel-plugin-11.11.0.tgz#c2d872b6a7767a9d176d007f5b31f7d504bb5d6c" + integrity sha512-m4HEDZleaaCH+XgDDsPF15Ht6wTLsgDTeR3WYj9Q/k76JtWhrJjcP4+/XlG8LGT/Rol9qUfOIztXeA84ATpqPQ== dependencies: "@babel/helper-module-imports" "^7.16.7" - "@babel/plugin-syntax-jsx" "^7.17.12" "@babel/runtime" "^7.18.3" - "@emotion/hash" "^0.9.0" - "@emotion/memoize" "^0.8.0" - "@emotion/serialize" "^1.1.1" + "@emotion/hash" "^0.9.1" + "@emotion/memoize" "^0.8.1" + "@emotion/serialize" "^1.1.2" babel-plugin-macros "^3.1.0" convert-source-map "^1.5.0" escape-string-regexp "^4.0.0" find-root "^1.1.0" source-map "^0.5.7" - stylis "4.1.3" + stylis "4.2.0" -"@emotion/cache@^11.10.5": - version "11.10.5" - resolved "https://registry.yarnpkg.com/@emotion/cache/-/cache-11.10.5.tgz#c142da9351f94e47527ed458f7bbbbe40bb13c12" - integrity sha512-dGYHWyzTdmK+f2+EnIGBpkz1lKc4Zbj2KHd4cX3Wi8/OWr5pKslNjc3yABKH4adRGCvSX4VDC0i04mrrq0aiRA== +"@emotion/cache@^11.11.0": + version "11.11.0" + resolved "https://registry.yarnpkg.com/@emotion/cache/-/cache-11.11.0.tgz#809b33ee6b1cb1a625fef7a45bc568ccd9b8f3ff" + integrity sha512-P34z9ssTCBi3e9EI1ZsWpNHcfY1r09ZO0rZbRO2ob3ZQMnFI35jB536qoXbkdesr5EUhYi22anuEJuyxifaqAQ== dependencies: - "@emotion/memoize" "^0.8.0" - "@emotion/sheet" "^1.2.1" - "@emotion/utils" "^1.2.0" - "@emotion/weak-memoize" "^0.3.0" - stylis "4.1.3" + "@emotion/memoize" "^0.8.1" + "@emotion/sheet" "^1.2.2" + "@emotion/utils" "^1.2.1" + "@emotion/weak-memoize" "^0.3.1" + stylis "4.2.0" "@emotion/hash@^0.8.0": version "0.8.0" resolved "https://registry.yarnpkg.com/@emotion/hash/-/hash-0.8.0.tgz#bbbff68978fefdbe68ccb533bc8cbe1d1afb5413" integrity sha512-kBJtf7PH6aWwZ6fka3zQ0p6SBYzx4fl1LoZXE2RrnYST9Xljm7WfKJrU4g/Xr3Beg72MLrp1AWNUmuYJTL7Cow== -"@emotion/hash@^0.9.0": - version "0.9.0" - resolved "https://registry.yarnpkg.com/@emotion/hash/-/hash-0.9.0.tgz#c5153d50401ee3c027a57a177bc269b16d889cb7" - integrity sha512-14FtKiHhy2QoPIzdTcvh//8OyBlknNs2nXRwIhG904opCby3l+9Xaf/wuPvICBF0rc1ZCNBd3nKe9cd2mecVkQ== +"@emotion/hash@^0.9.1": + version "0.9.1" + resolved "https://registry.yarnpkg.com/@emotion/hash/-/hash-0.9.1.tgz#4ffb0055f7ef676ebc3a5a91fb621393294e2f43" + integrity sha512-gJB6HLm5rYwSLI6PQa+X1t5CFGrv1J1TWG+sOyMCeKz2ojaj6Fnl/rZEspogG+cvqbt4AE/2eIyD2QfLKTBNlQ== -"@emotion/is-prop-valid@^1.2.0": - version "1.2.0" - resolved "https://registry.yarnpkg.com/@emotion/is-prop-valid/-/is-prop-valid-1.2.0.tgz#7f2d35c97891669f7e276eb71c83376a5dc44c83" - integrity sha512-3aDpDprjM0AwaxGE09bOPkNxHpBd+kA6jty3RnaEXdweX1DF1U3VQpPYb0g1IStAuK7SVQ1cy+bNBBKp4W3Fjg== +"@emotion/is-prop-valid@^1.2.1": + version "1.2.1" + resolved "https://registry.yarnpkg.com/@emotion/is-prop-valid/-/is-prop-valid-1.2.1.tgz#23116cf1ed18bfeac910ec6436561ecb1a3885cc" + integrity sha512-61Mf7Ufx4aDxx1xlDeOm8aFFigGHE4z+0sKCa+IHCeZKiyP9RLD0Mmx7m8b9/Cf37f7NAvQOOJAbQQGVr5uERw== dependencies: - "@emotion/memoize" "^0.8.0" + "@emotion/memoize" "^0.8.1" -"@emotion/memoize@^0.8.0": - version "0.8.0" - resolved "https://registry.yarnpkg.com/@emotion/memoize/-/memoize-0.8.0.tgz#f580f9beb67176fa57aae70b08ed510e1b18980f" - integrity sha512-G/YwXTkv7Den9mXDO7AhLWkE3q+I92B+VqAE+dYG4NGPaHZGvt3G8Q0p9vmE+sq7rTGphUbAvmQ9YpbfMQGGlA== +"@emotion/memoize@^0.8.1": + version "0.8.1" + resolved "https://registry.yarnpkg.com/@emotion/memoize/-/memoize-0.8.1.tgz#c1ddb040429c6d21d38cc945fe75c818cfb68e17" + integrity sha512-W2P2c/VRW1/1tLox0mVUalvnWXxavmv/Oum2aPsRcoDJuob75FC3Y8FbpfLwUegRcxINtGUMPq0tFCvYNTBXNA== "@emotion/react@^11.10.5": - version "11.10.5" - resolved "https://registry.yarnpkg.com/@emotion/react/-/react-11.10.5.tgz#95fff612a5de1efa9c0d535384d3cfa115fe175d" - integrity sha512-TZs6235tCJ/7iF6/rvTaOH4oxQg2gMAcdHemjwLKIjKz4rRuYe1HJ2TQJKnAcRAfOUDdU8XoDadCe1rl72iv8A== + version "11.11.1" + resolved "https://registry.yarnpkg.com/@emotion/react/-/react-11.11.1.tgz#b2c36afac95b184f73b08da8c214fdf861fa4157" + integrity sha512-5mlW1DquU5HaxjLkfkGN1GA/fvVGdyHURRiX/0FHl2cfIfRxSOfmxEH5YS43edp0OldZrZ+dkBKbngxcNCdZvA== dependencies: "@babel/runtime" "^7.18.3" - "@emotion/babel-plugin" "^11.10.5" - "@emotion/cache" "^11.10.5" - "@emotion/serialize" "^1.1.1" - "@emotion/use-insertion-effect-with-fallbacks" "^1.0.0" - "@emotion/utils" "^1.2.0" - "@emotion/weak-memoize" "^0.3.0" + "@emotion/babel-plugin" "^11.11.0" + "@emotion/cache" "^11.11.0" + "@emotion/serialize" "^1.1.2" + "@emotion/use-insertion-effect-with-fallbacks" "^1.0.1" + "@emotion/utils" "^1.2.1" + "@emotion/weak-memoize" "^0.3.1" hoist-non-react-statics "^3.3.1" -"@emotion/serialize@^1.1.1": - version "1.1.1" - resolved "https://registry.yarnpkg.com/@emotion/serialize/-/serialize-1.1.1.tgz#0595701b1902feded8a96d293b26be3f5c1a5cf0" - integrity sha512-Zl/0LFggN7+L1liljxXdsVSVlg6E/Z/olVWpfxUTxOAmi8NU7YoeWeLfi1RmnB2TATHoaWwIBRoL+FvAJiTUQA== +"@emotion/serialize@^1.1.2": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@emotion/serialize/-/serialize-1.1.2.tgz#017a6e4c9b8a803bd576ff3d52a0ea6fa5a62b51" + integrity sha512-zR6a/fkFP4EAcCMQtLOhIgpprZOwNmCldtpaISpvz348+DP4Mz8ZoKaGGCQpbzepNIUWbq4w6hNZkwDyKoS+HA== dependencies: - "@emotion/hash" "^0.9.0" - "@emotion/memoize" "^0.8.0" - "@emotion/unitless" "^0.8.0" - "@emotion/utils" "^1.2.0" + "@emotion/hash" "^0.9.1" + "@emotion/memoize" "^0.8.1" + "@emotion/unitless" "^0.8.1" + "@emotion/utils" "^1.2.1" csstype "^3.0.2" -"@emotion/sheet@^1.2.1": - version "1.2.1" - resolved "https://registry.yarnpkg.com/@emotion/sheet/-/sheet-1.2.1.tgz#0767e0305230e894897cadb6c8df2c51e61a6c2c" - integrity sha512-zxRBwl93sHMsOj4zs+OslQKg/uhF38MB+OMKoCrVuS0nyTkqnau+BM3WGEoOptg9Oz45T/aIGs1qbVAsEFo3nA== +"@emotion/sheet@^1.2.2": + version "1.2.2" + resolved "https://registry.yarnpkg.com/@emotion/sheet/-/sheet-1.2.2.tgz#d58e788ee27267a14342303e1abb3d508b6d0fec" + integrity sha512-0QBtGvaqtWi+nx6doRwDdBIzhNdZrXUppvTM4dtZZWEGTXL/XE/yJxLMGlDT1Gt+UHH5IX1n+jkXyytE/av7OA== "@emotion/styled@^11.10.5": - version "11.10.5" - resolved "https://registry.yarnpkg.com/@emotion/styled/-/styled-11.10.5.tgz#1fe7bf941b0909802cb826457e362444e7e96a79" - integrity sha512-8EP6dD7dMkdku2foLoruPCNkRevzdcBaY6q0l0OsbyJK+x8D9HWjX27ARiSIKNF634hY9Zdoedh8bJCiva8yZw== + version "11.11.0" + resolved "https://registry.yarnpkg.com/@emotion/styled/-/styled-11.11.0.tgz#26b75e1b5a1b7a629d7c0a8b708fbf5a9cdce346" + integrity sha512-hM5Nnvu9P3midq5aaXj4I+lnSfNi7Pmd4EWk1fOZ3pxookaQTNew6bp4JaCBYM4HVFZF9g7UjJmsUmC2JlxOng== dependencies: "@babel/runtime" "^7.18.3" - "@emotion/babel-plugin" "^11.10.5" - "@emotion/is-prop-valid" "^1.2.0" - "@emotion/serialize" "^1.1.1" - "@emotion/use-insertion-effect-with-fallbacks" "^1.0.0" - "@emotion/utils" "^1.2.0" + "@emotion/babel-plugin" "^11.11.0" + "@emotion/is-prop-valid" "^1.2.1" + "@emotion/serialize" "^1.1.2" + "@emotion/use-insertion-effect-with-fallbacks" "^1.0.1" + "@emotion/utils" "^1.2.1" -"@emotion/unitless@^0.8.0": - version "0.8.0" - resolved "https://registry.yarnpkg.com/@emotion/unitless/-/unitless-0.8.0.tgz#a4a36e9cbdc6903737cd20d38033241e1b8833db" - integrity sha512-VINS5vEYAscRl2ZUDiT3uMPlrFQupiKgHz5AA4bCH1miKBg4qtwkim1qPmJj/4WG6TreYMY111rEFsjupcOKHw== +"@emotion/unitless@^0.8.1": + version "0.8.1" + resolved "https://registry.yarnpkg.com/@emotion/unitless/-/unitless-0.8.1.tgz#182b5a4704ef8ad91bde93f7a860a88fd92c79a3" + integrity sha512-KOEGMu6dmJZtpadb476IsZBclKvILjopjUii3V+7MnXIQCYh8W3NgNcgwo21n9LXZX6EDIKvqfjYxXebDwxKmQ== -"@emotion/use-insertion-effect-with-fallbacks@^1.0.0": - version "1.0.0" - resolved "https://registry.yarnpkg.com/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.0.0.tgz#ffadaec35dbb7885bd54de3fa267ab2f860294df" - integrity sha512-1eEgUGmkaljiBnRMTdksDV1W4kUnmwgp7X9G8B++9GYwl1lUdqSndSriIrTJ0N7LQaoauY9JJ2yhiOYK5+NI4A== +"@emotion/use-insertion-effect-with-fallbacks@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.0.1.tgz#08de79f54eb3406f9daaf77c76e35313da963963" + integrity sha512-jT/qyKZ9rzLErtrjGgdkMBn2OP8wl0G3sQlBb3YPryvKHsjvINUhVaPFfP+fpBcOkmrVOVEEHQFJ7nbj2TH2gw== -"@emotion/utils@^1.2.0": - version "1.2.0" - resolved "https://registry.yarnpkg.com/@emotion/utils/-/utils-1.2.0.tgz#9716eaccbc6b5ded2ea5a90d65562609aab0f561" - integrity sha512-sn3WH53Kzpw8oQ5mgMmIzzyAaH2ZqFEbozVVBSYp538E06OSE6ytOp7pRAjNQR+Q/orwqdQYJSe2m3hCOeznkw== +"@emotion/utils@^1.2.1": + version "1.2.1" + resolved "https://registry.yarnpkg.com/@emotion/utils/-/utils-1.2.1.tgz#bbab58465738d31ae4cb3dbb6fc00a5991f755e4" + integrity sha512-Y2tGf3I+XVnajdItskUCn6LX+VUDmP6lTL4fcqsXAv43dnlbZiuW4MWQW38rW/BVWSE7Q/7+XQocmpnRYILUmg== -"@emotion/weak-memoize@^0.3.0": - version "0.3.0" - resolved "https://registry.yarnpkg.com/@emotion/weak-memoize/-/weak-memoize-0.3.0.tgz#ea89004119dc42db2e1dba0f97d553f7372f6fcb" - integrity sha512-AHPmaAx+RYfZz0eYu6Gviiagpmiyw98ySSlQvCUhVGDRtDFe4DBS0x1bSjdF3gqUDYOczB+yYvBTtEylYSdRhg== +"@emotion/weak-memoize@^0.3.1": + version "0.3.1" + resolved "https://registry.yarnpkg.com/@emotion/weak-memoize/-/weak-memoize-0.3.1.tgz#d0fce5d07b0620caa282b5131c297bb60f9d87e6" + integrity sha512-EsBwpc7hBUJWAsNPBmJy4hxWx12v6bshQsldrVmjxJoc3isbxhOrF2IcCpaXxfvq03NwkI7sbsOLXbYuqF/8Ww== -"@eslint/eslintrc@^1.4.0": - version "1.4.0" - resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-1.4.0.tgz#8ec64e0df3e7a1971ee1ff5158da87389f167a63" - integrity sha512-7yfvXy6MWLgWSFsLhz5yH3iQ52St8cdUY6FoGieKkRDVxuxmrNuUetIuu6cmjNWwniUHiWXjxCr5tTXDrbYS5A== +"@eslint-community/eslint-utils@^4.1.2", "@eslint-community/eslint-utils@^4.2.0", "@eslint-community/eslint-utils@^4.4.0": + version "4.4.0" + resolved "https://registry.yarnpkg.com/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz#a23514e8fb9af1269d5f7788aa556798d61c6b59" + integrity sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA== + dependencies: + eslint-visitor-keys "^3.3.0" + +"@eslint-community/regexpp@^4.4.0", "@eslint-community/regexpp@^4.5.1", "@eslint-community/regexpp@^4.6.0", "@eslint-community/regexpp@^4.6.1": + version "4.8.0" + resolved "https://registry.yarnpkg.com/@eslint-community/regexpp/-/regexpp-4.8.0.tgz#11195513186f68d42fbf449f9a7136b2c0c92005" + integrity sha512-JylOEEzDiOryeUnFbQz+oViCXS0KsvR1mvHkoMiu5+UiBvy+RYX7tzlIIIEstF/gVa2tj9AQXk3dgnxv6KxhFg== + +"@eslint/eslintrc@^2.1.2": + version "2.1.2" + resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-2.1.2.tgz#c6936b4b328c64496692f76944e755738be62396" + integrity sha512-+wvgpDsrB1YqAMdEUCcnTlpfVBH7Vqn6A/NT3D8WVXFIaKMlErPIZT3oCIAVCOtarRpMtelZLqJeU3t7WY6X6g== dependencies: ajv "^6.12.4" debug "^4.3.2" - espree "^9.4.0" + espree "^9.6.0" globals "^13.19.0" ignore "^5.2.0" import-fresh "^3.2.1" @@ -1339,10 +1419,42 @@ minimatch "^3.1.2" strip-json-comments "^3.1.1" -"@humanwhocodes/config-array@^0.11.8": - version "0.11.8" - resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.11.8.tgz#03595ac2075a4dc0f191cc2131de14fbd7d410b9" - integrity sha512-UybHIJzJnR5Qc/MsD9Kr+RpO2h+/P1GhOwdiLPXK5TWk5sgTdu88bTD9UP+CKbPPh5Rni1u0GjAdYQLemG8g+g== +"@eslint/js@8.48.0": + version "8.48.0" + resolved "https://registry.yarnpkg.com/@eslint/js/-/js-8.48.0.tgz#642633964e217905436033a2bd08bf322849b7fb" + integrity sha512-ZSjtmelB7IJfWD2Fvb7+Z+ChTIKWq6kjda95fLcQKNS5aheVHn4IkfgRQE3sIIzTcSLwLcLZUD9UBt+V7+h+Pw== + +"@floating-ui/core@^1.4.1": + version "1.4.1" + resolved "https://registry.yarnpkg.com/@floating-ui/core/-/core-1.4.1.tgz#0d633f4b76052668afb932492ac452f7ebe97f17" + integrity sha512-jk3WqquEJRlcyu7997NtR5PibI+y5bi+LS3hPmguVClypenMsCY3CBa3LAQnozRCtCrYWSEtAdiskpamuJRFOQ== + dependencies: + "@floating-ui/utils" "^0.1.1" + +"@floating-ui/dom@^1.5.1": + version "1.5.1" + resolved "https://registry.yarnpkg.com/@floating-ui/dom/-/dom-1.5.1.tgz#88b70defd002fe851f17b4a25efb2d3c04d7a8d7" + integrity sha512-KwvVcPSXg6mQygvA1TjbN/gh///36kKtllIF8SUm0qpFj8+rvYrpvlYdL1JoA71SHpDqgSSdGOSoQ0Mp3uY5aw== + dependencies: + "@floating-ui/core" "^1.4.1" + "@floating-ui/utils" "^0.1.1" + +"@floating-ui/react-dom@^2.0.1": + version "2.0.2" + resolved "https://registry.yarnpkg.com/@floating-ui/react-dom/-/react-dom-2.0.2.tgz#fab244d64db08e6bed7be4b5fcce65315ef44d20" + integrity sha512-5qhlDvjaLmAst/rKb3VdlCinwTF4EYMiVxuuc/HVUjs46W0zgtbMmAZ1UTsDrRTxRmUEzl92mOtWbeeXL26lSQ== + dependencies: + "@floating-ui/dom" "^1.5.1" + +"@floating-ui/utils@^0.1.1": + version "0.1.1" + resolved "https://registry.yarnpkg.com/@floating-ui/utils/-/utils-0.1.1.tgz#1a5b1959a528e374e8037c4396c3e825d6cf4a83" + integrity sha512-m0G6wlnhm/AX0H12IOWtK8gASEMffnX08RtKkCgTdHb9JpHKGloI7icFfLg9ZmQeavcvR0PKmzxClyuFPSjKWw== + +"@humanwhocodes/config-array@^0.11.10": + version "0.11.11" + resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.11.11.tgz#88a04c570dbbc7dd943e4712429c3df09bc32844" + integrity sha512-N2brEuAadi0CcdeMXUkhbZB84eskAc8MEX1By6qEchoVywSgXPIjou4rYsl0V3Hj0ZnuGycGCjdNgockbzeWNA== dependencies: "@humanwhocodes/object-schema" "^1.2.1" debug "^4.1.1" @@ -1580,62 +1692,54 @@ "@jest/schemas" "^28.1.3" "@types/istanbul-lib-coverage" "^2.0.0" "@types/istanbul-reports" "^3.0.0" - "@types/node" "*" - "@types/yargs" "^17.0.8" - chalk "^4.0.0" - -"@jridgewell/gen-mapping@^0.1.0": - version "0.1.1" - resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz#e5d2e450306a9491e3bd77e323e38d7aff315996" - integrity sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w== - dependencies: - "@jridgewell/set-array" "^1.0.0" - "@jridgewell/sourcemap-codec" "^1.4.10" + "@types/node" "*" + "@types/yargs" "^17.0.8" + chalk "^4.0.0" "@jridgewell/gen-mapping@^0.3.0", "@jridgewell/gen-mapping@^0.3.2": - version "0.3.2" - resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz#c1aedc61e853f2bb9f5dfe6d4442d3b565b253b9" - integrity sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A== + version "0.3.3" + resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz#7e02e6eb5df901aaedb08514203b096614024098" + integrity sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ== dependencies: "@jridgewell/set-array" "^1.0.1" "@jridgewell/sourcemap-codec" "^1.4.10" "@jridgewell/trace-mapping" "^0.3.9" -"@jridgewell/resolve-uri@3.1.0": - version "3.1.0" - resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz#2203b118c157721addfe69d47b70465463066d78" - integrity sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w== +"@jridgewell/resolve-uri@^3.1.0": + version "3.1.1" + resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz#c08679063f279615a3326583ba3a90d1d82cc721" + integrity sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA== -"@jridgewell/set-array@^1.0.0", "@jridgewell/set-array@^1.0.1": +"@jridgewell/set-array@^1.0.1": version "1.1.2" resolved "https://registry.yarnpkg.com/@jridgewell/set-array/-/set-array-1.1.2.tgz#7c6cf998d6d20b914c0a55a91ae928ff25965e72" integrity sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw== -"@jridgewell/source-map@^0.3.2": - version "0.3.2" - resolved "https://registry.yarnpkg.com/@jridgewell/source-map/-/source-map-0.3.2.tgz#f45351aaed4527a298512ec72f81040c998580fb" - integrity sha512-m7O9o2uR8k2ObDysZYzdfhb08VuEml5oWGiosa1VdaPZ/A6QyPkAJuwN0Q1lhULOf6B7MtQmHENS743hWtCrgw== +"@jridgewell/source-map@^0.3.3": + version "0.3.5" + resolved "https://registry.yarnpkg.com/@jridgewell/source-map/-/source-map-0.3.5.tgz#a3bb4d5c6825aab0d281268f47f6ad5853431e91" + integrity sha512-UTYAUj/wviwdsMfzoSJspJxbkH5o1snzwX0//0ENX1u/55kkZZkcTZP6u9bwKGkv+dkk9at4m1Cpt0uY80kcpQ== dependencies: "@jridgewell/gen-mapping" "^0.3.0" "@jridgewell/trace-mapping" "^0.3.9" -"@jridgewell/sourcemap-codec@1.4.14", "@jridgewell/sourcemap-codec@^1.4.10": - version "1.4.14" - resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz#add4c98d341472a289190b424efbdb096991bb24" - integrity sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw== +"@jridgewell/sourcemap-codec@^1.4.10", "@jridgewell/sourcemap-codec@^1.4.14": + version "1.4.15" + resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz#d7c6e6755c78567a951e04ab52ef0fd26de59f32" + integrity sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg== -"@jridgewell/trace-mapping@^0.3.14", "@jridgewell/trace-mapping@^0.3.9": - version "0.3.17" - resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.17.tgz#793041277af9073b0951a7fe0f0d8c4c98c36985" - integrity sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g== +"@jridgewell/trace-mapping@^0.3.17", "@jridgewell/trace-mapping@^0.3.9": + version "0.3.19" + resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.19.tgz#f8a3249862f91be48d3127c3cfe992f79b4b8811" + integrity sha512-kf37QtfW+Hwx/buWGMPcR60iF9ziHa6r/CZJIHbmcm4+0qrXiVdxegAH0F6yddEVQ7zdkjcGCgCzUu+BcbhQxw== dependencies: - "@jridgewell/resolve-uri" "3.1.0" - "@jridgewell/sourcemap-codec" "1.4.14" + "@jridgewell/resolve-uri" "^3.1.0" + "@jridgewell/sourcemap-codec" "^1.4.14" "@jsonforms/core@^3.0.0": - version "3.0.0" - resolved "https://registry.yarnpkg.com/@jsonforms/core/-/core-3.0.0.tgz#f743c139f2036f461cc52c109e1c3d884bea8e4e" - integrity sha512-DcUGLNaeAE411oA8d5dPuPEF2/nDmALAfQRsaA3GPAre2D76kJXyBb8TFMjLMRJCVIR0q5LsiRRdmLnuPVHKqA== + version "3.1.0" + resolved "https://registry.yarnpkg.com/@jsonforms/core/-/core-3.1.0.tgz#1eff4404584d7049103c00f7ce85d549603e124b" + integrity sha512-Whs6+VBNhQyMFoPjLCltS4KzcRskayBPYkj7zZaPgA/piPLQXAglAsz5jd5SK7bncYy+dGQSB/6LPzP1QhRxqw== dependencies: "@types/json-schema" "^7.0.3" ajv "^8.6.1" @@ -1643,17 +1747,17 @@ lodash "^4.17.15" "@jsonforms/material-renderers@^3.0.0": - version "3.0.0" - resolved "https://registry.yarnpkg.com/@jsonforms/material-renderers/-/material-renderers-3.0.0.tgz#573b5d4a8e28e3eab9130201d90ee14f5ed79f60" - integrity sha512-M0MgnB473vIAuuPMaUjNa3tBVEv/aTN59DK/Pm0TJrR+6UJgOJsBXfE6I/uQcpFaDbE5o91vK1fbRHHQ47BLZQ== + version "3.1.0" + resolved "https://registry.yarnpkg.com/@jsonforms/material-renderers/-/material-renderers-3.1.0.tgz#179173ca24a70acb7beb386996aea1136a65732d" + integrity sha512-XtHKIb7CfgQl0RwJnUlab8+DMmtlTqyEffeZVcc7Fsu+O9ujd902GOScTdKPa6LcW77yAiSoHnxpVkchdxwGHQ== dependencies: "@date-io/dayjs" "1.3.13" dayjs "1.10.6" "@jsonforms/react@^3.0.0": - version "3.0.0" - resolved "https://registry.yarnpkg.com/@jsonforms/react/-/react-3.0.0.tgz#73f9f52ec0301d6252b78a1af1c91f51f3da24e6" - integrity sha512-Fj/L6hjk9uYSEBQrV7Vyj3ocTYGFelSupAJYmlys/37BPgifzPc+cBQj5bMKzx6pfO8YbmI+Sr3HDs2eNA/LkA== + version "3.1.0" + resolved "https://registry.yarnpkg.com/@jsonforms/react/-/react-3.1.0.tgz#a9d8dd19d5913c1fcfd73470c7b86049c71b8b18" + integrity sha512-amgCdopa9SEes/gl/6MjQkSPq+rUZ+aEBx+bWlTc6dWgaNR0i/efIBFl/2o+fCyJAHFpTEsLzSfjzaPjUFVIxQ== dependencies: lodash "^4.17.15" @@ -1733,132 +1837,111 @@ prop-types "^15.7.2" react-is "^16.8.0 || ^17.0.0" -"@mui/base@5.0.0-alpha.111": - version "5.0.0-alpha.111" - resolved "https://registry.yarnpkg.com/@mui/base/-/base-5.0.0-alpha.111.tgz#fffec7f6393fc45c0d3a200ee5820820a4b92403" - integrity sha512-2wfIPpl97S4dPzD0QOM3UIzQ/EuXCYQvHmXxTpfKxev/cfkzOe7Ik/McoYUBbtM1bSOqH3W276R/L2LF9cyXqQ== - dependencies: - "@babel/runtime" "^7.20.6" - "@emotion/is-prop-valid" "^1.2.0" - "@mui/types" "^7.2.3" - "@mui/utils" "^5.11.1" - "@popperjs/core" "^2.11.6" - clsx "^1.2.1" +"@mui/base@5.0.0-beta.13": + version "5.0.0-beta.13" + resolved "https://registry.yarnpkg.com/@mui/base/-/base-5.0.0-beta.13.tgz#3bae94c39752546d84a67d4ca73486b7c4923a89" + integrity sha512-uC0l97pBspfDAp+iz2cJq8YZ8Sd9i73V77+WzUiOAckIVEyCm5dyVDZCCO2/phmzckVEeZCGcytybkjMQuhPQw== + dependencies: + "@babel/runtime" "^7.22.10" + "@emotion/is-prop-valid" "^1.2.1" + "@floating-ui/react-dom" "^2.0.1" + "@mui/types" "^7.2.4" + "@mui/utils" "^5.14.7" + "@popperjs/core" "^2.11.8" + clsx "^2.0.0" prop-types "^15.8.1" react-is "^18.2.0" -"@mui/core-downloads-tracker@^5.11.1": - version "5.11.1" - resolved "https://registry.yarnpkg.com/@mui/core-downloads-tracker/-/core-downloads-tracker-5.11.1.tgz#5130682392203916bd9d947bac35dfd38f533654" - integrity sha512-QVqVNlZ2K+LqUDE5kFgYd0r4KekR/dv2cNYbAutQWbfOA8VPVUVrDz0ELrEcoe8TjM/CwnsmGvaDh/YSNl/ALA== +"@mui/core-downloads-tracker@^5.14.7": + version "5.14.7" + resolved "https://registry.yarnpkg.com/@mui/core-downloads-tracker/-/core-downloads-tracker-5.14.7.tgz#95bed2487bf59632125a13b8eb8f4c21e460afec" + integrity sha512-sCWTUNElBPgB30iLvWe3PU7SIlTKZNf6/E/sko85iHVeHCM6WPkDw+y89CrZYjhFNmPqt2fIQM/pZu+rP2lFLA== "@mui/icons-material@^5.11.0": - version "5.11.0" - resolved "https://registry.yarnpkg.com/@mui/icons-material/-/icons-material-5.11.0.tgz#9ea6949278b2266d2683866069cd43009eaf6464" - integrity sha512-I2LaOKqO8a0xcLGtIozC9xoXjZAto5G5gh0FYUMAlbsIHNHIjn4Xrw9rvjY20vZonyiGrZNMAlAXYkY6JvhF6A== + version "5.14.7" + resolved "https://registry.yarnpkg.com/@mui/icons-material/-/icons-material-5.14.7.tgz#d7f6bd188fe38adf35c89d9343b8a529c2306383" + integrity sha512-mWp4DwMa8c1Gx9yOEtPgxM4b+e6hAbtZyzfSubdBwrnEE6G5D2rbAJ5MB+If6kfI48JaYaJ5j8+zAdmZLuZc0A== dependencies: - "@babel/runtime" "^7.20.6" + "@babel/runtime" "^7.22.10" "@mui/lab@^5.0.0-alpha.113": - version "5.0.0-alpha.113" - resolved "https://registry.yarnpkg.com/@mui/lab/-/lab-5.0.0-alpha.113.tgz#c532bb09c4f4987bb7306faf121d9e4240c94ef0" - integrity sha512-c0TwSRnILXr8V7G2N2fV1Jk0bDIGVyrF6SWE8DCnAa81q0hPQYrFJXAC3Lewezbbrao6nLubel5+c9ieka6J9g== - dependencies: - "@babel/runtime" "^7.20.6" - "@mui/base" "5.0.0-alpha.111" - "@mui/system" "^5.11.1" - "@mui/types" "^7.2.3" - "@mui/utils" "^5.11.1" - clsx "^1.2.1" + version "5.0.0-alpha.142" + resolved "https://registry.yarnpkg.com/@mui/lab/-/lab-5.0.0-alpha.142.tgz#aa8d69801b7f75cfe6ff1a62ccdc73fe662ceadc" + integrity sha512-JDrT5G3QBZ0nzkKMFWzJY5KN8WcyDx4p7qOjg6hs7yKLq90VSdsqIOmyhvWDxJR7zPNQjo0WRYBAaRaQ5FlGxg== + dependencies: + "@babel/runtime" "^7.22.10" + "@mui/base" "5.0.0-beta.13" + "@mui/system" "^5.14.7" + "@mui/types" "^7.2.4" + "@mui/utils" "^5.14.7" + clsx "^2.0.0" prop-types "^15.8.1" react-is "^18.2.0" "@mui/material@^5.11.1": - version "5.11.1" - resolved "https://registry.yarnpkg.com/@mui/material/-/material-5.11.1.tgz#89ebc860abae0f146d9ac69b85baa691f09cfb47" - integrity sha512-yaZiXvcrl2vgUK+VO24780BWRgwdAMmAyuMVZnRTts1Yu0tWd6PjIYq2ZtaOlpj6/LbaSS+Q2kSfxYnDQ20CEQ== - dependencies: - "@babel/runtime" "^7.20.6" - "@mui/base" "5.0.0-alpha.111" - "@mui/core-downloads-tracker" "^5.11.1" - "@mui/system" "^5.11.1" - "@mui/types" "^7.2.3" - "@mui/utils" "^5.11.1" - "@types/react-transition-group" "^4.4.5" - clsx "^1.2.1" - csstype "^3.1.1" + version "5.14.7" + resolved "https://registry.yarnpkg.com/@mui/material/-/material-5.14.7.tgz#6c2c0de8a625562f789e1bb33cb4cfc8cf20bdb0" + integrity sha512-jIZj9F7zMv6IlyaYDVv5M2Kp20jIX8c0kzuwteySHS/A0IvPVyomQEPtWc51MCbpDNCqzwoZUp3rQtA2lI8k7A== + dependencies: + "@babel/runtime" "^7.22.10" + "@mui/base" "5.0.0-beta.13" + "@mui/core-downloads-tracker" "^5.14.7" + "@mui/system" "^5.14.7" + "@mui/types" "^7.2.4" + "@mui/utils" "^5.14.7" + "@types/react-transition-group" "^4.4.6" + clsx "^2.0.0" + csstype "^3.1.2" prop-types "^15.8.1" react-is "^18.2.0" react-transition-group "^4.4.5" -"@mui/private-theming@^5.11.1": - version "5.11.1" - resolved "https://registry.yarnpkg.com/@mui/private-theming/-/private-theming-5.11.1.tgz#8e6a6c33c6f04cadba17b6f3320e22bd64413655" - integrity sha512-nnHg7kA5RwFRhy0wiDYe59sLCVGORpPypL1JcEdhv0+N0Zbmc2E/y4z2zqMRZ62MAEscpro7cQbvv244ThA84A== +"@mui/private-theming@^5.14.7": + version "5.14.7" + resolved "https://registry.yarnpkg.com/@mui/private-theming/-/private-theming-5.14.7.tgz#c9fec31e59bf66b12959e724b0e8ec3bb4a3d923" + integrity sha512-Y86+hmDnJab2Ka42PgxKpK3oL7EiacbeeX3X/lG9LGO0wSc45wZjHeTfIlVSkkUCkexiMKEJp5NlSjZhr27NRQ== dependencies: - "@babel/runtime" "^7.20.6" - "@mui/utils" "^5.11.1" + "@babel/runtime" "^7.22.10" + "@mui/utils" "^5.14.7" prop-types "^15.8.1" -"@mui/styled-engine@^5.11.0": - version "5.11.0" - resolved "https://registry.yarnpkg.com/@mui/styled-engine/-/styled-engine-5.11.0.tgz#79afb30c612c7807c4b77602cf258526d3997c7b" - integrity sha512-AF06K60Zc58qf0f7X+Y/QjaHaZq16znliLnGc9iVrV/+s8Ln/FCoeNuFvhlCbZZQ5WQcJvcy59zp0nXrklGGPQ== +"@mui/styled-engine@^5.14.7": + version "5.14.7" + resolved "https://registry.yarnpkg.com/@mui/styled-engine/-/styled-engine-5.14.7.tgz#aaacec6c87bcc9a180b2da062c613213af10f2e3" + integrity sha512-hKBETEDsIAkL8/mBwPiQj/vw28OeIhMXC3Tvj4J2bb9snxAKpiZioR1PwqP+6P41twsC/GKBd0Vr9oaWYaHuMg== dependencies: - "@babel/runtime" "^7.20.6" - "@emotion/cache" "^11.10.5" - csstype "^3.1.1" - prop-types "^15.8.1" - -"@mui/system@^5.11.1": - version "5.11.1" - resolved "https://registry.yarnpkg.com/@mui/system/-/system-5.11.1.tgz#86c85472f5c2d4eaf739acd426c7b1ccce38eda2" - integrity sha512-BEA2S0hay8n8CcZftkeAVsi0nsb5ZjdnZRCahv5lX7QJYwDjO4ucJ6lnvxHe2v/9Te1LLjTO7ojxu/qM6CE5Cg== - dependencies: - "@babel/runtime" "^7.20.6" - "@mui/private-theming" "^5.11.1" - "@mui/styled-engine" "^5.11.0" - "@mui/types" "^7.2.3" - "@mui/utils" "^5.11.1" - clsx "^1.2.1" - csstype "^3.1.1" + "@babel/runtime" "^7.22.10" + "@emotion/cache" "^11.11.0" + csstype "^3.1.2" prop-types "^15.8.1" -"@mui/types@^7.2.3": - version "7.2.3" - resolved "https://registry.yarnpkg.com/@mui/types/-/types-7.2.3.tgz#06faae1c0e2f3a31c86af6f28b3a4a42143670b9" - integrity sha512-tZ+CQggbe9Ol7e/Fs5RcKwg/woU+o8DCtOnccX6KmbBc7YrfqMYEYuaIcXHuhpT880QwNkZZ3wQwvtlDFA2yOw== - -"@mui/utils@^5.10.3": - version "5.13.6" - resolved "https://registry.yarnpkg.com/@mui/utils/-/utils-5.13.6.tgz#aa29d75de59577585b9f23891b03592d40459ed7" - integrity sha512-ggNlxl5NPSbp+kNcQLmSig6WVB0Id+4gOxhx644987v4fsji+CSXc+MFYLocFB/x4oHtzCUlSzbVHlJfP/fXoQ== - dependencies: - "@babel/runtime" "^7.22.5" - "@types/prop-types" "^15.7.5" - "@types/react-is" "^18.2.0" +"@mui/system@^5.11.1", "@mui/system@^5.14.7": + version "5.14.7" + resolved "https://registry.yarnpkg.com/@mui/system/-/system-5.14.7.tgz#b08e23f9151d38186ab12dd618906abd4d73d203" + integrity sha512-jeZtHglc+Pi6qjGoopT6O4RqYXVBMqHVOsjMGP0hxGSSPm1T4gsAu7jU8eqGx9YwwjvvJ0eotTjFqw7iJ6qE2Q== + dependencies: + "@babel/runtime" "^7.22.10" + "@mui/private-theming" "^5.14.7" + "@mui/styled-engine" "^5.14.7" + "@mui/types" "^7.2.4" + "@mui/utils" "^5.14.7" + clsx "^2.0.0" + csstype "^3.1.2" prop-types "^15.8.1" - react-is "^18.2.0" -"@mui/utils@^5.11.1": - version "5.11.1" - resolved "https://registry.yarnpkg.com/@mui/utils/-/utils-5.11.1.tgz#8d12b3c2245efd9a1c0595658dcb4c86f6625206" - integrity sha512-lMAPgIJoil8V9ZxsMbEflMsvZmWcHbRVMc4JDY9jPO9V4welpF43h/O267b1RqlcRnC5MEbVQV605GYkTZY29Q== - dependencies: - "@babel/runtime" "^7.20.6" - "@types/prop-types" "^15.7.5" - "@types/react-is" "^16.7.1 || ^17.0.0" - prop-types "^15.8.1" - react-is "^18.2.0" +"@mui/types@^7.2.4": + version "7.2.4" + resolved "https://registry.yarnpkg.com/@mui/types/-/types-7.2.4.tgz#b6fade19323b754c5c6de679a38f068fd50b9328" + integrity sha512-LBcwa8rN84bKF+f5sDyku42w1NTxaPgPyYKODsh01U1fVstTClbUoSA96oyRBnSNyEiAVjKm6Gwx9vjR+xyqHA== -"@mui/utils@^5.12.3": - version "5.13.1" - resolved "https://registry.yarnpkg.com/@mui/utils/-/utils-5.13.1.tgz#86199e46014215f95da046a5ec803f4a39c96eee" - integrity sha512-6lXdWwmlUbEU2jUI8blw38Kt+3ly7xkmV9ljzY4Q20WhsJMWiNry9CX8M+TaP/HbtuyR8XKsdMgQW7h7MM3n3A== +"@mui/utils@^5.10.3", "@mui/utils@^5.14.7": + version "5.14.7" + resolved "https://registry.yarnpkg.com/@mui/utils/-/utils-5.14.7.tgz#3677bcabe032f1185e151f57d8c1a166df3ae0a1" + integrity sha512-RtheP/aBoPogVdi8vj8Vo2IFnRa4mZVmnD0RGlVZ49yF60rZs+xP4/KbpIrTr83xVs34QmHQ2aQ+IX7I0a0dDw== dependencies: - "@babel/runtime" "^7.21.0" + "@babel/runtime" "^7.22.10" "@types/prop-types" "^15.7.5" - "@types/react-is" "^18.2.0" + "@types/react-is" "^18.2.1" prop-types "^15.8.1" react-is "^18.2.0" @@ -1874,14 +1957,14 @@ reselect "^4.1.6" "@mui/x-date-pickers@^6.5.0": - version "6.5.0" - resolved "https://registry.yarnpkg.com/@mui/x-date-pickers/-/x-date-pickers-6.5.0.tgz#b71dbf9d8961fb34d9d829a4c6f9159ebb4e9206" - integrity sha512-dRCO1mzHjfOqsa4LdKxiXQnV0cuGiAkliyxSDCdRn6clK2WdF9Oj+1+4Mkx7fcJA61SV1eP4Yg29s0/VDsZKZw== + version "6.12.1" + resolved "https://registry.yarnpkg.com/@mui/x-date-pickers/-/x-date-pickers-6.12.1.tgz#ffd30b61ee58267ffdb4f2d8e0b2181c4ac842e8" + integrity sha512-euMM7KNbqoOgIdf5P8T8KG74qqbpDvLp5k8yEVMx1zHeSiSZGofKpQrDFAMxjJRnJ0x1aJLIhFEc46O70fSAlA== dependencies: - "@babel/runtime" "^7.21.0" - "@mui/utils" "^5.12.3" + "@babel/runtime" "^7.22.11" + "@mui/utils" "^5.14.7" "@types/react-transition-group" "^4.4.6" - clsx "^1.2.1" + clsx "^2.0.0" prop-types "^15.8.1" react-transition-group "^4.4.5" @@ -1913,10 +1996,22 @@ "@nodelib/fs.scandir" "2.1.5" fastq "^1.6.0" +"@pkgr/utils@^2.3.1": + version "2.4.2" + resolved "https://registry.yarnpkg.com/@pkgr/utils/-/utils-2.4.2.tgz#9e638bbe9a6a6f165580dc943f138fd3309a2cbc" + integrity sha512-POgTXhjrTfbTV63DiFXav4lBHiICLKKwDeaKn9Nphwj7WH6m0hMMCaJkMyRWjgtPFyRKRVoMXXjczsTQRDEhYw== + dependencies: + cross-spawn "^7.0.3" + fast-glob "^3.3.0" + is-glob "^4.0.3" + open "^9.1.0" + picocolors "^1.0.0" + tslib "^2.6.0" + "@pmmmwh/react-refresh-webpack-plugin@^0.5.3": - version "0.5.10" - resolved "https://registry.yarnpkg.com/@pmmmwh/react-refresh-webpack-plugin/-/react-refresh-webpack-plugin-0.5.10.tgz#2eba163b8e7dbabb4ce3609ab5e32ab63dda3ef8" - integrity sha512-j0Ya0hCFZPd4x40qLzbhGsh9TMtdb+CJQiso+WxLOPNasohq9cc5SNUcwsZaRH6++Xh91Xkm/xHCkuIiIu0LUA== + version "0.5.11" + resolved "https://registry.yarnpkg.com/@pmmmwh/react-refresh-webpack-plugin/-/react-refresh-webpack-plugin-0.5.11.tgz#7c2268cedaa0644d677e8c4f377bc8fb304f714a" + integrity sha512-7j/6vdTym0+qZ6u4XbSAxrWBGYSdCfTzySkj7WAFgDLmSyWlOrWvpyzxlFh5jtw9dn0oL/jtW+06XfFiisN3JQ== dependencies: ansi-html-community "^0.0.8" common-path-prefix "^3.0.0" @@ -1928,10 +2023,10 @@ schema-utils "^3.0.0" source-map "^0.7.3" -"@popperjs/core@^2.11.6", "@popperjs/core@^2.9.2": - version "2.11.6" - resolved "https://registry.yarnpkg.com/@popperjs/core/-/core-2.11.6.tgz#cee20bd55e68a1720bdab363ecf0c821ded4cd45" - integrity sha512-50/17A98tWUfQ176raKiOGXuYpLyyVMkxxG6oylzL3BPOlA6ADGdK7EYunSa4I064xerltq9TGXs8HmOk5E+vw== +"@popperjs/core@^2.11.8": + version "2.11.8" + resolved "https://registry.yarnpkg.com/@popperjs/core/-/core-2.11.8.tgz#6b79032e760a0899cd4204710beede972a3a185f" + integrity sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A== "@react-pdf/fns@2.0.1": version "2.0.1" @@ -1940,13 +2035,13 @@ dependencies: "@babel/runtime" "^7.20.13" -"@react-pdf/font@^2.3.4": - version "2.3.4" - resolved "https://registry.yarnpkg.com/@react-pdf/font/-/font-2.3.4.tgz#3411e2b49807a86cd1dc33b471b2b1228b7d18e3" - integrity sha512-ICvVH0GW3kgocxVfE0mFY3EcnAoxRolkOfhPCfLu8mRbwJaHRiKX5+8SRKbPADZNdHrF9ngt4LpUxThy+bdZXg== +"@react-pdf/font@^2.3.6": + version "2.3.6" + resolved "https://registry.yarnpkg.com/@react-pdf/font/-/font-2.3.6.tgz#d92c6abf5fe6643842d47b0d22d52487026de311" + integrity sha512-JYV+KmVyG2tPdpCK0/iFiBy1V7VHz2fETttKCgTRsLAo+w8RpM0pUGSAYROSuRl7yqbhiKGw/A24PYWhBReiOQ== dependencies: "@babel/runtime" "^7.20.13" - "@react-pdf/types" "^2.3.1" + "@react-pdf/types" "^2.3.3" cross-fetch "^3.1.5" fontkit "^2.0.2" is-url "^1.2.4" @@ -1960,19 +2055,19 @@ "@react-pdf/png-js" "^2.2.0" cross-fetch "^3.1.5" -"@react-pdf/layout@^3.6.0": - version "3.6.0" - resolved "https://registry.yarnpkg.com/@react-pdf/layout/-/layout-3.6.0.tgz#799101f95cb12a76f289cf0c4297a9e61285662a" - integrity sha512-xrcVWxtXpobW0iqTd8OmMCVMmeGUM46PYq7B1MGR1fI1QG/EKe4HzFdhSdd0werZYj+t1TRC8+tVSX5POs5SYA== +"@react-pdf/layout@^3.6.2": + version "3.6.2" + resolved "https://registry.yarnpkg.com/@react-pdf/layout/-/layout-3.6.2.tgz#10fc0b8f26cfbd4c7f774aa2317d2fb625c6f656" + integrity sha512-YD3/tDC6p5XPCXI04zH79bgX8LytjxEYfeCtsIzEFk0A2VvIHoRnRRDZ2OhZmO5g112ykyjY8vn9//ubTt+Ktg== dependencies: "@babel/runtime" "^7.20.13" "@react-pdf/fns" "2.0.1" "@react-pdf/image" "^2.2.1" "@react-pdf/pdfkit" "^3.0.2" "@react-pdf/primitives" "^3.0.0" - "@react-pdf/stylesheet" "^4.1.5" + "@react-pdf/stylesheet" "^4.1.7" "@react-pdf/textkit" "^4.2.0" - "@react-pdf/types" "^2.3.1" + "@react-pdf/types" "^2.3.3" "@react-pdf/yoga" "^4.1.2" cross-fetch "^3.1.5" emoji-regex "^10.2.1" @@ -2002,16 +2097,16 @@ resolved "https://registry.yarnpkg.com/@react-pdf/primitives/-/primitives-3.0.1.tgz#3b2bfebdb1fef6fc7f99214ccfd0932267b8e0cd" integrity sha512-0HGcknrLNwyhxe+SZCBL29JY4M85mXKdvTZE9uhjNbADGgTc8wVnkc5+e4S/lDvugbVISXyuIhZnYwtK9eDnyQ== -"@react-pdf/render@^3.2.4": - version "3.2.4" - resolved "https://registry.yarnpkg.com/@react-pdf/render/-/render-3.2.4.tgz#63dee668cd6082f374cfce1310b9d79bb7e500ce" - integrity sha512-lnef097Dx2vHKpY9OHHNmV+nsG5vpd33h76tCzdlbijj+TyVm1j7ZQ5qadGq1uMOFAU6lp0hEo7VoDk7XnjmFw== +"@react-pdf/render@^3.2.6": + version "3.2.6" + resolved "https://registry.yarnpkg.com/@react-pdf/render/-/render-3.2.6.tgz#9d6a6e3c89568fa05a37dac4e29c220eec0689c6" + integrity sha512-nsd1sleWMzBdrYGv5BwChPgVwoTZilfdiadE5wQiblFqG1C7EYINadalnEl1tjldKAzofSPBLKJbnSGR5r2lIQ== dependencies: "@babel/runtime" "^7.20.13" "@react-pdf/fns" "2.0.1" "@react-pdf/primitives" "^3.0.0" "@react-pdf/textkit" "^4.2.0" - "@react-pdf/types" "^2.3.1" + "@react-pdf/types" "^2.3.3" abs-svg-path "^0.1.1" color-string "^1.5.3" normalize-svg-path "^1.1.0" @@ -2019,31 +2114,31 @@ svg-arc-to-cubic-bezier "^3.2.0" "@react-pdf/renderer@^3.1.9": - version "3.1.9" - resolved "https://registry.yarnpkg.com/@react-pdf/renderer/-/renderer-3.1.9.tgz#886bfb0b6263d96303adcf8ea63ee776ff0ef4ad" - integrity sha512-kfEH7O+Jy7aihbUqrT9Ej1gx8/twRWvFMfHlACr29QsN+s+w0XzWpHCvbjkinVFABYcvsenluiirik6mf4qwRQ== + version "3.1.12" + resolved "https://registry.yarnpkg.com/@react-pdf/renderer/-/renderer-3.1.12.tgz#3c208a35662c561712acad1e06ccd0b753b2472a" + integrity sha512-y4H2ELH0okJP7+ig+uNjFAfuAanWiF3mxsKsE7ZBuhF4tabbMt9fX+pQ7qn4xrzEWX0vlso6s6ebkkeGdSGWzA== dependencies: "@babel/runtime" "^7.20.13" - "@react-pdf/font" "^2.3.4" - "@react-pdf/layout" "^3.6.0" + "@react-pdf/font" "^2.3.6" + "@react-pdf/layout" "^3.6.2" "@react-pdf/pdfkit" "^3.0.2" "@react-pdf/primitives" "^3.0.0" - "@react-pdf/render" "^3.2.4" - "@react-pdf/types" "^2.3.1" + "@react-pdf/render" "^3.2.6" + "@react-pdf/types" "^2.3.3" events "^3.3.0" object-assign "^4.1.1" prop-types "^15.6.2" queue "^6.0.1" scheduler "^0.17.0" -"@react-pdf/stylesheet@^4.1.5": - version "4.1.5" - resolved "https://registry.yarnpkg.com/@react-pdf/stylesheet/-/stylesheet-4.1.5.tgz#4dc9da3c29f5bd205509b6f44e74e93b4bf46b47" - integrity sha512-8sP+4KD3cAfBEsZBQeJC7GUC0vkCLiAc6kZaGX0dXaBR3nZO2TaCD8+ZuezokZi+ARp/yvWJqR2vIX8ra7X1xA== +"@react-pdf/stylesheet@^4.1.7": + version "4.1.7" + resolved "https://registry.yarnpkg.com/@react-pdf/stylesheet/-/stylesheet-4.1.7.tgz#f0ac1396e70d356262de59aeb8efa17c7d9a2a0c" + integrity sha512-3n0Vg0XFszPyo0MpH75DkLRvsS4JOE0HzBH6XqFHDiquZDrC4mNgmMhZEbsOED+8xDGoCeVh8fLU3L6Tu0HWqg== dependencies: "@babel/runtime" "^7.20.13" "@react-pdf/fns" "2.0.1" - "@react-pdf/types" "^2.3.1" + "@react-pdf/types" "^2.3.3" color-string "^1.5.3" hsl-to-hex "^1.0.0" media-engine "^1.0.3" @@ -2059,10 +2154,10 @@ hyphen "^1.6.4" unicode-properties "^1.4.1" -"@react-pdf/types@^2.3.1": - version "2.3.1" - resolved "https://registry.yarnpkg.com/@react-pdf/types/-/types-2.3.1.tgz#a379f4621e8be6c8f2d0205787854854781f7a87" - integrity sha512-FiwAsNp2oQ2W39xAU1PCjY6YNjEuypQykEA6VMz4WZ4ERvyOBB4M5B8063lA8YYBcjYB8xQOa9og4UH1eqMbgg== +"@react-pdf/types@^2.3.3": + version "2.3.3" + resolved "https://registry.yarnpkg.com/@react-pdf/types/-/types-2.3.3.tgz#96a0d0514d74291bf1dbc7c75322025b3aa72bbb" + integrity sha512-I3BVu5vF0xxX6rvqZHt4gCjFAt6X+mak5bwYQyf6bm21IIMDXXBtgXqWEl1wosWizArox7fcN/XbEnysrf/8Dw== "@react-pdf/yoga@^4.1.2": version "4.1.2" @@ -2071,29 +2166,28 @@ dependencies: "@babel/runtime" "^7.20.13" -"@reactflow/background@11.1.0": - version "11.1.0" - resolved "https://registry.yarnpkg.com/@reactflow/background/-/background-11.1.0.tgz#943c799d9f251340e9867ad8f4c6ac291163e401" - integrity sha512-EgDn3rhK+l8jKmE6KGUZvesRjdh7fOqsz5Hj7STUU5/uGsvgN9KFuudY/Ka8m+yCQxqNK8MAJcRMOZd0mvNFMQ== +"@reactflow/background@11.2.8": + version "11.2.8" + resolved "https://registry.yarnpkg.com/@reactflow/background/-/background-11.2.8.tgz#aa83f87b7d65442b52732f0a04d9da981f978265" + integrity sha512-5o41N2LygiNC2/Pk8Ak2rIJjXbKHfQ23/Y9LFsnAlufqwdzFqKA8txExpsMoPVHHlbAdA/xpQaMuoChGPqmyDw== dependencies: - "@babel/runtime" "^7.18.9" - "@reactflow/core" "11.4.0" + "@reactflow/core" "11.8.3" classcat "^5.0.3" - zustand "^4.1.1" + zustand "^4.4.1" -"@reactflow/controls@11.1.0": - version "11.1.0" - resolved "https://registry.yarnpkg.com/@reactflow/controls/-/controls-11.1.0.tgz#6d6f6dd6e53557579c6cfcea3c7376d2d00c2953" - integrity sha512-5nH1TQ9mkveUOnq7QgohzeAdGR4WwKQJMrWjb5u3Dnm5D5+oRxTE3eGBoaw6B6nYaK1rDrPCcMAuGmEPdEC+Mg== +"@reactflow/controls@11.1.19": + version "11.1.19" + resolved "https://registry.yarnpkg.com/@reactflow/controls/-/controls-11.1.19.tgz#a8bc4b4eafc10d5d230db5286753e867bcf35e5b" + integrity sha512-Vo0LFfAYjiSRMLEII/aeBo+1MT2a0Yc7iLVnkuRTLzChC0EX+A2Fa+JlzeOEYKxXlN4qcDxckRNGR7092v1HOQ== dependencies: - "@babel/runtime" "^7.18.9" - "@reactflow/core" "11.4.0" + "@reactflow/core" "11.8.3" classcat "^5.0.3" + zustand "^4.4.1" -"@reactflow/core@11.4.0": - version "11.4.0" - resolved "https://registry.yarnpkg.com/@reactflow/core/-/core-11.4.0.tgz#9af0c812eb9968b75cf55427c6be4a9205d0db48" - integrity sha512-AfFp685kmxWs2Iiq35TatG9Q8u5W+eftXECQ0ea55Oi37nrMe5jfWhjnGnnl3bSFcHqAe6avqNiFDwqugU6kzQ== +"@reactflow/core@11.8.3": + version "11.8.3" + resolved "https://registry.yarnpkg.com/@reactflow/core/-/core-11.8.3.tgz#03ffeb06fbc141b8f786cb4ac8169f8a51a5f00e" + integrity sha512-y6DN8Wy4V4KQBGHFqlj9zWRjLJU6CgdnVwWaEA/PdDg/YUkFBMpZnXqTs60czinoA2rAcvsz50syLTPsj5e+Wg== dependencies: "@types/d3" "^7.4.0" "@types/d3-drag" "^3.0.1" @@ -2103,36 +2197,45 @@ d3-drag "^3.0.0" d3-selection "^3.0.0" d3-zoom "^3.0.0" - zustand "^4.1.1" + zustand "^4.4.1" -"@reactflow/minimap@11.3.0": - version "11.3.0" - resolved "https://registry.yarnpkg.com/@reactflow/minimap/-/minimap-11.3.0.tgz#2f89dbab4c10b754c452f70857172d959cca60aa" - integrity sha512-nvb4qmbsogjhrn7GWXpvLMtmAyE7mjs0BXvtbpcFVpKqQ3Lbf76zCa8c2krUMnBBqu+9yF0Ftkn7mMCTV2gPLQ== +"@reactflow/minimap@11.6.3": + version "11.6.3" + resolved "https://registry.yarnpkg.com/@reactflow/minimap/-/minimap-11.6.3.tgz#1cfddd87e9afd23ad704167988c66bd683ffc5d2" + integrity sha512-PSA28dk09RnBHOA1zb45fjQXz3UozSJZmsIpgq49O3trfVFlSgRapxNdGsughWLs7/emg2M5jmi6Vc+ejcfjvQ== dependencies: - "@babel/runtime" "^7.18.9" - "@reactflow/core" "11.4.0" + "@reactflow/core" "11.8.3" "@types/d3-selection" "^3.0.3" "@types/d3-zoom" "^3.0.1" classcat "^5.0.3" d3-selection "^3.0.0" d3-zoom "^3.0.0" - zustand "^4.1.1" + zustand "^4.4.1" -"@reactflow/node-toolbar@1.1.0": - version "1.1.0" - resolved "https://registry.yarnpkg.com/@reactflow/node-toolbar/-/node-toolbar-1.1.0.tgz#c7de2fb5c7aef02a1e575ce12a35d23cd45c18bd" - integrity sha512-kibrTGGvwhFGndVSgwr9E6l9Uddr44csr06X+PJ7FJ0SXgeOHbSw4MaM/9dSFxkFoCi77fPXSdMONNTReSBnIg== +"@reactflow/node-resizer@2.1.5": + version "2.1.5" + resolved "https://registry.yarnpkg.com/@reactflow/node-resizer/-/node-resizer-2.1.5.tgz#f4033946ccc9cc8f47a94ed93f10a32befd546f1" + integrity sha512-z/hJlsptd2vTx13wKouqvN/Kln08qbkA+YTJLohc2aJ6rx3oGn9yX4E4IqNxhA7zNqYEdrnc1JTEA//ifh9z3w== dependencies: - "@babel/runtime" "^7.18.9" - "@reactflow/core" "11.4.0" + "@reactflow/core" "11.8.3" + classcat "^5.0.4" + d3-drag "^3.0.0" + d3-selection "^3.0.0" + zustand "^4.4.1" + +"@reactflow/node-toolbar@1.2.7": + version "1.2.7" + resolved "https://registry.yarnpkg.com/@reactflow/node-toolbar/-/node-toolbar-1.2.7.tgz#cf6639945dc42b42416f293d6132e1187bca3424" + integrity sha512-vs+Wg1tjy3SuD7eoeTqEtscBfE9RY+APqC28urVvftkrtsN7KlnoQjqDG6aE45jWP4z+8bvFizRWjAhxysNLkg== + dependencies: + "@reactflow/core" "11.8.3" classcat "^5.0.3" - zustand "^4.1.1" + zustand "^4.4.1" -"@remix-run/router@1.2.0": - version "1.2.0" - resolved "https://registry.yarnpkg.com/@remix-run/router/-/router-1.2.0.tgz#54eff8306938b64c521f4a9ed313d33a91ef019a" - integrity sha512-GO82KYYTWPRCgdNtnheaZG3LcViUlxRFlHM7ykh7N+ufoXi6PVIHoP+9RUG/vuzl2hr9i/h6EA1Eq+2HpqJ0gQ== +"@remix-run/router@1.8.0": + version "1.8.0" + resolved "https://registry.yarnpkg.com/@remix-run/router/-/router-1.8.0.tgz#e848d2f669f601544df15ce2a313955e4bf0bafc" + integrity sha512-mrfKqIHnSZRyIzBcanNJmVQELTnX+qagEDlcKO90RgRBVOZGSGvZKeDihTRfWcqoDn5N/NkUcwWTccnpN18Tfg== "@rollup/plugin-babel@^5.2.0": version "5.3.1" @@ -2172,9 +2275,9 @@ picomatch "^2.2.2" "@rushstack/eslint-patch@^1.1.0": - version "1.2.0" - resolved "https://registry.yarnpkg.com/@rushstack/eslint-patch/-/eslint-patch-1.2.0.tgz#8be36a1f66f3265389e90b5f9c9962146758f728" - integrity sha512-sXo/qW2/pAcmT43VoRKOJbDOfV3cYpq3szSVfIThQXNt+E4DfKj361vaAt3c88U5tPUxzEswam7GW48PJqtKAg== + version "1.3.3" + resolved "https://registry.yarnpkg.com/@rushstack/eslint-patch/-/eslint-patch-1.3.3.tgz#16ab6c727d8c2020a5b6e4a176a243ecd88d8d69" + integrity sha512-0xd7qez0AQ+MbHatZTlI1gu5vkG8r7MYRUJAHPAHJBmGLs16zpkrpAVLvjQKQOqaXPDUBwOiJzNc00znHSCVBw== "@sinclair/typebox@^0.24.1": version "0.24.51" @@ -2309,10 +2412,11 @@ loader-utils "^2.0.0" "@swc/helpers@^0.4.2": - version "0.4.14" - resolved "https://registry.yarnpkg.com/@swc/helpers/-/helpers-0.4.14.tgz#1352ac6d95e3617ccb7c1498ff019654f1e12a74" - integrity sha512-4C7nX/dvpzB7za4Ql9K81xK3HPxCpHMgwTZVyf+9JQ6VUbn9jjZVN7/Nkdz/Ugzs2CSjqnL/UPXroiVBVHUWUw== + version "0.4.36" + resolved "https://registry.yarnpkg.com/@swc/helpers/-/helpers-0.4.36.tgz#fcfff76ed52c214f357e8e9d3f37b568908072d9" + integrity sha512-5lxnyLEYFskErRPenYItLRSge5DjrJngYKdVjRSrWfza9G6KkgHEXi0vUZiyUeMU5JfXH1YnvXZzSp8ul88o2Q== dependencies: + legacy-swc-helpers "npm:@swc/helpers@=0.4.14" tslib "^2.4.0" "@tootallnate/once@1": @@ -2326,12 +2430,12 @@ integrity sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA== "@types/babel__core@^7.0.0", "@types/babel__core@^7.1.14": - version "7.1.20" - resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.1.20.tgz#e168cdd612c92a2d335029ed62ac94c95b362359" - integrity sha512-PVb6Bg2QuscZ30FvOU7z4guG6c926D9YRvOxEaelzndpMsvP+YM74Q/dAFASpg2l6+XLalxSGxcq/lrgYWZtyQ== + version "7.20.1" + resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.20.1.tgz#916ecea274b0c776fec721e333e55762d3a9614b" + integrity sha512-aACu/U/omhdk15O4Nfb+fHgH/z3QsfQzpnvRZhYhThms83ZnAOZz7zZAWO7mn2yyNQaA4xTO8GLK3uqFU4bYYw== dependencies: - "@babel/parser" "^7.1.0" - "@babel/types" "^7.0.0" + "@babel/parser" "^7.20.7" + "@babel/types" "^7.20.7" "@types/babel__generator" "*" "@types/babel__template" "*" "@types/babel__traverse" "*" @@ -2352,11 +2456,11 @@ "@babel/types" "^7.0.0" "@types/babel__traverse@*", "@types/babel__traverse@^7.0.4", "@types/babel__traverse@^7.0.6": - version "7.18.3" - resolved "https://registry.yarnpkg.com/@types/babel__traverse/-/babel__traverse-7.18.3.tgz#dfc508a85781e5698d5b33443416b6268c4b3e8d" - integrity sha512-1kbcJ40lLB7MHsj39U4Sh1uTd2E7rLEa79kmDpI6cy+XiXsteB3POdQomoq4FxszMrO3ZYchkhYJw7A2862b3w== + version "7.20.1" + resolved "https://registry.yarnpkg.com/@types/babel__traverse/-/babel__traverse-7.20.1.tgz#dd6f1d2411ae677dcb2db008c962598be31d6acf" + integrity sha512-MitHFXnhtgwsGZWtT68URpOvLN4EREih1u3QtQiN4VdAxWKRVvGCSvw/Qth0M0Qq3pJpnGOu5JaM/ydK7OGbqg== dependencies: - "@babel/types" "^7.3.0" + "@babel/types" "^7.20.7" "@types/body-parser@*": version "1.19.2" @@ -2374,9 +2478,9 @@ "@types/node" "*" "@types/connect-history-api-fallback@^1.3.5": - version "1.3.5" - resolved "https://registry.yarnpkg.com/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.3.5.tgz#d1f7a8a09d0ed5a57aee5ae9c18ab9b803205dae" - integrity sha512-h8QJa8xSb1WD4fpKBDcATDNGXghFj6/3GRWG6dhmRcu0RX1Ubasur2Uvx5aeEwlf0MwblEC2bMzzMQntxnw/Cw== + version "1.5.0" + resolved "https://registry.yarnpkg.com/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.5.0.tgz#9fd20b3974bdc2bcd4ac6567e2e0f6885cb2cf41" + integrity sha512-4x5FkPpLipqwthjPsF7ZRbOv3uoLUFkTA9G9v583qi4pACvq0uTELrB8OLUzPWUI4IJIyvM85vzkV1nyiI2Lig== dependencies: "@types/express-serve-static-core" "*" "@types/node" "*" @@ -2389,28 +2493,28 @@ "@types/node" "*" "@types/d3-array@*": - version "3.0.3" - resolved "https://registry.yarnpkg.com/@types/d3-array/-/d3-array-3.0.3.tgz#87d990bf504d14ad6b16766979d04e943c046dac" - integrity sha512-Reoy+pKnvsksN0lQUlcH6dOGjRZ/3WRwXR//m+/8lt1BXeI4xyaUZoqULNjyXXRuh0Mj4LNpkCvhUpQlY3X5xQ== + version "3.0.7" + resolved "https://registry.yarnpkg.com/@types/d3-array/-/d3-array-3.0.7.tgz#b128a0c0b0d9481d3281df47de0955730db384a1" + integrity sha512-4/Q0FckQ8TBjsB0VdGFemJOG8BLXUB2KKlL0VmZ+eOYeOnTb/wDRQqYWpBmQ6IlvWkXwkYiot+n9Px2aTJ7zGQ== "@types/d3-axis@*": - version "3.0.1" - resolved "https://registry.yarnpkg.com/@types/d3-axis/-/d3-axis-3.0.1.tgz#6afc20744fa5cc0cbc3e2bd367b140a79ed3e7a8" - integrity sha512-zji/iIbdd49g9WN0aIsGcwcTBUkgLsCSwB+uH+LPVDAiKWENMtI3cJEWt+7/YYwelMoZmbBfzA3qCdrZ2XFNnw== + version "3.0.3" + resolved "https://registry.yarnpkg.com/@types/d3-axis/-/d3-axis-3.0.3.tgz#e9ca5d1dd7b1da4023ab0f9e921c3f6e86b8c06d" + integrity sha512-SE3x/pLO/+GIHH17mvs1uUVPkZ3bHquGzvZpPAh4yadRy71J93MJBpgK/xY8l9gT28yTN1g9v3HfGSFeBMmwZw== dependencies: "@types/d3-selection" "*" "@types/d3-brush@*": - version "3.0.1" - resolved "https://registry.yarnpkg.com/@types/d3-brush/-/d3-brush-3.0.1.tgz#ae5f17ce391935ca88b29000e60ee20452c6357c" - integrity sha512-B532DozsiTuQMHu2YChdZU0qsFJSio3Q6jmBYGYNp3gMDzBmuFFgPt9qKA4VYuLZMp4qc6eX7IUFUEsvHiXZAw== + version "3.0.3" + resolved "https://registry.yarnpkg.com/@types/d3-brush/-/d3-brush-3.0.3.tgz#c5de3fd8efad6d85507fa74992540060aba38c25" + integrity sha512-MQ1/M/B5ifTScHSe5koNkhxn2mhUPqXjGuKjjVYckplAPjP9t2I2sZafb/YVHDwhoXWZoSav+Q726eIbN3qprA== dependencies: "@types/d3-selection" "*" "@types/d3-chord@*": - version "3.0.1" - resolved "https://registry.yarnpkg.com/@types/d3-chord/-/d3-chord-3.0.1.tgz#54c8856c19c8e4ab36a53f73ba737de4768ad248" - integrity sha512-eQfcxIHrg7V++W8Qxn6QkqBNBokyhdWSAS73AbkbMzvLQmVVBviknoz2SRS/ZJdIOmhcmmdCRE/NFOm28Z1AMw== + version "3.0.3" + resolved "https://registry.yarnpkg.com/@types/d3-chord/-/d3-chord-3.0.3.tgz#cd1dc38ac7cb390fe06abc09d30ddf0cd2ff350a" + integrity sha512-keuSRwO02c7PBV3JMWuctIfdeJrVFI7RpzouehvBWL4/GGUB3PBNg/9ZKPZAgJphzmS2v2+7vr7BGDQw1CAulw== "@types/d3-color@*": version "3.1.0" @@ -2418,9 +2522,9 @@ integrity sha512-HKuicPHJuvPgCD+np6Se9MQvS6OCbJmOjGvylzMJRlDwUXjKTTXs6Pwgk79O09Vj/ho3u1ofXnhFOaEWWPrlwA== "@types/d3-contour@*": - version "3.0.1" - resolved "https://registry.yarnpkg.com/@types/d3-contour/-/d3-contour-3.0.1.tgz#9ff4e2fd2a3910de9c5097270a7da8a6ef240017" - integrity sha512-C3zfBrhHZvrpAAK3YXqLWVAGo87A4SvJ83Q/zVJ8rFWJdKejUnDYaWZPkA8K84kb2vDA/g90LTQAz7etXcgoQQ== + version "3.0.3" + resolved "https://registry.yarnpkg.com/@types/d3-contour/-/d3-contour-3.0.3.tgz#16255aeb85557488bdf84c0a7988c428c0d2939b" + integrity sha512-x7G/tdDZt4m09XZnG2SutbIuQqmkNYqR9uhDMdPlpJbcwepkEjEWG29euFcgVA1k6cn92CHdDL9Z+fOnxnbVQw== dependencies: "@types/d3-array" "*" "@types/geojson" "*" @@ -2431,21 +2535,21 @@ integrity sha512-tLxQ2sfT0p6sxdG75c6f/ekqxjyYR0+LwPrsO1mbC9YDBzPJhs2HbJJRrn8Ez1DBoHRo2yx7YEATI+8V1nGMnQ== "@types/d3-dispatch@*": - version "3.0.1" - resolved "https://registry.yarnpkg.com/@types/d3-dispatch/-/d3-dispatch-3.0.1.tgz#a1b18ae5fa055a6734cb3bd3cbc6260ef19676e3" - integrity sha512-NhxMn3bAkqhjoxabVJWKryhnZXXYYVQxaBnbANu0O94+O/nX9qSjrA1P1jbAQJxJf+VC72TxDX/YJcKue5bRqw== + version "3.0.3" + resolved "https://registry.yarnpkg.com/@types/d3-dispatch/-/d3-dispatch-3.0.3.tgz#5f6a4e9bbf90e8f775083154c3d7205cfb804762" + integrity sha512-Df7KW3Re7G6cIpIhQtqHin8yUxUHYAqiE41ffopbmU5+FifYUNV7RVyTg8rQdkEagg83m14QtS8InvNb95Zqug== "@types/d3-drag@*", "@types/d3-drag@^3.0.1": - version "3.0.1" - resolved "https://registry.yarnpkg.com/@types/d3-drag/-/d3-drag-3.0.1.tgz#fb1e3d5cceeee4d913caa59dedf55c94cb66e80f" - integrity sha512-o1Va7bLwwk6h03+nSM8dpaGEYnoIG19P0lKqlic8Un36ymh9NSkNFX1yiXMKNMx8rJ0Kfnn2eovuFaL6Jvj0zA== + version "3.0.3" + resolved "https://registry.yarnpkg.com/@types/d3-drag/-/d3-drag-3.0.3.tgz#829a58420d8818be65a005795068964ff80a387b" + integrity sha512-82AuQMpBQjuXeIX4tjCYfWjpm3g7aGCfx6dFlxX2JlRaiME/QWcHzBsINl7gbHCODA2anPYlL31/Trj/UnjK9A== dependencies: "@types/d3-selection" "*" "@types/d3-dsv@*": - version "3.0.0" - resolved "https://registry.yarnpkg.com/@types/d3-dsv/-/d3-dsv-3.0.0.tgz#f3c61fb117bd493ec0e814856feb804a14cfc311" - integrity sha512-o0/7RlMl9p5n6FQDptuJVMxDf/7EDEv2SYEO/CwdG2tr1hTfUVi0Iavkk2ax+VpaQ/1jVhpnj5rq1nj8vwhn2A== + version "3.0.2" + resolved "https://registry.yarnpkg.com/@types/d3-dsv/-/d3-dsv-3.0.2.tgz#0504c17388714e28a601dcaaf400147271ea14c2" + integrity sha512-DooW5AOkj4AGmseVvbwHvwM/Ltu0Ks0WrhG6r5FG9riHT5oUUTHz6xHsHqJSVU8ZmPkOqlUEY2obS5C9oCIi2g== "@types/d3-ease@*": version "3.0.0" @@ -2453,16 +2557,16 @@ integrity sha512-aMo4eaAOijJjA6uU+GIeW018dvy9+oH5Y2VPPzjjfxevvGQ/oRDs+tfYC9b50Q4BygRR8yE2QCLsrT0WtAVseA== "@types/d3-fetch@*": - version "3.0.1" - resolved "https://registry.yarnpkg.com/@types/d3-fetch/-/d3-fetch-3.0.1.tgz#f9fa88b81aa2eea5814f11aec82ecfddbd0b8fe0" - integrity sha512-toZJNOwrOIqz7Oh6Q7l2zkaNfXkfR7mFSJvGvlD/Ciq/+SQ39d5gynHJZ/0fjt83ec3WL7+u3ssqIijQtBISsw== + version "3.0.3" + resolved "https://registry.yarnpkg.com/@types/d3-fetch/-/d3-fetch-3.0.3.tgz#ae55cc49bd71b448182deff0cc4b448eff1f9b33" + integrity sha512-/EsDKRiQkby3Z/8/AiZq8bsuLDo/tYHnNIZkUpSeEHWV7fHUl6QFBjvMPbhkKGk9jZutzfOkGygCV7eR/MkcXA== dependencies: "@types/d3-dsv" "*" "@types/d3-force@*": - version "3.0.3" - resolved "https://registry.yarnpkg.com/@types/d3-force/-/d3-force-3.0.3.tgz#76cb20d04ae798afede1ea6e41750763ff5a9c82" - integrity sha512-z8GteGVfkWJMKsx6hwC3SiTSLspL98VNpmvLpEFJQpZPq6xpA1I8HNBDNSpukfK0Vb0l64zGFhzunLgEAcBWSA== + version "3.0.5" + resolved "https://registry.yarnpkg.com/@types/d3-force/-/d3-force-3.0.5.tgz#835bbe01e084195175ddf71b7900bd44a9a23e8e" + integrity sha512-EGG+IWx93ESSXBwfh/5uPuR9Hp8M6o6qEGU7bBQslxCvrdUBQZha/EFpu/VMdLU4B0y4Oe4h175nSm7p9uqFug== "@types/d3-format@*": version "3.0.1" @@ -2470,16 +2574,16 @@ integrity sha512-5KY70ifCCzorkLuIkDe0Z9YTf9RR2CjBX1iaJG+rgM/cPP+sO+q9YdQ9WdhQcgPj1EQiJ2/0+yUkkziTG6Lubg== "@types/d3-geo@*": - version "3.0.2" - resolved "https://registry.yarnpkg.com/@types/d3-geo/-/d3-geo-3.0.2.tgz#e7ec5f484c159b2c404c42d260e6d99d99f45d9a" - integrity sha512-DbqK7MLYA8LpyHQfv6Klz0426bQEf7bRTvhMy44sNGVyZoWn//B0c+Qbeg8Osi2Obdc9BLLXYAKpyWege2/7LQ== + version "3.0.4" + resolved "https://registry.yarnpkg.com/@types/d3-geo/-/d3-geo-3.0.4.tgz#fa38f02256c3023ea3b88cb011cff1426eb7ff52" + integrity sha512-kmUK8rVVIBPKJ1/v36bk2aSgwRj2N/ZkjDT+FkMT5pgedZoPlyhaG62J+9EgNIgUXE6IIL0b7bkLxCzhE6U4VQ== dependencies: "@types/geojson" "*" "@types/d3-hierarchy@*": - version "3.1.0" - resolved "https://registry.yarnpkg.com/@types/d3-hierarchy/-/d3-hierarchy-3.1.0.tgz#4561bb7ace038f247e108295ef77b6a82193ac25" - integrity sha512-g+sey7qrCa3UbsQlMZZBOHROkFqx7KZKvUpRzI/tAp/8erZWpYq7FgNKvYwebi2LaEiVs1klhUfd3WCThxmmWQ== + version "3.1.3" + resolved "https://registry.yarnpkg.com/@types/d3-hierarchy/-/d3-hierarchy-3.1.3.tgz#9e935540e2494f3402938bf53811ed74ca3c36ba" + integrity sha512-GpSK308Xj+HeLvogfEc7QsCOcIxkDwLhFYnOoohosEzOqv7/agxwvJER1v/kTC+CY1nfazR0F7gnHo7GE41/fw== "@types/d3-interpolate@*": version "3.0.1" @@ -2514,21 +2618,21 @@ integrity sha512-dsoJGEIShosKVRBZB0Vo3C8nqSDqVGujJU6tPznsBJxNJNwMF8utmS83nvCBKQYPpjCzaaHcrf66iTRpZosLPw== "@types/d3-scale@*": - version "4.0.2" - resolved "https://registry.yarnpkg.com/@types/d3-scale/-/d3-scale-4.0.2.tgz#41be241126af4630524ead9cb1008ab2f0f26e69" - integrity sha512-Yk4htunhPAwN0XGlIwArRomOjdoBFXC3+kCxK2Ubg7I9shQlVSJy/pG/Ht5ASN+gdMIalpk8TJ5xV74jFsetLA== + version "4.0.4" + resolved "https://registry.yarnpkg.com/@types/d3-scale/-/d3-scale-4.0.4.tgz#3c5e2263eea5a3670cd91043b9f4d150a94c43f1" + integrity sha512-eq1ZeTj0yr72L8MQk6N6heP603ubnywSDRfNpi5enouR112HzGLS6RIvExCzZTraFF4HdzNpJMwA/zGiMoHUUw== dependencies: "@types/d3-time" "*" "@types/d3-selection@*", "@types/d3-selection@^3.0.3": - version "3.0.3" - resolved "https://registry.yarnpkg.com/@types/d3-selection/-/d3-selection-3.0.3.tgz#57be7da68e7d9c9b29efefd8ea5a9ef1171e42ba" - integrity sha512-Mw5cf6nlW1MlefpD9zrshZ+DAWL4IQ5LnWfRheW6xwsdaWOb6IRRu2H7XPAQcyXEx1D7XQWgdoKR83ui1/HlEA== + version "3.0.6" + resolved "https://registry.yarnpkg.com/@types/d3-selection/-/d3-selection-3.0.6.tgz#c35b5320188e921d10f77f50198705a14b8aecf6" + integrity sha512-2ACr96USZVjXR9KMD9IWi1Epo4rSDKnUtYn6q2SPhYxykvXTw9vR77lkFNruXVg4i1tzQtBxeDMx0oNvJWbF1w== "@types/d3-shape@*": - version "3.1.0" - resolved "https://registry.yarnpkg.com/@types/d3-shape/-/d3-shape-3.1.0.tgz#1d87a6ddcf28285ef1e5c278ca4bdbc0658f3505" - integrity sha512-jYIYxFFA9vrJ8Hd4Se83YI6XF+gzDL1aC5DCsldai4XYYiVNdhtpGbA/GM6iyQ8ayhSp3a148LY34hy7A4TxZA== + version "3.1.2" + resolved "https://registry.yarnpkg.com/@types/d3-shape/-/d3-shape-3.1.2.tgz#a3d421d8b0bc0c6c67cb3f4b4471ddc133cb0117" + integrity sha512-NN4CXr3qeOUNyK5WasVUV8NCSAx/CRVcwcb0BuuS1PiTqwIm6ABi1SyasLZ/vsVCFDArF+W4QiGzSry1eKYQ7w== dependencies: "@types/d3-path" "*" @@ -2548,16 +2652,16 @@ integrity sha512-HNB/9GHqu7Fo8AQiugyJbv6ZxYz58wef0esl4Mv828w1ZKpAshw/uFWVDUcIB9KKFeFKoxS3cHY07FFgtTRZ1g== "@types/d3-transition@*": - version "3.0.2" - resolved "https://registry.yarnpkg.com/@types/d3-transition/-/d3-transition-3.0.2.tgz#393dc3e3d55009a43cc6f252e73fccab6d78a8a4" - integrity sha512-jo5o/Rf+/u6uerJ/963Dc39NI16FQzqwOc54bwvksGAdVfvDrqDpVeq95bEvPtBwLCVZutAEyAtmSyEMxN7vxQ== + version "3.0.4" + resolved "https://registry.yarnpkg.com/@types/d3-transition/-/d3-transition-3.0.4.tgz#1515cd38bdc6d84103d7b6ccb25acdb72b5dd095" + integrity sha512-512a4uCOjUzsebydItSXsHrPeQblCVk8IKjqCUmrlvBWkkVh3donTTxmURDo1YPwIVDh5YVwCAO6gR4sgimCPQ== dependencies: "@types/d3-selection" "*" "@types/d3-zoom@*", "@types/d3-zoom@^3.0.1": - version "3.0.1" - resolved "https://registry.yarnpkg.com/@types/d3-zoom/-/d3-zoom-3.0.1.tgz#4bfc7e29625c4f79df38e2c36de52ec3e9faf826" - integrity sha512-7s5L9TjfqIYQmQQEUcpMAcBOahem7TRoSO/+Gkz02GbMVuULiZzjF2BOdw291dbO2aNon4m2OdFsRGaCq2caLQ== + version "3.0.4" + resolved "https://registry.yarnpkg.com/@types/d3-zoom/-/d3-zoom-3.0.4.tgz#1c754cf9f3ac96c59e6d9372c4d49f09e3e6fce3" + integrity sha512-cqkuY1ah9ZQre2POqjSLcM8g40UVya/qwEUrNYP2/rCVljbmqKCVcv+ebvwhlI5azIbSEL7m+os6n+WlYA43aA== dependencies: "@types/d3-interpolate" "*" "@types/d3-selection" "*" @@ -2599,9 +2703,9 @@ "@types/d3-zoom" "*" "@types/debug@^4.0.0": - version "4.1.7" - resolved "https://registry.yarnpkg.com/@types/debug/-/debug-4.1.7.tgz#7cc0ea761509124709b8b2d1090d8f6c17aadb82" - integrity sha512-9AonUzyTjXXhEOa0DnqpzZi6VHlqKMswga9EXjpXnnqxwLtdvPPtlO8evrI5D9S6asFRCQ6v+wpiUKbw+vKqyg== + version "4.1.8" + resolved "https://registry.yarnpkg.com/@types/debug/-/debug-4.1.8.tgz#cef723a5d0a90990313faec2d1e22aee5eecb317" + integrity sha512-/vPO1EPOs306Cvhwv7KfVfYvOJqA/S/AXjaHQiJboCZzcNDb+TIJFN9/2C9DZ//ijSKWioNyUxD792QmDJ+HKQ== dependencies: "@types/ms" "*" @@ -2614,44 +2718,40 @@ "@types/estree" "*" "@types/eslint@*", "@types/eslint@^7.29.0 || ^8.4.1": - version "8.4.10" - resolved "https://registry.yarnpkg.com/@types/eslint/-/eslint-8.4.10.tgz#19731b9685c19ed1552da7052b6f668ed7eb64bb" - integrity sha512-Sl/HOqN8NKPmhWo2VBEPm0nvHnu2LL3v9vKo8MEq0EtbJ4eVzGPl41VNPvn5E1i5poMk4/XD8UriLHpJvEP/Nw== + version "8.44.2" + resolved "https://registry.yarnpkg.com/@types/eslint/-/eslint-8.44.2.tgz#0d21c505f98a89b8dd4d37fa162b09da6089199a" + integrity sha512-sdPRb9K6iL5XZOmBubg8yiFp5yS/JdUDQsq5e6h95km91MCYMuvp7mh1fjPEYUhvHepKpZOjnEaMBR4PxjWDzg== dependencies: "@types/estree" "*" "@types/json-schema" "*" -"@types/estree@*": - version "1.0.0" - resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.0.tgz#5fb2e536c1ae9bf35366eed879e827fa59ca41c2" - integrity sha512-WulqXMDUTYAXCjZnk6JtIHPigp55cVtDgDrO2gHRwhyJto21+1zbVCtOYB2L1F9w4qCQ0rOGWBnBe0FNTiEJIQ== +"@types/estree@*", "@types/estree@^1.0.0": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.1.tgz#aa22750962f3bf0e79d753d3cc067f010c95f194" + integrity sha512-LG4opVs2ANWZ1TJoKc937iMmNstM/d0ae1vNbnBvBhqCSezgVUOzcLCqbI5elV8Vy6WKwKjaqR+zO9VKirBBCA== "@types/estree@0.0.39": version "0.0.39" resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.39.tgz#e177e699ee1b8c22d23174caaa7422644389509f" integrity sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw== -"@types/estree@^0.0.51": - version "0.0.51" - resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.51.tgz#cfd70924a25a3fd32b218e5e420e6897e1ac4f40" - integrity sha512-CuPgU6f3eT/XgKKPqKd/gLZV1Xmvf1a2R5POBOGQa6uv82xpls89HU5zKeVoyR8XzHd1RGNOlQlvUe3CFkjWNQ== - -"@types/express-serve-static-core@*", "@types/express-serve-static-core@^4.17.31": - version "4.17.31" - resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.17.31.tgz#a1139efeab4e7323834bb0226e62ac019f474b2f" - integrity sha512-DxMhY+NAsTwMMFHBTtJFNp5qiHKJ7TeqOo23zVEM9alT1Ml27Q3xcTH0xwxn7Q0BbMcVEJOs/7aQtUWupUQN3Q== +"@types/express-serve-static-core@*", "@types/express-serve-static-core@^4.17.33": + version "4.17.36" + resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.17.36.tgz#baa9022119bdc05a4adfe740ffc97b5f9360e545" + integrity sha512-zbivROJ0ZqLAtMzgzIUC4oNqDG9iF0lSsAqpOD9kbs5xcIM3dTiyuHvBc7R8MtWBp3AAWGaovJa+wzWPjLYW7Q== dependencies: "@types/node" "*" "@types/qs" "*" "@types/range-parser" "*" + "@types/send" "*" "@types/express@*", "@types/express@^4.17.13": - version "4.17.15" - resolved "https://registry.yarnpkg.com/@types/express/-/express-4.17.15.tgz#9290e983ec8b054b65a5abccb610411953d417ff" - integrity sha512-Yv0k4bXGOH+8a+7bELd2PqHQsuiANB+A8a4gnQrkRWzrkKlb6KHaVvyXhqs04sVW/OWlbPyYxRgYlIXLfrufMQ== + version "4.17.17" + resolved "https://registry.yarnpkg.com/@types/express/-/express-4.17.17.tgz#01d5437f6ef9cfa8668e616e13c2f2ac9a491ae4" + integrity sha512-Q4FmmuLGBG58btUnfS1c1r/NQdlp3DMfGDGig8WhfpA2YRUtEkxAjkZb0yvplJGYdF1fsQ81iMDcH24sSCNC/Q== dependencies: "@types/body-parser" "*" - "@types/express-serve-static-core" "^4.17.31" + "@types/express-serve-static-core" "^4.17.33" "@types/qs" "*" "@types/serve-static" "*" @@ -2661,28 +2761,33 @@ integrity sha512-Nmh0K3iWQJzniTuPRcJn5hxXkfB1T1pgB89SBig5PlJQU5yocazeu4jATJlaA0GYFKWMqDdvYemoSnF2pXgLVA== "@types/graceful-fs@^4.1.2": - version "4.1.5" - resolved "https://registry.yarnpkg.com/@types/graceful-fs/-/graceful-fs-4.1.5.tgz#21ffba0d98da4350db64891f92a9e5db3cdb4e15" - integrity sha512-anKkLmZZ+xm4p8JWBf4hElkM4XR+EZeA2M9BAkkTldmcyDY4mbdIJnRghDJH3Ov5ooY7/UAoENtmdMSkaAd7Cw== + version "4.1.6" + resolved "https://registry.yarnpkg.com/@types/graceful-fs/-/graceful-fs-4.1.6.tgz#e14b2576a1c25026b7f02ede1de3b84c3a1efeae" + integrity sha512-Sig0SNORX9fdW+bQuTEovKj3uHcUL6LQKbCrrqb1X7J6/ReAbhCXRAhc+SMejhLELFj2QcyuxmUooZ4bt5ReSw== dependencies: "@types/node" "*" "@types/hast@^2.0.0": - version "2.3.4" - resolved "https://registry.yarnpkg.com/@types/hast/-/hast-2.3.4.tgz#8aa5ef92c117d20d974a82bdfb6a648b08c0bafc" - integrity sha512-wLEm0QvaoawEDoTRwzTXp4b4jpwiJDvR5KMnFnVodm3scufTlBOWRD6N1OBf9TZMhjlNsSfcO5V+7AF4+Vy+9g== + version "2.3.5" + resolved "https://registry.yarnpkg.com/@types/hast/-/hast-2.3.5.tgz#08caac88b44d0fdd04dc17a19142355f43bd8a7a" + integrity sha512-SvQi0L/lNpThgPoleH53cdjB3y9zpLlVjRbqB3rH8hx1jiRSBGAhyjV3H+URFjNVRqt2EdYNrbZE5IsGlNfpRg== dependencies: - "@types/unist" "*" + "@types/unist" "^2" "@types/html-minifier-terser@^6.0.0": version "6.1.0" resolved "https://registry.yarnpkg.com/@types/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz#4fc33a00c1d0c16987b1a20cf92d20614c55ac35" integrity sha512-oh/6byDPnL1zeNXFrDXFLyZjkr1MsBG667IM792caf1L2UPOOMf65NFzjUH/ltyfwjAGfs1rsX1eftK0jC/KIg== +"@types/http-errors@*": + version "2.0.1" + resolved "https://registry.yarnpkg.com/@types/http-errors/-/http-errors-2.0.1.tgz#20172f9578b225f6c7da63446f56d4ce108d5a65" + integrity sha512-/K3ds8TRAfBvi5vfjuz8y6+GiAYBZ0x4tXv1Av6CWBWn0IlADc+ZX9pMq7oU0fNQPnBwIZl3rmeLp6SBApbxSQ== + "@types/http-proxy@^1.17.8": - version "1.17.9" - resolved "https://registry.yarnpkg.com/@types/http-proxy/-/http-proxy-1.17.9.tgz#7f0e7931343761efde1e2bf48c40f02f3f75705a" - integrity sha512-QsbSjA/fSk7xB+UXlCT3wHBy5ai9wOcNDWwZAtud+jXhwOM3l+EYZh8Lng4+/6n8uar0J7xILzqftJdJ/Wdfkw== + version "1.17.11" + resolved "https://registry.yarnpkg.com/@types/http-proxy/-/http-proxy-1.17.11.tgz#0ca21949a5588d55ac2b659b69035c84bd5da293" + integrity sha512-HC8G7c1WmaF2ekqpnFq626xd3Zz0uvaqFmBJNRZCGEZCXkvSdJoNFn/8Ygbd9fKNQj8UzLdCETaI0UWPAjK7IA== dependencies: "@types/node" "*" @@ -2705,10 +2810,10 @@ dependencies: "@types/istanbul-lib-report" "*" -"@types/json-schema@*", "@types/json-schema@^7.0.3", "@types/json-schema@^7.0.4", "@types/json-schema@^7.0.5", "@types/json-schema@^7.0.8", "@types/json-schema@^7.0.9": - version "7.0.11" - resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.11.tgz#d421b6c527a3037f7c84433fd2c4229e016863d3" - integrity sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ== +"@types/json-schema@*", "@types/json-schema@^7.0.12", "@types/json-schema@^7.0.3", "@types/json-schema@^7.0.4", "@types/json-schema@^7.0.5", "@types/json-schema@^7.0.8", "@types/json-schema@^7.0.9": + version "7.0.12" + resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.12.tgz#d70faba7039d5fca54c83c7dbab41051d2b6f6cb" + integrity sha512-Hr5Jfhc9eYOQNPYO5WLDq/n4jqijdHNlDXjuAQkkt+mWdQR+XJToOHrsD4cPaMXpn6KO7y2+wM8AZEs8VpBLVA== "@types/json5@^0.0.29": version "0.0.29" @@ -2716,26 +2821,31 @@ integrity sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ== "@types/mdast@^3.0.0": - version "3.0.11" - resolved "https://registry.yarnpkg.com/@types/mdast/-/mdast-3.0.11.tgz#dc130f7e7d9306124286f6d6cee40cf4d14a3dc0" - integrity sha512-Y/uImid8aAwrEA24/1tcRZwpxX3pIFTSilcNDKSPn+Y2iDywSEachzRuvgAYYLR3wpGXAsMbv5lvKLDZLeYPAw== + version "3.0.12" + resolved "https://registry.yarnpkg.com/@types/mdast/-/mdast-3.0.12.tgz#beeb511b977c875a5b0cc92eab6fcac2f0895514" + integrity sha512-DT+iNIRNX884cx0/Q1ja7NyUPpZuv0KPyL5rGNxm1WC1OtHstl7n4Jb7nk+xacNShQMbczJjt8uFzznpp6kYBg== dependencies: - "@types/unist" "*" + "@types/unist" "^2" "@types/mime@*": version "3.0.1" resolved "https://registry.yarnpkg.com/@types/mime/-/mime-3.0.1.tgz#5f8f2bca0a5863cb69bc0b0acd88c96cb1d4ae10" integrity sha512-Y4XFY5VJAuw0FgAqPNd6NNoV44jbq9Bz2L7Rh/J6jLTiHBSBJa9fxqQIvkIld4GsoDOcCbvzOUAbLPsSKKg+uA== +"@types/mime@^1": + version "1.3.2" + resolved "https://registry.yarnpkg.com/@types/mime/-/mime-1.3.2.tgz#93e25bf9ee75fe0fd80b594bc4feb0e862111b5a" + integrity sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw== + "@types/ms@*": version "0.7.31" resolved "https://registry.yarnpkg.com/@types/ms/-/ms-0.7.31.tgz#31b7ca6407128a3d2bbc27fe2d21b345397f6197" integrity sha512-iiUgKzV9AuaEkZqkOLDIvlQiL6ltuZd9tGcW3gwpnX8JbuiuhFlEGmmFXEXkN50Cvq7Os88IY2v0dkDqXYWVgA== "@types/node@*": - version "18.11.17" - resolved "https://registry.yarnpkg.com/@types/node/-/node-18.11.17.tgz#5c009e1d9c38f4a2a9d45c0b0c493fe6cdb4bcb5" - integrity sha512-HJSUJmni4BeDHhfzn6nF0sVmd1SMezP7/4F0Lq+aXzmp2xm9O7WXrUtHW/CHlYVtZUbByEvWidHqRtcJXGF2Ng== + version "20.5.7" + resolved "https://registry.yarnpkg.com/@types/node/-/node-20.5.7.tgz#4b8ecac87fbefbc92f431d09c30e176fc0a7c377" + integrity sha512-dP7f3LdZIysZnmvP3ANJYTSwg+wLLl8p7RqniVlV7j+oXSXAbt9h0WIBFmJy5inWZoX9wZN6eXx+YXd9Rh3RBA== "@types/parse-json@^4.0.0": version "4.0.0" @@ -2748,9 +2858,9 @@ integrity sha512-SuT16Q1K51EAVPz1K29DJ/sXjhSQ0zjvsypYJ6tlwVsRV9jwW5Adq2ch8Dq8kDBCkYnELS7N7VNCSB5nC56t/g== "@types/prettier@^2.1.5": - version "2.7.2" - resolved "https://registry.yarnpkg.com/@types/prettier/-/prettier-2.7.2.tgz#6c2324641cc4ba050a8c710b2b251b377581fbf0" - integrity sha512-KufADq8uQqo1pYKVIYzfKbJfBAc0sOeXqGbFaSpv8MRmC/zXgowNZmFcbngndGk922QDmOASEXUZCaY48gs4cg== + version "2.7.3" + resolved "https://registry.yarnpkg.com/@types/prettier/-/prettier-2.7.3.tgz#3e51a17e291d01d17d3fc61422015a933af7a08f" + integrity sha512-+68kP9yzs4LMp7VNh8gdzMSPZFL44MLGqiHWvttYJe+6qnuVr4Ek9wSBQoveqY/r+LwjCcU29kNVkidwim+kYA== "@types/prismjs@^1.0.0": version "1.26.0" @@ -2763,14 +2873,14 @@ integrity sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w== "@types/q@^1.5.1": - version "1.5.5" - resolved "https://registry.yarnpkg.com/@types/q/-/q-1.5.5.tgz#75a2a8e7d8ab4b230414505d92335d1dcb53a6df" - integrity sha512-L28j2FcJfSZOnL1WBjDYp2vUHCeIFlyYI/53EwD/rKUBQ7MtUUfbQWiyKJGpcnv4/WgrhWsFKrcPstcAt/J0tQ== + version "1.5.6" + resolved "https://registry.yarnpkg.com/@types/q/-/q-1.5.6.tgz#a6edffe8283910e46dc7a573621f928e6b47fa56" + integrity sha512-IKjZ8RjTSwD4/YG+2gtj7BPFRB/lNbWKTiSj3M7U/TD2B7HfYCxvp2Zz6xA2WIY7pAuL1QOUPw8gQRbUrrq4fQ== "@types/qs@*": - version "6.9.7" - resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.9.7.tgz#63bb7d067db107cc1e457c303bc25d511febf6cb" - integrity sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw== + version "6.9.8" + resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.9.8.tgz#f2a7de3c107b89b441e071d5472e6b726b4adf45" + integrity sha512-u95svzDlTysU5xecFNTgfFG5RUWu1A9P0VzgpcIiGZA9iraHOdSzcxMxQ55DyeRaGCSxQi7LxXDI4rzq/MYfdg== "@types/range-parser@*": version "1.2.4" @@ -2778,34 +2888,20 @@ integrity sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw== "@types/react-dom@^18.0.9": - version "18.0.9" - resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-18.0.9.tgz#ffee5e4bfc2a2f8774b15496474f8e7fe8d0b504" - integrity sha512-qnVvHxASt/H7i+XG1U1xMiY5t+IHcPGUK7TDMDzom08xa7e86eCeKOiLZezwCKVxJn6NEiiy2ekgX8aQssjIKg== - dependencies: - "@types/react" "*" - -"@types/react-is@^16.7.1 || ^17.0.0": - version "17.0.3" - resolved "https://registry.yarnpkg.com/@types/react-is/-/react-is-17.0.3.tgz#2d855ba575f2fc8d17ef9861f084acc4b90a137a" - integrity sha512-aBTIWg1emtu95bLTLx0cpkxwGW3ueZv71nE2YFBpL8k/z5czEW8yYpOo8Dp+UUAFAtKwNaOsh/ioSeQnWlZcfw== - dependencies: - "@types/react" "*" - -"@types/react-is@^18.2.0": - version "18.2.0" - resolved "https://registry.yarnpkg.com/@types/react-is/-/react-is-18.2.0.tgz#2f5137853a46017b3d56447940fb3eb92bbf24a5" - integrity sha512-1vz2yObaQkLL7YFe/pme2cpvDsCwI1WXIfL+5eLz0MI9gFG24Re16RzUsI8t9XZn9ZWvgLNDrJBmrqXJO7GNQQ== + version "18.2.7" + resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-18.2.7.tgz#67222a08c0a6ae0a0da33c3532348277c70abb63" + integrity sha512-GRaAEriuT4zp9N4p1i8BDBYmEyfo+xQ3yHjJU4eiK5NDa1RmUZG+unZABUTK4/Ox/M+GaHwb6Ow8rUITrtjszA== dependencies: "@types/react" "*" -"@types/react-transition-group@^4.2.0", "@types/react-transition-group@^4.4.5": - version "4.4.5" - resolved "https://registry.yarnpkg.com/@types/react-transition-group/-/react-transition-group-4.4.5.tgz#aae20dcf773c5aa275d5b9f7cdbca638abc5e416" - integrity sha512-juKD/eiSM3/xZYzjuzH6ZwpP+/lejltmiS3QEzV/vmb/Q8+HfDmxu+Baga8UEMGBqV88Nbg4l2hY/K2DkyaLLA== +"@types/react-is@^18.2.1": + version "18.2.1" + resolved "https://registry.yarnpkg.com/@types/react-is/-/react-is-18.2.1.tgz#61d01c2a6fc089a53520c0b66996d458fdc46863" + integrity sha512-wyUkmaaSZEzFZivD8F2ftSyAfk6L+DfFliVj/mYdOXbVjRcS87fQJLTnhk6dRZPuJjI+9g6RZJO4PNCngUrmyw== dependencies: "@types/react" "*" -"@types/react-transition-group@^4.4.6": +"@types/react-transition-group@^4.2.0", "@types/react-transition-group@^4.4.6": version "4.4.6" resolved "https://registry.yarnpkg.com/@types/react-transition-group/-/react-transition-group-4.4.6.tgz#18187bcda5281f8e10dfc48f0943e2fdf4f75e2e" integrity sha512-VnCdSxfcm08KjsJVQcfBmhEQAPnLB8G08hAxn39azX1qYBQ/5RVQuoHuKIcfKOdncuaUvEpFKFzEvbtIMsfVew== @@ -2813,9 +2909,9 @@ "@types/react" "*" "@types/react@*": - version "18.0.26" - resolved "https://registry.yarnpkg.com/@types/react/-/react-18.0.26.tgz#8ad59fc01fef8eaf5c74f4ea392621749f0b7917" - integrity sha512-hCR3PJQsAIXyxhTNSiDFY//LhnMZWpNNr5etoCqx/iUfGc5gXWtQR2Phl908jVR6uPXacojQWTg4qRpkxTuGug== + version "18.2.21" + resolved "https://registry.yarnpkg.com/@types/react/-/react-18.2.21.tgz#774c37fd01b522d0b91aed04811b58e4e0514ed9" + integrity sha512-neFKG/sBAwGxHgXiIxnbm3/AAVQ/cMRS93hvBpg8xYRbeQSPVABp9U2bRnPf0iI4+Ucdv3plSxKK+3CW2ENJxA== dependencies: "@types/prop-types" "*" "@types/scheduler" "*" @@ -2834,14 +2930,22 @@ integrity sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA== "@types/scheduler@*": - version "0.16.2" - resolved "https://registry.yarnpkg.com/@types/scheduler/-/scheduler-0.16.2.tgz#1a62f89525723dde24ba1b01b092bf5df8ad4d39" - integrity sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew== + version "0.16.3" + resolved "https://registry.yarnpkg.com/@types/scheduler/-/scheduler-0.16.3.tgz#cef09e3ec9af1d63d2a6cc5b383a737e24e6dcf5" + integrity sha512-5cJ8CB4yAx7BH1oMvdU0Jh9lrEXyPkar6F9G/ERswkCuvP4KQZfZkSjcMbAICCpQTN4OuZn8tz0HiKv9TGZgrQ== + +"@types/semver@^7.3.12", "@types/semver@^7.5.0": + version "7.5.1" + resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.5.1.tgz#0480eeb7221eb9bc398ad7432c9d7e14b1a5a367" + integrity sha512-cJRQXpObxfNKkFAZbJl2yjWtJCqELQIdShsogr1d2MilP8dKD9TE/nEKHkJgUNHdGKCQaf9HbIynuV2csLGVLg== -"@types/semver@^7.3.12": - version "7.3.13" - resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.3.13.tgz#da4bfd73f49bd541d28920ab0e2bf0ee80f71c91" - integrity sha512-21cFJr9z3g5dW8B0CVI9g2O9beqaThGQ6ZFBqHfwhzLDKUxaqTIy3vnfah/UPkfOiF2pLq+tGz+W8RyCskuslw== +"@types/send@*": + version "0.17.1" + resolved "https://registry.yarnpkg.com/@types/send/-/send-0.17.1.tgz#ed4932b8a2a805f1fe362a70f4e62d0ac994e301" + integrity sha512-Cwo8LE/0rnvX7kIIa3QHCkcuF21c05Ayb0ZfxPiv0W8VRiZiNW/WuRupHKpqqGVGf7SUA44QSOUKaEd9lIrd/Q== + dependencies: + "@types/mime" "^1" + "@types/node" "*" "@types/serve-index@^1.9.1": version "1.9.1" @@ -2851,10 +2955,11 @@ "@types/express" "*" "@types/serve-static@*", "@types/serve-static@^1.13.10": - version "1.15.0" - resolved "https://registry.yarnpkg.com/@types/serve-static/-/serve-static-1.15.0.tgz#c7930ff61afb334e121a9da780aac0d9b8f34155" - integrity sha512-z5xyF6uh8CbjAu9760KDKsH2FcDxZ2tFCsA4HIMWE6IkiYMXfVoa+4f9KX+FN0ZLsaMw1WNG2ETLA6N+/YA+cg== + version "1.15.2" + resolved "https://registry.yarnpkg.com/@types/serve-static/-/serve-static-1.15.2.tgz#3e5419ecd1e40e7405d34093f10befb43f63381a" + integrity sha512-J2LqtvFYCzaj8pVYKw8klQXrLLk7TBZmQ4ShlcdkELFKGwGMfevMLneMMRkMgZxotOD9wg497LpC7O8PcvAmfw== dependencies: + "@types/http-errors" "*" "@types/mime" "*" "@types/node" "*" @@ -2871,24 +2976,24 @@ integrity sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw== "@types/trusted-types@^2.0.2": - version "2.0.2" - resolved "https://registry.yarnpkg.com/@types/trusted-types/-/trusted-types-2.0.2.tgz#fc25ad9943bcac11cceb8168db4f275e0e72e756" - integrity sha512-F5DIZ36YVLE+PN+Zwws4kJogq47hNgX3Nx6WyDJ3kcplxyke3XIzB8uK5n/Lpm1HBsbGzd6nmGehL8cPekP+Tg== + version "2.0.3" + resolved "https://registry.yarnpkg.com/@types/trusted-types/-/trusted-types-2.0.3.tgz#a136f83b0758698df454e328759dbd3d44555311" + integrity sha512-NfQ4gyz38SL8sDNrSixxU2Os1a5xcdFxipAFxYEuLUlvU2uDwS4NUpsImcf1//SlWItCVMMLiylsxbmNMToV/g== -"@types/unist@*", "@types/unist@^2.0.0": - version "2.0.6" - resolved "https://registry.yarnpkg.com/@types/unist/-/unist-2.0.6.tgz#250a7b16c3b91f672a24552ec64678eeb1d3a08d" - integrity sha512-PBjIUxZHOuj0R15/xuwJYjFi+KZdNFrehocChv4g5hu6aFroHue8m0lBP0POdK2nKzbw0cgV1mws8+V/JAcEkQ== +"@types/unist@^2", "@types/unist@^2.0.0": + version "2.0.8" + resolved "https://registry.yarnpkg.com/@types/unist/-/unist-2.0.8.tgz#bb197b9639aa1a04cf464a617fe800cccd92ad5c" + integrity sha512-d0XxK3YTObnWVp6rZuev3c49+j4Lo8g4L1ZRm9z5L0xpoZycUPshHgczK5gsUMaZOstjVYYi09p5gYvUtfChYw== "@types/uuid@^9.0.0": - version "9.0.0" - resolved "https://registry.yarnpkg.com/@types/uuid/-/uuid-9.0.0.tgz#53ef263e5239728b56096b0a869595135b7952d2" - integrity sha512-kr90f+ERiQtKWMz5rP32ltJ/BtULDI5RVO0uavn1HQUOwjx0R1h0rnDYNL0CepF1zL5bSY6FISAfd9tOdDhU5Q== + version "9.0.3" + resolved "https://registry.yarnpkg.com/@types/uuid/-/uuid-9.0.3.tgz#6cdd939b4316b4f81625de9f06028d848c4a1533" + integrity sha512-taHQQH/3ZyI3zP8M/puluDEIEvtQHVYcC6y3N8ijFtAd28+Ey/G4sg1u2gB01S8MwybLOKAp9/yCMu/uR5l3Ug== -"@types/ws@^8.5.1": - version "8.5.3" - resolved "https://registry.yarnpkg.com/@types/ws/-/ws-8.5.3.tgz#7d25a1ffbecd3c4f2d35068d0b283c037003274d" - integrity sha512-6YOoWjruKj1uLf3INHH7D3qTXwFfEsg1kf3c0uDdSBJwfa/llkwIjrAGV7j7mVgGNbzTQ3HiHKKDXl6bJPD97w== +"@types/ws@^8.5.5": + version "8.5.5" + resolved "https://registry.yarnpkg.com/@types/ws/-/ws-8.5.5.tgz#af587964aa06682702ee6dcbc7be41a80e4b28eb" + integrity sha512-lwhs8hktwxSjf9UaZ9tG5M03PGogvFaH8gUgLNbN9HKIg0dvv6q+gkSuJ8HN4/VbyxkuLzCjlN7GquQ0gUJfIg== dependencies: "@types/node" "*" @@ -2898,237 +3003,323 @@ integrity sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA== "@types/yargs@^16.0.0": - version "16.0.4" - resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-16.0.4.tgz#26aad98dd2c2a38e421086ea9ad42b9e51642977" - integrity sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw== + version "16.0.5" + resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-16.0.5.tgz#12cc86393985735a283e387936398c2f9e5f88e3" + integrity sha512-AxO/ADJOBFJScHbWhq2xAhlWP24rY4aCEG/NFaMvbT3X2MgRsLjhjQwsn0Zi5zn0LG9jUhCCZMeX9Dkuw6k+vQ== dependencies: "@types/yargs-parser" "*" "@types/yargs@^17.0.8": - version "17.0.17" - resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-17.0.17.tgz#5672e5621f8e0fca13f433a8017aae4b7a2a03e7" - integrity sha512-72bWxFKTK6uwWJAVT+3rF6Jo6RTojiJ27FQo8Rf60AL+VZbzoVPnMFhKsUnbjR8A3BTCYQ7Mv3hnl8T0A+CX9g== + version "17.0.24" + resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-17.0.24.tgz#b3ef8d50ad4aa6aecf6ddc97c580a00f5aa11902" + integrity sha512-6i0aC7jV6QzQB8ne1joVZ0eSFIstHsCrobmOtghM11yGlH0j43FKL2UhWdELkyps0zuf7qVTUVCCR+tgSlyLLw== dependencies: "@types/yargs-parser" "*" "@typescript-eslint/eslint-plugin@^5.5.0": - version "5.47.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.47.0.tgz#dadb79df3b0499699b155839fd6792f16897d910" - integrity sha512-AHZtlXAMGkDmyLuLZsRpH3p4G/1iARIwc/T0vIem2YB+xW6pZaXYXzCBnZSF/5fdM97R9QqZWZ+h3iW10XgevQ== - dependencies: - "@typescript-eslint/scope-manager" "5.47.0" - "@typescript-eslint/type-utils" "5.47.0" - "@typescript-eslint/utils" "5.47.0" + version "5.62.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.62.0.tgz#aeef0328d172b9e37d9bab6dbc13b87ed88977db" + integrity sha512-TiZzBSJja/LbhNPvk6yc0JrX9XqhQ0hdh6M2svYfsHGejaKFIAGd9MQ+ERIMzLGlN/kZoYIgdxFV0PuljTKXag== + dependencies: + "@eslint-community/regexpp" "^4.4.0" + "@typescript-eslint/scope-manager" "5.62.0" + "@typescript-eslint/type-utils" "5.62.0" + "@typescript-eslint/utils" "5.62.0" debug "^4.3.4" + graphemer "^1.4.0" ignore "^5.2.0" natural-compare-lite "^1.4.0" - regexpp "^3.2.0" semver "^7.3.7" tsutils "^3.21.0" +"@typescript-eslint/eslint-plugin@^6.4.0": + version "6.5.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.5.0.tgz#5cee33edf0d45d5ec773e3b3111206b098ac8599" + integrity sha512-2pktILyjvMaScU6iK3925uvGU87E+N9rh372uGZgiMYwafaw9SXq86U04XPq3UH6tzRvNgBsub6x2DacHc33lw== + dependencies: + "@eslint-community/regexpp" "^4.5.1" + "@typescript-eslint/scope-manager" "6.5.0" + "@typescript-eslint/type-utils" "6.5.0" + "@typescript-eslint/utils" "6.5.0" + "@typescript-eslint/visitor-keys" "6.5.0" + debug "^4.3.4" + graphemer "^1.4.0" + ignore "^5.2.4" + natural-compare "^1.4.0" + semver "^7.5.4" + ts-api-utils "^1.0.1" + "@typescript-eslint/experimental-utils@^5.0.0": - version "5.47.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-5.47.0.tgz#60f26e62d948f9977488825730007ec350bc1e44" - integrity sha512-DAP8xOaTAJLxouU0QrATiw8o/OHxxbUBXtkf9v+bCCU6tbJUn24xwB1dHFw3b5wYq4XvC1z5lYEN0g/Rx1sjzA== + version "5.62.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-5.62.0.tgz#14559bf73383a308026b427a4a6129bae2146741" + integrity sha512-RTXpeB3eMkpoclG3ZHft6vG/Z30azNHuqY6wKPBHlVMZFuEvrtlEDe8gMqDb+SO+9hjC/pLekeSCryf9vMZlCw== dependencies: - "@typescript-eslint/utils" "5.47.0" + "@typescript-eslint/utils" "5.62.0" "@typescript-eslint/parser@^5.5.0": - version "5.47.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.47.0.tgz#62e83de93499bf4b500528f74bf2e0554e3a6c8d" - integrity sha512-udPU4ckK+R1JWCGdQC4Qa27NtBg7w020ffHqGyAK8pAgOVuNw7YaKXGChk+udh+iiGIJf6/E/0xhVXyPAbsczw== + version "5.62.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.62.0.tgz#1b63d082d849a2fcae8a569248fbe2ee1b8a56c7" + integrity sha512-VlJEV0fOQ7BExOsHYAGrgbEiZoi8D+Bl2+f6V2RrXerRSylnp+ZBHmPvaIa8cz0Ajx7WO7Z5RqfgYg7ED1nRhA== + dependencies: + "@typescript-eslint/scope-manager" "5.62.0" + "@typescript-eslint/types" "5.62.0" + "@typescript-eslint/typescript-estree" "5.62.0" + debug "^4.3.4" + +"@typescript-eslint/parser@^6.4.0", "@typescript-eslint/parser@^6.5.0": + version "6.5.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-6.5.0.tgz#3d6ed231c5e307c5f5f4a0d86893ec01e92b8c77" + integrity sha512-LMAVtR5GN8nY0G0BadkG0XIe4AcNMeyEy3DyhKGAh9k4pLSMBO7rF29JvDBpZGCmp5Pgz5RLHP6eCpSYZJQDuQ== dependencies: - "@typescript-eslint/scope-manager" "5.47.0" - "@typescript-eslint/types" "5.47.0" - "@typescript-eslint/typescript-estree" "5.47.0" + "@typescript-eslint/scope-manager" "6.5.0" + "@typescript-eslint/types" "6.5.0" + "@typescript-eslint/typescript-estree" "6.5.0" + "@typescript-eslint/visitor-keys" "6.5.0" debug "^4.3.4" -"@typescript-eslint/scope-manager@5.47.0": - version "5.47.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.47.0.tgz#f58144a6b0ff58b996f92172c488813aee9b09df" - integrity sha512-dvJab4bFf7JVvjPuh3sfBUWsiD73aiftKBpWSfi3sUkysDQ4W8x+ZcFpNp7Kgv0weldhpmMOZBjx1wKN8uWvAw== +"@typescript-eslint/scope-manager@5.62.0": + version "5.62.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.62.0.tgz#d9457ccc6a0b8d6b37d0eb252a23022478c5460c" + integrity sha512-VXuvVvZeQCQb5Zgf4HAxc04q5j+WrNAtNh9OwCsCgpKqESMTu3tF/jhZ3xG6T4NZwWl65Bg8KuS2uEvhSfLl0w== + dependencies: + "@typescript-eslint/types" "5.62.0" + "@typescript-eslint/visitor-keys" "5.62.0" + +"@typescript-eslint/scope-manager@6.5.0": + version "6.5.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-6.5.0.tgz#f2cb20895aaad41b3ad27cc3a338ce8598f261c5" + integrity sha512-A8hZ7OlxURricpycp5kdPTH3XnjG85UpJS6Fn4VzeoH4T388gQJ/PGP4ole5NfKt4WDVhmLaQ/dBLNDC4Xl/Kw== dependencies: - "@typescript-eslint/types" "5.47.0" - "@typescript-eslint/visitor-keys" "5.47.0" + "@typescript-eslint/types" "6.5.0" + "@typescript-eslint/visitor-keys" "6.5.0" -"@typescript-eslint/type-utils@5.47.0": - version "5.47.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-5.47.0.tgz#2b440979c574e317d3473225ae781f292c99e55d" - integrity sha512-1J+DFFrYoDUXQE1b7QjrNGARZE6uVhBqIvdaXTe5IN+NmEyD68qXR1qX1g2u4voA+nCaelQyG8w30SAOihhEYg== +"@typescript-eslint/type-utils@5.62.0": + version "5.62.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-5.62.0.tgz#286f0389c41681376cdad96b309cedd17d70346a" + integrity sha512-xsSQreu+VnfbqQpW5vnCJdq1Z3Q0U31qiWmRhr98ONQmcp/yhiPJFPq8MXiJVLiksmOKSjIldZzkebzHuCGzew== dependencies: - "@typescript-eslint/typescript-estree" "5.47.0" - "@typescript-eslint/utils" "5.47.0" + "@typescript-eslint/typescript-estree" "5.62.0" + "@typescript-eslint/utils" "5.62.0" debug "^4.3.4" tsutils "^3.21.0" -"@typescript-eslint/types@5.47.0": - version "5.47.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.47.0.tgz#67490def406eaa023dbbd8da42ee0d0c9b5229d3" - integrity sha512-eslFG0Qy8wpGzDdYKu58CEr3WLkjwC5Usa6XbuV89ce/yN5RITLe1O8e+WFEuxnfftHiJImkkOBADj58ahRxSg== +"@typescript-eslint/type-utils@6.5.0": + version "6.5.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-6.5.0.tgz#6d246c93739282bc0d2e623f28d0dec6cfcc38d7" + integrity sha512-f7OcZOkRivtujIBQ4yrJNIuwyCQO1OjocVqntl9dgSIZAdKqicj3xFDqDOzHDlGCZX990LqhLQXWRnQvsapq8A== + dependencies: + "@typescript-eslint/typescript-estree" "6.5.0" + "@typescript-eslint/utils" "6.5.0" + debug "^4.3.4" + ts-api-utils "^1.0.1" + +"@typescript-eslint/types@5.62.0": + version "5.62.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.62.0.tgz#258607e60effa309f067608931c3df6fed41fd2f" + integrity sha512-87NVngcbVXUahrRTqIK27gD2t5Cu1yuCXxbLcFtCzZGlfyVWWh8mLHkoxzjsB6DDNnvdL+fW8MiwPEJyGJQDgQ== + +"@typescript-eslint/types@6.5.0": + version "6.5.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-6.5.0.tgz#f4e55cfd99ac5346ea772770bf212a3e689a8f04" + integrity sha512-eqLLOEF5/lU8jW3Bw+8auf4lZSbbljHR2saKnYqON12G/WsJrGeeDHWuQePoEf9ro22+JkbPfWQwKEC5WwLQ3w== -"@typescript-eslint/typescript-estree@5.47.0": - version "5.47.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.47.0.tgz#ed971a11c5c928646d6ba7fc9dfdd6e997649aca" - integrity sha512-LxfKCG4bsRGq60Sqqu+34QT5qT2TEAHvSCCJ321uBWywgE2dS0LKcu5u+3sMGo+Vy9UmLOhdTw5JHzePV/1y4Q== +"@typescript-eslint/typescript-estree@5.62.0": + version "5.62.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.62.0.tgz#7d17794b77fabcac615d6a48fb143330d962eb9b" + integrity sha512-CmcQ6uY7b9y694lKdRB8FEel7JbU/40iSAPomu++SjLMntB+2Leay2LO6i8VnJk58MtE9/nQSFIH6jpyRWyYzA== dependencies: - "@typescript-eslint/types" "5.47.0" - "@typescript-eslint/visitor-keys" "5.47.0" + "@typescript-eslint/types" "5.62.0" + "@typescript-eslint/visitor-keys" "5.62.0" debug "^4.3.4" globby "^11.1.0" is-glob "^4.0.3" semver "^7.3.7" tsutils "^3.21.0" -"@typescript-eslint/utils@5.47.0", "@typescript-eslint/utils@^5.13.0": - version "5.47.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.47.0.tgz#b5005f7d2696769a1fdc1e00897005a25b3a0ec7" - integrity sha512-U9xcc0N7xINrCdGVPwABjbAKqx4GK67xuMV87toI+HUqgXj26m6RBp9UshEXcTrgCkdGYFzgKLt8kxu49RilDw== +"@typescript-eslint/typescript-estree@6.5.0": + version "6.5.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-6.5.0.tgz#1cef6bc822585e9ef89d88834bc902d911d747ed" + integrity sha512-q0rGwSe9e5Kk/XzliB9h2LBc9tmXX25G0833r7kffbl5437FPWb2tbpIV9wAATebC/018pGa9fwPDuvGN+LxWQ== + dependencies: + "@typescript-eslint/types" "6.5.0" + "@typescript-eslint/visitor-keys" "6.5.0" + debug "^4.3.4" + globby "^11.1.0" + is-glob "^4.0.3" + semver "^7.5.4" + ts-api-utils "^1.0.1" + +"@typescript-eslint/utils@5.62.0", "@typescript-eslint/utils@^5.58.0": + version "5.62.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.62.0.tgz#141e809c71636e4a75daa39faed2fb5f4b10df86" + integrity sha512-n8oxjeb5aIbPFEtmQxQYOLI0i9n5ySBEY/ZEHHZqKQSFnxio1rv6dthascc9dLuwrL0RC5mPCxB7vnAVGAYWAQ== dependencies: + "@eslint-community/eslint-utils" "^4.2.0" "@types/json-schema" "^7.0.9" "@types/semver" "^7.3.12" - "@typescript-eslint/scope-manager" "5.47.0" - "@typescript-eslint/types" "5.47.0" - "@typescript-eslint/typescript-estree" "5.47.0" + "@typescript-eslint/scope-manager" "5.62.0" + "@typescript-eslint/types" "5.62.0" + "@typescript-eslint/typescript-estree" "5.62.0" eslint-scope "^5.1.1" - eslint-utils "^3.0.0" semver "^7.3.7" -"@typescript-eslint/visitor-keys@5.47.0": - version "5.47.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.47.0.tgz#4aca4efbdf6209c154df1f7599852d571b80bb45" - integrity sha512-ByPi5iMa6QqDXe/GmT/hR6MZtVPi0SqMQPDx15FczCBXJo/7M8T88xReOALAfpBLm+zxpPfmhuEvPb577JRAEg== - dependencies: - "@typescript-eslint/types" "5.47.0" +"@typescript-eslint/utils@6.5.0": + version "6.5.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-6.5.0.tgz#6668bee4f7f24978b11df8a2ea42d56eebc4662c" + integrity sha512-9nqtjkNykFzeVtt9Pj6lyR9WEdd8npPhhIPM992FWVkZuS6tmxHfGVnlUcjpUP2hv8r4w35nT33mlxd+Be1ACQ== + dependencies: + "@eslint-community/eslint-utils" "^4.4.0" + "@types/json-schema" "^7.0.12" + "@types/semver" "^7.5.0" + "@typescript-eslint/scope-manager" "6.5.0" + "@typescript-eslint/types" "6.5.0" + "@typescript-eslint/typescript-estree" "6.5.0" + semver "^7.5.4" + +"@typescript-eslint/visitor-keys@5.62.0": + version "5.62.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.62.0.tgz#2174011917ce582875954ffe2f6912d5931e353e" + integrity sha512-07ny+LHRzQXepkGg6w0mFY41fVUNBrL2Roj/++7V1txKugfjm/Ci/qSND03r2RhlJhJYMcTn9AhhSSqQp0Ysyw== + dependencies: + "@typescript-eslint/types" "5.62.0" eslint-visitor-keys "^3.3.0" +"@typescript-eslint/visitor-keys@6.5.0": + version "6.5.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-6.5.0.tgz#1a6f474a0170a447b76f0699ce6700110fd11436" + integrity sha512-yCB/2wkbv3hPsh02ZS8dFQnij9VVQXJMN/gbQsaaY+zxALkZnxa/wagvLEFsAWMPv7d7lxQmNsIzGU1w/T/WyA== + dependencies: + "@typescript-eslint/types" "6.5.0" + eslint-visitor-keys "^3.4.1" + "@uiw/react-textarea-code-editor@^2.1.1": - version "2.1.1" - resolved "https://registry.yarnpkg.com/@uiw/react-textarea-code-editor/-/react-textarea-code-editor-2.1.1.tgz#59a7e0c8b04d7aa36f4997a81dbbbb9004d324e3" - integrity sha512-vFUb58Dj8SCAcAL264ik6rFMzHmOAI4TG8BInu9avCdJ1ugRhrwD+RA7FKQN2xAoBokF9JJacyTqx+EUXIOg2g== + version "2.1.7" + resolved "https://registry.yarnpkg.com/@uiw/react-textarea-code-editor/-/react-textarea-code-editor-2.1.7.tgz#f67a190e3f2b4627268e0d17600bbbe396545c33" + integrity sha512-mh3+PLiWPM9eclpdQ16jhm1mlS9IEwwiNkfQX34RACB9M0p7JoSI8Tq0T+3sTgbGzgwkrruOvsXUY6NKYLohZQ== dependencies: "@babel/runtime" "^7.18.6" rehype "~12.0.1" rehype-prism-plus "1.5.0" -"@webassemblyjs/ast@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.11.1.tgz#2bfd767eae1a6996f432ff7e8d7fc75679c0b6a7" - integrity sha512-ukBh14qFLjxTQNTXocdyksN5QdM28S1CxHt2rdskFyL+xFV7VremuBLVbmCePj+URalXBENx/9Lm7lnhihtCSw== +"@webassemblyjs/ast@1.11.6", "@webassemblyjs/ast@^1.11.5": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.11.6.tgz#db046555d3c413f8966ca50a95176a0e2c642e24" + integrity sha512-IN1xI7PwOvLPgjcf180gC1bqn3q/QaOCwYUahIOhbYUu8KA/3tw2RT/T0Gidi1l7Hhj5D/INhJxiICObqpMu4Q== dependencies: - "@webassemblyjs/helper-numbers" "1.11.1" - "@webassemblyjs/helper-wasm-bytecode" "1.11.1" + "@webassemblyjs/helper-numbers" "1.11.6" + "@webassemblyjs/helper-wasm-bytecode" "1.11.6" -"@webassemblyjs/floating-point-hex-parser@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.1.tgz#f6c61a705f0fd7a6aecaa4e8198f23d9dc179e4f" - integrity sha512-iGRfyc5Bq+NnNuX8b5hwBrRjzf0ocrJPI6GWFodBFzmFnyvrQ83SHKhmilCU/8Jv67i4GJZBMhEzltxzcNagtQ== +"@webassemblyjs/floating-point-hex-parser@1.11.6": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.6.tgz#dacbcb95aff135c8260f77fa3b4c5fea600a6431" + integrity sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw== -"@webassemblyjs/helper-api-error@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.1.tgz#1a63192d8788e5c012800ba6a7a46c705288fd16" - integrity sha512-RlhS8CBCXfRUR/cwo2ho9bkheSXG0+NwooXcc3PAILALf2QLdFyj7KGsKRbVc95hZnhnERon4kW/D3SZpp6Tcg== +"@webassemblyjs/helper-api-error@1.11.6": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.6.tgz#6132f68c4acd59dcd141c44b18cbebbd9f2fa768" + integrity sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q== -"@webassemblyjs/helper-buffer@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.1.tgz#832a900eb444884cde9a7cad467f81500f5e5ab5" - integrity sha512-gwikF65aDNeeXa8JxXa2BAk+REjSyhrNC9ZwdT0f8jc4dQQeDQ7G4m0f2QCLPJiMTTO6wfDmRmj/pW0PsUvIcA== +"@webassemblyjs/helper-buffer@1.11.6": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.6.tgz#b66d73c43e296fd5e88006f18524feb0f2c7c093" + integrity sha512-z3nFzdcp1mb8nEOFFk8DrYLpHvhKC3grJD2ardfKOzmbmJvEf/tPIqCY+sNcwZIY8ZD7IkB2l7/pqhUhqm7hLA== -"@webassemblyjs/helper-numbers@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.1.tgz#64d81da219fbbba1e3bd1bfc74f6e8c4e10a62ae" - integrity sha512-vDkbxiB8zfnPdNK9Rajcey5C0w+QJugEglN0of+kmO8l7lDb77AnlKYQF7aarZuCrv+l0UvqL+68gSDr3k9LPQ== +"@webassemblyjs/helper-numbers@1.11.6": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.6.tgz#cbce5e7e0c1bd32cf4905ae444ef64cea919f1b5" + integrity sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g== dependencies: - "@webassemblyjs/floating-point-hex-parser" "1.11.1" - "@webassemblyjs/helper-api-error" "1.11.1" + "@webassemblyjs/floating-point-hex-parser" "1.11.6" + "@webassemblyjs/helper-api-error" "1.11.6" "@xtuc/long" "4.2.2" -"@webassemblyjs/helper-wasm-bytecode@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.1.tgz#f328241e41e7b199d0b20c18e88429c4433295e1" - integrity sha512-PvpoOGiJwXeTrSf/qfudJhwlvDQxFgelbMqtq52WWiXC6Xgg1IREdngmPN3bs4RoO83PnL/nFrxucXj1+BX62Q== +"@webassemblyjs/helper-wasm-bytecode@1.11.6": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.6.tgz#bb2ebdb3b83aa26d9baad4c46d4315283acd51e9" + integrity sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA== -"@webassemblyjs/helper-wasm-section@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.1.tgz#21ee065a7b635f319e738f0dd73bfbda281c097a" - integrity sha512-10P9No29rYX1j7F3EVPX3JvGPQPae+AomuSTPiF9eBQeChHI6iqjMIwR9JmOJXwpnn/oVGDk7I5IlskuMwU/pg== +"@webassemblyjs/helper-wasm-section@1.11.6": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.6.tgz#ff97f3863c55ee7f580fd5c41a381e9def4aa577" + integrity sha512-LPpZbSOwTpEC2cgn4hTydySy1Ke+XEu+ETXuoyvuyezHO3Kjdu90KK95Sh9xTbmjrCsUwvWwCOQQNta37VrS9g== dependencies: - "@webassemblyjs/ast" "1.11.1" - "@webassemblyjs/helper-buffer" "1.11.1" - "@webassemblyjs/helper-wasm-bytecode" "1.11.1" - "@webassemblyjs/wasm-gen" "1.11.1" + "@webassemblyjs/ast" "1.11.6" + "@webassemblyjs/helper-buffer" "1.11.6" + "@webassemblyjs/helper-wasm-bytecode" "1.11.6" + "@webassemblyjs/wasm-gen" "1.11.6" -"@webassemblyjs/ieee754@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/ieee754/-/ieee754-1.11.1.tgz#963929e9bbd05709e7e12243a099180812992614" - integrity sha512-hJ87QIPtAMKbFq6CGTkZYJivEwZDbQUgYd3qKSadTNOhVY7p+gfP6Sr0lLRVTaG1JjFj+r3YchoqRYxNH3M0GQ== +"@webassemblyjs/ieee754@1.11.6": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/ieee754/-/ieee754-1.11.6.tgz#bb665c91d0b14fffceb0e38298c329af043c6e3a" + integrity sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg== dependencies: "@xtuc/ieee754" "^1.2.0" -"@webassemblyjs/leb128@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/leb128/-/leb128-1.11.1.tgz#ce814b45574e93d76bae1fb2644ab9cdd9527aa5" - integrity sha512-BJ2P0hNZ0u+Th1YZXJpzW6miwqQUGcIHT1G/sf72gLVD9DZ5AdYTqPNbHZh6K1M5VmKvFXwGSWZADz+qBWxeRw== +"@webassemblyjs/leb128@1.11.6": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/leb128/-/leb128-1.11.6.tgz#70e60e5e82f9ac81118bc25381a0b283893240d7" + integrity sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ== dependencies: "@xtuc/long" "4.2.2" -"@webassemblyjs/utf8@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/utf8/-/utf8-1.11.1.tgz#d1f8b764369e7c6e6bae350e854dec9a59f0a3ff" - integrity sha512-9kqcxAEdMhiwQkHpkNiorZzqpGrodQQ2IGrHHxCy+Ozng0ofyMA0lTqiLkVs1uzTRejX+/O0EOT7KxqVPuXosQ== - -"@webassemblyjs/wasm-edit@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.1.tgz#ad206ebf4bf95a058ce9880a8c092c5dec8193d6" - integrity sha512-g+RsupUC1aTHfR8CDgnsVRVZFJqdkFHpsHMfJuWQzWU3tvnLC07UqHICfP+4XyL2tnr1amvl1Sdp06TnYCmVkA== - dependencies: - "@webassemblyjs/ast" "1.11.1" - "@webassemblyjs/helper-buffer" "1.11.1" - "@webassemblyjs/helper-wasm-bytecode" "1.11.1" - "@webassemblyjs/helper-wasm-section" "1.11.1" - "@webassemblyjs/wasm-gen" "1.11.1" - "@webassemblyjs/wasm-opt" "1.11.1" - "@webassemblyjs/wasm-parser" "1.11.1" - "@webassemblyjs/wast-printer" "1.11.1" - -"@webassemblyjs/wasm-gen@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.1.tgz#86c5ea304849759b7d88c47a32f4f039ae3c8f76" - integrity sha512-F7QqKXwwNlMmsulj6+O7r4mmtAlCWfO/0HdgOxSklZfQcDu0TpLiD1mRt/zF25Bk59FIjEuGAIyn5ei4yMfLhA== - dependencies: - "@webassemblyjs/ast" "1.11.1" - "@webassemblyjs/helper-wasm-bytecode" "1.11.1" - "@webassemblyjs/ieee754" "1.11.1" - "@webassemblyjs/leb128" "1.11.1" - "@webassemblyjs/utf8" "1.11.1" - -"@webassemblyjs/wasm-opt@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.1.tgz#657b4c2202f4cf3b345f8a4c6461c8c2418985f2" - integrity sha512-VqnkNqnZlU5EB64pp1l7hdm3hmQw7Vgqa0KF/KCNO9sIpI6Fk6brDEiX+iCOYrvMuBWDws0NkTOxYEb85XQHHw== - dependencies: - "@webassemblyjs/ast" "1.11.1" - "@webassemblyjs/helper-buffer" "1.11.1" - "@webassemblyjs/wasm-gen" "1.11.1" - "@webassemblyjs/wasm-parser" "1.11.1" - -"@webassemblyjs/wasm-parser@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.1.tgz#86ca734534f417e9bd3c67c7a1c75d8be41fb199" - integrity sha512-rrBujw+dJu32gYB7/Lup6UhdkPx9S9SnobZzRVL7VcBH9Bt9bCBLEuX/YXOOtBsOZ4NQrRykKhffRWHvigQvOA== - dependencies: - "@webassemblyjs/ast" "1.11.1" - "@webassemblyjs/helper-api-error" "1.11.1" - "@webassemblyjs/helper-wasm-bytecode" "1.11.1" - "@webassemblyjs/ieee754" "1.11.1" - "@webassemblyjs/leb128" "1.11.1" - "@webassemblyjs/utf8" "1.11.1" - -"@webassemblyjs/wast-printer@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-printer/-/wast-printer-1.11.1.tgz#d0c73beda8eec5426f10ae8ef55cee5e7084c2f0" - integrity sha512-IQboUWM4eKzWW+N/jij2sRatKMh99QEelo3Eb2q0qXkvPRISAj8Qxtmw5itwqK+TTkBuUIE45AxYPToqPtL5gg== - dependencies: - "@webassemblyjs/ast" "1.11.1" +"@webassemblyjs/utf8@1.11.6": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/utf8/-/utf8-1.11.6.tgz#90f8bc34c561595fe156603be7253cdbcd0fab5a" + integrity sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA== + +"@webassemblyjs/wasm-edit@^1.11.5": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.6.tgz#c72fa8220524c9b416249f3d94c2958dfe70ceab" + integrity sha512-Ybn2I6fnfIGuCR+Faaz7YcvtBKxvoLV3Lebn1tM4o/IAJzmi9AWYIPWpyBfU8cC+JxAO57bk4+zdsTjJR+VTOw== + dependencies: + "@webassemblyjs/ast" "1.11.6" + "@webassemblyjs/helper-buffer" "1.11.6" + "@webassemblyjs/helper-wasm-bytecode" "1.11.6" + "@webassemblyjs/helper-wasm-section" "1.11.6" + "@webassemblyjs/wasm-gen" "1.11.6" + "@webassemblyjs/wasm-opt" "1.11.6" + "@webassemblyjs/wasm-parser" "1.11.6" + "@webassemblyjs/wast-printer" "1.11.6" + +"@webassemblyjs/wasm-gen@1.11.6": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.6.tgz#fb5283e0e8b4551cc4e9c3c0d7184a65faf7c268" + integrity sha512-3XOqkZP/y6B4F0PBAXvI1/bky7GryoogUtfwExeP/v7Nzwo1QLcq5oQmpKlftZLbT+ERUOAZVQjuNVak6UXjPA== + dependencies: + "@webassemblyjs/ast" "1.11.6" + "@webassemblyjs/helper-wasm-bytecode" "1.11.6" + "@webassemblyjs/ieee754" "1.11.6" + "@webassemblyjs/leb128" "1.11.6" + "@webassemblyjs/utf8" "1.11.6" + +"@webassemblyjs/wasm-opt@1.11.6": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.6.tgz#d9a22d651248422ca498b09aa3232a81041487c2" + integrity sha512-cOrKuLRE7PCe6AsOVl7WasYf3wbSo4CeOk6PkrjS7g57MFfVUF9u6ysQBBODX0LdgSvQqRiGz3CXvIDKcPNy4g== + dependencies: + "@webassemblyjs/ast" "1.11.6" + "@webassemblyjs/helper-buffer" "1.11.6" + "@webassemblyjs/wasm-gen" "1.11.6" + "@webassemblyjs/wasm-parser" "1.11.6" + +"@webassemblyjs/wasm-parser@1.11.6", "@webassemblyjs/wasm-parser@^1.11.5": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.6.tgz#bb85378c527df824004812bbdb784eea539174a1" + integrity sha512-6ZwPeGzMJM3Dqp3hCsLgESxBGtT/OeCvCZ4TA1JUPYgmhAx38tTPR9JaKy0S5H3evQpO/h2uWs2j6Yc/fjkpTQ== + dependencies: + "@webassemblyjs/ast" "1.11.6" + "@webassemblyjs/helper-api-error" "1.11.6" + "@webassemblyjs/helper-wasm-bytecode" "1.11.6" + "@webassemblyjs/ieee754" "1.11.6" + "@webassemblyjs/leb128" "1.11.6" + "@webassemblyjs/utf8" "1.11.6" + +"@webassemblyjs/wast-printer@1.11.6": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-printer/-/wast-printer-1.11.6.tgz#a7bf8dd7e362aeb1668ff43f35cb849f188eff20" + integrity sha512-JM7AhRcE+yW2GWYaKeHL5vt4xqee5N2WcezptmgyhNS+ScggqcT1OtXykhAb13Sn5Yas0j2uv9tHgrjwvzAP4A== + dependencies: + "@webassemblyjs/ast" "1.11.6" "@xtuc/long" "4.2.2" "@xtuc/ieee754@^1.2.0": @@ -3167,39 +3358,30 @@ acorn-globals@^6.0.0: acorn "^7.1.1" acorn-walk "^7.1.1" -acorn-import-assertions@^1.7.6: - version "1.8.0" - resolved "https://registry.yarnpkg.com/acorn-import-assertions/-/acorn-import-assertions-1.8.0.tgz#ba2b5939ce62c238db6d93d81c9b111b29b855e9" - integrity sha512-m7VZ3jwz4eK6A4Vtt8Ew1/mNbP24u0FhdyfA7fSvnJR6LMdfOYnmuIrrJAgrYfYJ10F/otaHTtrtrtmHdMNzEw== +acorn-import-assertions@^1.9.0: + version "1.9.0" + resolved "https://registry.yarnpkg.com/acorn-import-assertions/-/acorn-import-assertions-1.9.0.tgz#507276249d684797c84e0734ef84860334cfb1ac" + integrity sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA== acorn-jsx@^5.3.2: version "5.3.2" resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937" integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ== -acorn-node@^1.8.2: - version "1.8.2" - resolved "https://registry.yarnpkg.com/acorn-node/-/acorn-node-1.8.2.tgz#114c95d64539e53dede23de8b9d96df7c7ae2af8" - integrity sha512-8mt+fslDufLYntIoPAaIMUe/lrbrehIiwmR3t2k9LljIzoigEPF27eLk2hy8zSGzmR/ogr7zbRKINMo1u0yh5A== - dependencies: - acorn "^7.0.0" - acorn-walk "^7.0.0" - xtend "^4.0.2" - -acorn-walk@^7.0.0, acorn-walk@^7.1.1: +acorn-walk@^7.1.1: version "7.2.0" resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-7.2.0.tgz#0de889a601203909b0fbe07b8938dc21d2e967bc" integrity sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA== -acorn@^7.0.0, acorn@^7.1.1: +acorn@^7.1.1: version "7.4.1" resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa" integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A== -acorn@^8.2.4, acorn@^8.5.0, acorn@^8.7.1, acorn@^8.8.0: - version "8.8.1" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.8.1.tgz#0a3f9cbecc4ec3bea6f0a80b66ae8dd2da250b73" - integrity sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA== +acorn@^8.2.4, acorn@^8.7.1, acorn@^8.8.2, acorn@^8.9.0: + version "8.10.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.10.0.tgz#8be5b3907a67221a81ab23c7889c4c5526b62ec5" + integrity sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw== address@^1.0.1, address@^1.1.2: version "1.2.2" @@ -3245,14 +3427,14 @@ ajv-keywords@^3.4.1, ajv-keywords@^3.5.2: resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.5.2.tgz#31f29da5ab6e00d1c2d329acf7b5929614d5014d" integrity sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ== -ajv-keywords@^5.0.0: +ajv-keywords@^5.1.0: version "5.1.0" resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-5.1.0.tgz#69d4d385a4733cdbeab44964a1170a88f87f0e16" integrity sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw== dependencies: fast-deep-equal "^3.1.3" -ajv@^6.10.0, ajv@^6.12.2, ajv@^6.12.4, ajv@^6.12.5: +ajv@^6.12.2, ajv@^6.12.4, ajv@^6.12.5: version "6.12.6" resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== @@ -3262,10 +3444,10 @@ ajv@^6.10.0, ajv@^6.12.2, ajv@^6.12.4, ajv@^6.12.5: json-schema-traverse "^0.4.1" uri-js "^4.2.2" -ajv@^8.0.0, ajv@^8.6.0, ajv@^8.6.1, ajv@^8.8.0: - version "8.11.2" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.11.2.tgz#aecb20b50607acf2569b6382167b65a96008bb78" - integrity sha512-E4bfmKAhGiSTvMfL1Myyycaub+cUEU2/IvpylXkUu7CHBkBj1f/ikdzbD7YQ6FKUbixDxeYvB/xY4fvyroDlQg== +ajv@^8.0.0, ajv@^8.6.0, ajv@^8.6.1, ajv@^8.9.0: + version "8.12.0" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.12.0.tgz#d1a0527323e22f53562c567c00991577dfbe19d1" + integrity sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA== dependencies: fast-deep-equal "^3.1.1" json-schema-traverse "^1.0.0" @@ -3313,6 +3495,11 @@ ansi-styles@^5.0.0: resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-5.2.0.tgz#07449690ad45777d1924ac2abb2fc8895dba836b" integrity sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA== +any-promise@^1.0.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/any-promise/-/any-promise-1.3.0.tgz#abc6afeedcea52e809cdc0376aed3ce39635d17f" + integrity sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A== + anymatch@^3.0.3, anymatch@~3.1.2: version "3.1.3" resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.3.tgz#790c58b19ba1720a84205b57c618d5ad8524973e" @@ -3338,13 +3525,20 @@ argparse@^2.0.1: resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== -aria-query@^4.2.2: - version "4.2.2" - resolved "https://registry.yarnpkg.com/aria-query/-/aria-query-4.2.2.tgz#0d2ca6c9aceb56b8977e9fed6aed7e15bbd2f83b" - integrity sha512-o/HelwhuKpTj/frsOsbNLNgnNGVIFsVP/SW2BSF14gVl7kAfMOJ6/8wUAUvG1R1NHKrfG+2sHZTu0yauT1qBrA== +aria-query@^5.1.3: + version "5.3.0" + resolved "https://registry.yarnpkg.com/aria-query/-/aria-query-5.3.0.tgz#650c569e41ad90b51b3d7df5e5eed1c7549c103e" + integrity sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A== + dependencies: + dequal "^2.0.3" + +array-buffer-byte-length@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/array-buffer-byte-length/-/array-buffer-byte-length-1.0.0.tgz#fabe8bc193fea865f317fe7807085ee0dee5aead" + integrity sha512-LPuwb2P+NrQw3XhxGc36+XSvuBPopovXYTR9Ew++Du9Yb/bx5AzBfrIsBoj0EZUifjQU+sHL21sseZ3jerWO/A== dependencies: - "@babel/runtime" "^7.10.2" - "@babel/runtime-corejs3" "^7.10.2" + call-bind "^1.0.2" + is-array-buffer "^3.0.1" array-flatten@1.1.1: version "1.1.1" @@ -3356,7 +3550,7 @@ array-flatten@^2.1.2: resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-2.1.2.tgz#24ef80a28c1a893617e2149b0c6d0d788293b099" integrity sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ== -array-includes@^3.1.4, array-includes@^3.1.5, array-includes@^3.1.6: +array-includes@^3.1.6: version "3.1.6" resolved "https://registry.yarnpkg.com/array-includes/-/array-includes-3.1.6.tgz#9e9e720e194f198266ba9e18c29e6a9b0e4b225f" integrity sha512-sgTbLvL6cNnw24FnbaDyjmvddQ2ML8arZsgaJhoABMoplz/4QRhtrYS+alr1BUM1Bwp6dhx8vVCBSLG+StwOFw== @@ -3372,7 +3566,18 @@ array-union@^2.1.0: resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d" integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw== -array.prototype.flat@^1.2.5: +array.prototype.findlastindex@^1.2.2: + version "1.2.3" + resolved "https://registry.yarnpkg.com/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.3.tgz#b37598438f97b579166940814e2c0493a4f50207" + integrity sha512-LzLoiOMAxvy+Gd3BAq3B7VeIgPdo+Q8hthvKtXybMvRV0jrXfJM/t8mw7nNlpEcVlVUnCnM2KSX4XU5HmpodOA== + dependencies: + call-bind "^1.0.2" + define-properties "^1.2.0" + es-abstract "^1.22.1" + es-shim-unscopables "^1.0.0" + get-intrinsic "^1.2.1" + +array.prototype.flat@^1.3.1: version "1.3.1" resolved "https://registry.yarnpkg.com/array.prototype.flat/-/array.prototype.flat-1.3.1.tgz#ffc6576a7ca3efc2f46a143b9d1dda9b4b3cf5e2" integrity sha512-roTU0KWIOmJ4DRLmwKd19Otg0/mT3qPNt0Qb3GWW8iObuZXxrjB/pzn0R3hqpRSWg4HCwqx+0vwOnWnvlOyeIA== @@ -3393,13 +3598,13 @@ array.prototype.flatmap@^1.3.1: es-shim-unscopables "^1.0.0" array.prototype.reduce@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/array.prototype.reduce/-/array.prototype.reduce-1.0.5.tgz#6b20b0daa9d9734dd6bc7ea66b5bbce395471eac" - integrity sha512-kDdugMl7id9COE8R7MHF5jWk7Dqt/fs4Pv+JXoICnYwqpjjjbUurz6w5fT5IG6brLdJhv6/VoHB0H7oyIBXd+Q== + version "1.0.6" + resolved "https://registry.yarnpkg.com/array.prototype.reduce/-/array.prototype.reduce-1.0.6.tgz#63149931808c5fc1e1354814923d92d45f7d96d5" + integrity sha512-UW+Mz8LG/sPSU8jRDCjVr6J/ZKAGpHfwrZ6kWTG5qCxIEiXdVshqGnu5vEZA8S1y6X4aCSbQZ0/EEsfvEvBiSg== dependencies: call-bind "^1.0.2" - define-properties "^1.1.4" - es-abstract "^1.20.4" + define-properties "^1.2.0" + es-abstract "^1.22.1" es-array-method-boxes-properly "^1.0.0" is-string "^1.0.7" @@ -3414,6 +3619,18 @@ array.prototype.tosorted@^1.1.1: es-shim-unscopables "^1.0.0" get-intrinsic "^1.1.3" +arraybuffer.prototype.slice@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.1.tgz#9b5ea3868a6eebc30273da577eb888381c0044bb" + integrity sha512-09x0ZWFEjj4WD8PDbykUwo3t9arLn8NIzmmYEJFpYekOAQjpkGSyrQhNoRTcwwcFRu+ycWF78QZ63oWTqSjBcw== + dependencies: + array-buffer-byte-length "^1.0.0" + call-bind "^1.0.2" + define-properties "^1.2.0" + get-intrinsic "^1.2.1" + is-array-buffer "^3.0.2" + is-shared-array-buffer "^1.0.2" + asap@~2.0.6: version "2.0.6" resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46" @@ -3429,6 +3646,13 @@ async@^3.2.3: resolved "https://registry.yarnpkg.com/async/-/async-3.2.4.tgz#2d22e00f8cddeb5fde5dd33522b56d1cf569a81c" integrity sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ== +asynciterator.prototype@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/asynciterator.prototype/-/asynciterator.prototype-1.0.0.tgz#8c5df0514936cdd133604dfcc9d3fb93f09b2b62" + integrity sha512-wwHYEIS0Q80f5mosx3L/dfG5t5rjEa9Ft51GTaNt862EnpyGHpgz2RkZvLPp1oF5TnAiTohkEKVEu8pQPJI7Vg== + dependencies: + has-symbols "^1.0.3" + asynckit@^0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" @@ -3445,43 +3669,50 @@ attr-accept@^2.0.0: integrity sha512-7prDjvt9HmqiZ0cl5CRjtS84sEyhsHP2coDkaZKRKVfCDo9s7iw7ChVmar78Gu9pC4SoR/28wFu/G5JJhTnqEg== autoprefixer@^10.4.13: - version "10.4.13" - resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-10.4.13.tgz#b5136b59930209a321e9fa3dca2e7c4d223e83a8" - integrity sha512-49vKpMqcZYsJjwotvt4+h/BCjJVnhGwcLpDt5xkcaOG3eLrG/HUYLagrihYsQ+qrIBgIzX1Rw7a6L8I/ZA1Atg== + version "10.4.15" + resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-10.4.15.tgz#a1230f4aeb3636b89120b34a1f513e2f6834d530" + integrity sha512-KCuPB8ZCIqFdA4HwKXsvz7j6gvSDNhDP7WnUjBleRkKjPdvCmHFuQ77ocavI8FT6NdvlBnE2UFr2H4Mycn8Vew== dependencies: - browserslist "^4.21.4" - caniuse-lite "^1.0.30001426" + browserslist "^4.21.10" + caniuse-lite "^1.0.30001520" fraction.js "^4.2.0" normalize-range "^0.1.2" picocolors "^1.0.0" postcss-value-parser "^4.2.0" -axe-core@^4.4.3: - version "4.6.1" - resolved "https://registry.yarnpkg.com/axe-core/-/axe-core-4.6.1.tgz#79cccdee3e3ab61a8f42c458d4123a6768e6fbce" - integrity sha512-lCZN5XRuOnpG4bpMq8v0khrWtUOn+i8lZSb6wHZH56ZfbIEv6XwJV84AAueh9/zi7qPVJ/E4yz6fmsiyOmXR4w== +available-typed-arrays@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz#92f95616501069d07d10edb2fc37d3e1c65123b7" + integrity sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw== + +axe-core@^4.6.2: + version "4.7.2" + resolved "https://registry.yarnpkg.com/axe-core/-/axe-core-4.7.2.tgz#040a7342b20765cb18bb50b628394c21bccc17a0" + integrity sha512-zIURGIS1E1Q4pcrMjp+nnEh+16G56eG/MUllJH8yEvw7asDo7Ac9uhC9KIH5jzpITueEZolfYglnCGIuSBz39g== axios-mock-adapter@^1.21.2: - version "1.21.2" - resolved "https://registry.yarnpkg.com/axios-mock-adapter/-/axios-mock-adapter-1.21.2.tgz#87a48f80aa89bb1ab1ad630fa467975e30aa4721" - integrity sha512-jzyNxU3JzB2XVhplZboUcF0YDs7xuExzoRSHXPHr+UQajaGmcTqvkkUADgkVI2WkGlpZ1zZlMVdcTMU0ejV8zQ== + version "1.21.5" + resolved "https://registry.yarnpkg.com/axios-mock-adapter/-/axios-mock-adapter-1.21.5.tgz#dd85081717a759f88509c20515082dc09c1cedd7" + integrity sha512-5NI1V/VK+8+JeTF8niqOowuysA4b8mGzdlMN/QnTnoXbYh4HZSNiopsDclN2g/m85+G++IrEtUdZaQ3GnaMsSA== dependencies: fast-deep-equal "^3.1.3" is-buffer "^2.0.5" axios@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/axios/-/axios-1.2.1.tgz#44cf04a3c9f0c2252ebd85975361c026cb9f864a" - integrity sha512-I88cFiGu9ryt/tfVEi4kX2SITsvDddTajXTOFmt2uK1ZVA8LytjtdeyefdQWEf5PU8w+4SSJDoYnggflB5tW4A== + version "1.5.0" + resolved "https://registry.yarnpkg.com/axios/-/axios-1.5.0.tgz#f02e4af823e2e46a9768cfc74691fdd0517ea267" + integrity sha512-D4DdjDo5CY50Qms0qGQTTw6Q44jl7zRwY7bthds06pUGfChBCTcQs+N743eFWGEd6pRTMd6A+I87aWyFV5wiZQ== dependencies: follow-redirects "^1.15.0" form-data "^4.0.0" proxy-from-env "^1.1.0" -axobject-query@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/axobject-query/-/axobject-query-2.2.0.tgz#943d47e10c0b704aa42275e20edf3722648989be" - integrity sha512-Td525n+iPOOyUQIeBfcASuG6uJsDOITl7Mds5gFyerkWiX7qhUTdYUBlSgNMyVqtSJqwpt1kXGLdUt6SykLMRA== +axobject-query@^3.1.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/axobject-query/-/axobject-query-3.2.1.tgz#39c378a6e3b06ca679f29138151e45b2b32da62a" + integrity sha512-jsyHu61e6N4Vbz/v18DHwWYKK0bSWLqn47eeDSKPB7m8tqMHF9YJ+mhIk2lVteyZrY8tnSj/jHOv4YiTCuCJgg== + dependencies: + dequal "^2.0.3" babel-jest@^27.4.2, babel-jest@^27.5.1: version "27.5.1" @@ -3542,29 +3773,29 @@ babel-plugin-named-asset-import@^0.3.8: resolved "https://registry.yarnpkg.com/babel-plugin-named-asset-import/-/babel-plugin-named-asset-import-0.3.8.tgz#6b7fa43c59229685368683c28bc9734f24524cc2" integrity sha512-WXiAc++qo7XcJ1ZnTYGtLxmBCVbddAml3CEXgWaBzNzLNoxtQ8AiGEFDMOhot9XjTCQbvP5E77Fj9Gk924f00Q== -babel-plugin-polyfill-corejs2@^0.3.3: - version "0.3.3" - resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.3.3.tgz#5d1bd3836d0a19e1b84bbf2d9640ccb6f951c122" - integrity sha512-8hOdmFYFSZhqg2C/JgLUQ+t52o5nirNwaWM2B9LWteozwIvM14VSwdsCAUET10qT+kmySAlseadmfeeSWFCy+Q== +babel-plugin-polyfill-corejs2@^0.4.5: + version "0.4.5" + resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.5.tgz#8097b4cb4af5b64a1d11332b6fb72ef5e64a054c" + integrity sha512-19hwUH5FKl49JEsvyTcoHakh6BE0wgXLLptIyKZ3PijHc/Ci521wygORCUCCred+E/twuqRyAkE02BAWPmsHOg== dependencies: - "@babel/compat-data" "^7.17.7" - "@babel/helper-define-polyfill-provider" "^0.3.3" - semver "^6.1.1" + "@babel/compat-data" "^7.22.6" + "@babel/helper-define-polyfill-provider" "^0.4.2" + semver "^6.3.1" -babel-plugin-polyfill-corejs3@^0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.6.0.tgz#56ad88237137eade485a71b52f72dbed57c6230a" - integrity sha512-+eHqR6OPcBhJOGgsIar7xoAB1GcSwVUA3XjAd7HJNzOXT4wv6/H7KIdA/Nc60cvUlDbKApmqNvD1B1bzOt4nyA== +babel-plugin-polyfill-corejs3@^0.8.3: + version "0.8.3" + resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.8.3.tgz#b4f719d0ad9bb8e0c23e3e630c0c8ec6dd7a1c52" + integrity sha512-z41XaniZL26WLrvjy7soabMXrfPWARN25PZoriDEiLMxAp50AUW3t35BGQUMg5xK3UrpVTtagIDklxYa+MhiNA== dependencies: - "@babel/helper-define-polyfill-provider" "^0.3.3" - core-js-compat "^3.25.1" + "@babel/helper-define-polyfill-provider" "^0.4.2" + core-js-compat "^3.31.0" -babel-plugin-polyfill-regenerator@^0.4.1: - version "0.4.1" - resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.4.1.tgz#390f91c38d90473592ed43351e801a9d3e0fd747" - integrity sha512-NtQGmyQDXjQqQ+IzRkBVwEOz9lQ4zxAQZgoAYEtU9dJjnl1Oc98qnN7jcp+bE7O7aYzVpavXE3/VKXNzUbh7aw== +babel-plugin-polyfill-regenerator@^0.5.2: + version "0.5.2" + resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.5.2.tgz#80d0f3e1098c080c8b5a65f41e9427af692dc326" + integrity sha512-tAlOptU0Xj34V1Y2PNTL4Y0FOJMDB6bZmoW39FeCQIhigGLkqu3Fj6uiXpxIf6Ij274ENdYx64y6Au+ZKlb1IA== dependencies: - "@babel/helper-define-polyfill-provider" "^0.3.3" + "@babel/helper-define-polyfill-provider" "^0.4.2" babel-plugin-transform-react-remove-prop-types@^0.4.24: version "0.4.24" @@ -3649,6 +3880,11 @@ bfj@^7.0.2: hoopy "^0.1.4" tryer "^1.0.1" +big-integer@^1.6.44: + version "1.6.51" + resolved "https://registry.yarnpkg.com/big-integer/-/big-integer-1.6.51.tgz#0df92a5d9880560d3ff2d5fd20245c889d130686" + integrity sha512-GPEid2Y9QU1Exl1rpO9B2IPJGHPSupF5GnVIP0blYvNOMer2bTvSWs1jGOUg04hTmu67nmLsQ9TBo1puaotBHg== + big.js@^5.2.2: version "5.2.2" resolved "https://registry.yarnpkg.com/big.js/-/big.js-5.2.2.tgz#65f0af382f578bcdc742bd9c281e9cb2d7768328" @@ -3683,9 +3919,9 @@ body-parser@1.20.1: unpipe "1.0.0" bonjour-service@^1.0.11: - version "1.0.14" - resolved "https://registry.yarnpkg.com/bonjour-service/-/bonjour-service-1.0.14.tgz#c346f5bc84e87802d08f8d5a60b93f758e514ee7" - integrity sha512-HIMbgLnk1Vqvs6B4Wq5ep7mxvj9sGz5d1JJyDNSGNIdA/w2MCz6GTjWTdjqOJV1bEPj+6IkxDvWNFKEBxNt4kQ== + version "1.1.1" + resolved "https://registry.yarnpkg.com/bonjour-service/-/bonjour-service-1.1.1.tgz#960948fa0e0153f5d26743ab15baf8e33752c135" + integrity sha512-Z/5lQRMOG9k7W+FkeGTNjh7htqn/2LMnfOvBZ8pynNZCM9MwkQkI3zeI4oz09uWdcgmgHugVvBqxGg4VQJ5PCg== dependencies: array-flatten "^2.1.2" dns-equal "^1.0.0" @@ -3697,6 +3933,13 @@ boolbase@^1.0.0, boolbase@~1.0.0: resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e" integrity sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww== +bplist-parser@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/bplist-parser/-/bplist-parser-0.2.0.tgz#43a9d183e5bf9d545200ceac3e712f79ebbe8d0e" + integrity sha512-z0M+byMThzQmD9NILRniCUXYsYpjwnlO8N5uCFaCqIOpqRsJCrQL9NK3JsD67CN5a08nF5oIL2bD6loTdHOuKw== + dependencies: + big-integer "^1.6.44" + brace-expansion@^1.1.7: version "1.1.11" resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" @@ -3738,15 +3981,15 @@ browserify-zlib@^0.2.0: dependencies: pako "~1.0.5" -browserslist@^4.0.0, browserslist@^4.14.5, browserslist@^4.16.6, browserslist@^4.18.1, browserslist@^4.21.3, browserslist@^4.21.4: - version "4.21.4" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.21.4.tgz#e7496bbc67b9e39dd0f98565feccdcb0d4ff6987" - integrity sha512-CBHJJdDmgjl3daYjN5Cp5kbTf1mUhZoS+beLklHIvkOWscs83YAhLlF3Wsh/lciQYAcbBJgTOD44VtG31ZM4Hw== +browserslist@^4.0.0, browserslist@^4.14.5, browserslist@^4.18.1, browserslist@^4.21.10, browserslist@^4.21.4, browserslist@^4.21.9: + version "4.21.10" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.21.10.tgz#dbbac576628c13d3b2231332cb2ec5a46e015bb0" + integrity sha512-bipEBdZfVH5/pwrvqc+Ub0kUPVfGUhlKxbvfD+z1BDnPEO/X98ruXGA1WP5ASpAFKan7Qr6j736IacbZQuAlKQ== dependencies: - caniuse-lite "^1.0.30001400" - electron-to-chromium "^1.4.251" - node-releases "^2.0.6" - update-browserslist-db "^1.0.9" + caniuse-lite "^1.0.30001517" + electron-to-chromium "^1.4.477" + node-releases "^2.0.13" + update-browserslist-db "^1.0.11" bser@2.1.1: version "2.1.1" @@ -3765,6 +4008,20 @@ builtin-modules@^3.1.0: resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-3.3.0.tgz#cae62812b89801e9656336e46223e030386be7b6" integrity sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw== +builtins@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/builtins/-/builtins-5.0.1.tgz#87f6db9ab0458be728564fa81d876d8d74552fa9" + integrity sha512-qwVpFEHNfhYJIzNRBvd2C1kyo6jz3ZSMPyyuR47OPdiKWlbYnZNyDWuyR175qDnAJLiCo5fBBqPb3RiXgWlkOQ== + dependencies: + semver "^7.0.0" + +bundle-name@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/bundle-name/-/bundle-name-3.0.0.tgz#ba59bcc9ac785fb67ccdbf104a2bf60c099f0e1a" + integrity sha512-PKA4BeSvBpQKQ8iPOGCSiell+N8P+Tf1DlwqmYhpe2gAhKPHn8EYOxVT+ShuGmhg8lN8XiSlS80yiExKXrURlw== + dependencies: + run-applescript "^5.0.0" + bytes@3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.0.0.tgz#d32815404d689699f85a4ea4fa8755dd13a96048" @@ -3821,10 +4078,10 @@ caniuse-api@^3.0.0: lodash.memoize "^4.1.2" lodash.uniq "^4.5.0" -caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001400, caniuse-lite@^1.0.30001426: - version "1.0.30001519" - resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001519.tgz" - integrity sha512-0QHgqR+Jv4bxHMp8kZ1Kn8CH55OikjKJ6JmKkZYP1F3D7w+lnFXF70nG5eNfsZS89jadi5Ywy5UCSKLAglIRkg== +caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001517, caniuse-lite@^1.0.30001520: + version "1.0.30001525" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001525.tgz#d2e8fdec6116ffa36284ca2c33ef6d53612fe1c8" + integrity sha512-/3z+wB4icFt3r0USMwxujAqRvaD/B7rvGTsKhbhSQErVrJvkZCLhgNLJxU8MevahQVH6hCU9FsHdNUFbiwmE7Q== case-sensitive-paths-webpack-plugin@^2.4.0: version "2.4.0" @@ -3836,7 +4093,7 @@ ccount@^2.0.0: resolved "https://registry.yarnpkg.com/ccount/-/ccount-2.0.1.tgz#17a3bf82302e0870d6da43a01311a8bc02a3ecf5" integrity sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg== -chalk@^2.0.0, chalk@^2.4.1: +chalk@^2.4.1, chalk@^2.4.2: version "2.4.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== @@ -3909,16 +4166,16 @@ chrome-trace-event@^1.0.2: integrity sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg== ci-info@^3.2.0: - version "3.7.0" - resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-3.7.0.tgz#6d01b3696c59915b6ce057e4aa4adfc2fa25f5ef" - integrity sha512-2CpRNYmImPx+RXKLq6jko/L07phmS9I02TyqkcNU20GCF/GgaWvc58hPtjxDX8lPpkdwc9sNh72V9k00S7ezog== + version "3.8.0" + resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-3.8.0.tgz#81408265a5380c929f0bc665d62256628ce9ef91" + integrity sha512-eXTggHWSooYhq49F2opQhuHWgzucfF2YgODK4e1566GQs5BIfP30B0oenwBJHfWxAs2fyPB1s7Mg949zLf61Yw== cjs-module-lexer@^1.0.0: - version "1.2.2" - resolved "https://registry.yarnpkg.com/cjs-module-lexer/-/cjs-module-lexer-1.2.2.tgz#9f84ba3244a512f3a54e5277e8eef4c489864e40" - integrity sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA== + version "1.2.3" + resolved "https://registry.yarnpkg.com/cjs-module-lexer/-/cjs-module-lexer-1.2.3.tgz#6c370ab19f8a3394e318fe682686ec0ac684d107" + integrity sha512-0TNiGstbQmCFwt4akjjBg5pLRTSyj/PkWQ1ZoO2zntmg9yLqSRxwEa4iCfQLGjqhiqBfOJa7W/E8wfGrTDmlZQ== -classcat@^5.0.3: +classcat@^5.0.3, classcat@^5.0.4: version "5.0.4" resolved "https://registry.yarnpkg.com/classcat/-/classcat-5.0.4.tgz#e12d1dfe6df6427f260f03b80dc63571a5107ba6" integrity sha512-sbpkOw6z413p+HDGcBENe498WM9woqWHiJxCq7nvmxe9WmrUmqfAcxpIwAiMtM5Q3AhYkzXcNQHqsWq0mND51g== @@ -3929,12 +4186,17 @@ classnames@^2.2.6: integrity sha512-CSbhY4cFEJRe6/GQzIk5qXZ4Jeg5pcsP7b5peFSDpffpe1cqjASH/n9UTjBwOp6XpMSTwQ8Za2K5V02ueA7Tmw== clean-css@^5.2.2: - version "5.3.1" - resolved "https://registry.yarnpkg.com/clean-css/-/clean-css-5.3.1.tgz#d0610b0b90d125196a2894d35366f734e5d7aa32" - integrity sha512-lCr8OHhiWCTw4v8POJovCoh4T7I9U11yVsPjMWWnnMmp9ZowCxyad1Pathle/9HjaDp+fdQKjO9fQydE6RHTZg== + version "5.3.2" + resolved "https://registry.yarnpkg.com/clean-css/-/clean-css-5.3.2.tgz#70ecc7d4d4114921f5d298349ff86a31a9975224" + integrity sha512-JVJbM+f3d3Q704rF4bqQ5UUyTtuJ0JRKNbTKVEeujCCBoMdkEi+V+e8oktO9qGQNSvHrFTM6JZRXrUvGR1czww== dependencies: source-map "~0.6.0" +client-only@^0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/client-only/-/client-only-0.0.1.tgz#38bba5d403c41ab150bff64a95c85013cf73bca1" + integrity sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA== + cliui@^7.0.2: version "7.0.4" resolved "https://registry.yarnpkg.com/cliui/-/cliui-7.0.4.tgz#a0265ee655476fc807aea9df3df8df7783808b4f" @@ -3954,6 +4216,11 @@ clsx@^1.0.2, clsx@^1.0.4, clsx@^1.1.1, clsx@^1.2.1: resolved "https://registry.yarnpkg.com/clsx/-/clsx-1.2.1.tgz#0ddc4a20a549b59c93a4116bb26f5294ca17dc12" integrity sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg== +clsx@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/clsx/-/clsx-2.0.0.tgz#12658f3fd98fafe62075595a5c30e43d18f3d00b" + integrity sha512-rQ1+kcj+ttHG0MKVGBUXwayCCF1oh39BF5COIpRzuCEv8Mwjv0XucrI2ExNTOn9IlLifGClWQcU9BrZORvtw6Q== + co@^4.6.0: version "4.6.0" resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" @@ -3969,9 +4236,9 @@ coa@^2.0.2: q "^1.1.2" collect-v8-coverage@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/collect-v8-coverage/-/collect-v8-coverage-1.0.1.tgz#cc2c8e94fc18bbdffe64d6534570c8a673b27f59" - integrity sha512-iBPtljfCNcTKNAto0KEtDfZ3qzjJvqE3aTGZsbhjSBlorqpXJlaWWtPO35D+ZImoC3KWejX64o+yPGxhWSTzfg== + version "1.0.2" + resolved "https://registry.yarnpkg.com/collect-v8-coverage/-/collect-v8-coverage-1.0.2.tgz#c0b29bcd33bcd0779a1344c2136051e6afd3d9e9" + integrity sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q== color-convert@^1.9.0: version "1.9.3" @@ -3992,7 +4259,7 @@ color-name@1.1.3: resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" integrity sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw== -color-name@^1.0.0, color-name@^1.1.4, color-name@~1.1.4: +color-name@^1.0.0, color-name@~1.1.4: version "1.1.4" resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== @@ -4011,9 +4278,9 @@ colord@^2.9.1: integrity sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw== colorette@^2.0.10: - version "2.0.19" - resolved "https://registry.yarnpkg.com/colorette/-/colorette-2.0.19.tgz#cdf044f47ad41a0f4b56b3a0d5b4e6e1a2d5a798" - integrity sha512-3tlv/dIP7FWvj3BsbHrGLJ6l/oKh1O3TcgBqMn+yyCagOxc23fyzDS6HypQbgxWbkpDnf52p1LuR4eWDQ/K9WQ== + version "2.0.20" + resolved "https://registry.yarnpkg.com/colorette/-/colorette-2.0.20.tgz#9eb793e6833067f7235902fcd3b09917a000a95a" + integrity sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w== combined-stream@^1.0.8: version "1.0.8" @@ -4032,6 +4299,11 @@ commander@^2.20.0: resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== +commander@^4.0.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/commander/-/commander-4.1.1.tgz#9fd602bd936294e9e9ef46a3f4d6964044b18068" + integrity sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA== + commander@^7.2.0: version "7.2.0" resolved "https://registry.yarnpkg.com/commander/-/commander-7.2.0.tgz#a36cb57d0b501ce108e4d20559a150a391d97ab7" @@ -4100,9 +4372,9 @@ content-disposition@0.5.4: safe-buffer "5.2.1" content-type@~1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b" - integrity sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA== + version "1.0.5" + resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.5.tgz#8b773162656d1d1086784c8f23a54ce6d73d7918" + integrity sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA== convert-source-map@^1.4.0, convert-source-map@^1.5.0, convert-source-map@^1.6.0, convert-source-map@^1.7.0: version "1.9.0" @@ -4119,22 +4391,22 @@ cookie@0.5.0: resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.5.0.tgz#d1f5d71adec6558c58f389987c366aa47e994f8b" integrity sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw== -core-js-compat@^3.25.1: - version "3.26.1" - resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.26.1.tgz#0e710b09ebf689d719545ac36e49041850f943df" - integrity sha512-622/KzTudvXCDLRw70iHW4KKs1aGpcRcowGWyYJr2DEBfRrd6hNJybxSWJFuZYD4ma86xhrwDDHxmDaIq4EA8A== +core-js-compat@^3.31.0: + version "3.32.1" + resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.32.1.tgz#55f9a7d297c0761a8eb1d31b593e0f5b6ffae964" + integrity sha512-GSvKDv4wE0bPnQtjklV101juQ85g6H3rm5PDP20mqlS5j0kXF3pP97YvAu5hl+uFHqMictp3b2VxOHljWMAtuA== dependencies: - browserslist "^4.21.4" + browserslist "^4.21.10" -core-js-pure@^3.23.3, core-js-pure@^3.25.1: - version "3.26.1" - resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.26.1.tgz#653f4d7130c427820dcecd3168b594e8bb095a33" - integrity sha512-VVXcDpp/xJ21KdULRq/lXdLzQAtX7+37LzpyfFM973il0tWSsDEoyzG38G14AjTpK9VTfiNM9jnFauq/CpaWGQ== +core-js-pure@^3.23.3: + version "3.32.1" + resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.32.1.tgz#5775b88f9062885f67b6d7edce59984e89d276f3" + integrity sha512-f52QZwkFVDPf7UEQZGHKx6NYxsxmVGJe5DIvbzOdRMJlmT6yv0KDjR8rmy3ngr/t5wU54c7Sp/qIJH0ppbhVpQ== core-js@^3.19.2: - version "3.26.1" - resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.26.1.tgz#7a9816dabd9ee846c1c0fe0e8fcad68f3709134e" - integrity sha512-21491RRQVzUn0GGM9Z1Jrpr6PNPxPi+Za8OM9q4tksTSnlbXXGKK1nXNg/QvwFYettXvSX6zWKCtHHfjN4puyA== + version "3.32.1" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.32.1.tgz#a7d8736a3ed9dd05940c3c4ff32c591bb735be77" + integrity sha512-lqufgNn9NLnESg5mQeYsxQP5w7wrViSj0jr/kv6ECQiByzQkrn1MKvV0L3acttpDqfQrHLwr2KCMgX5b8X+lyQ== core-util-is@~1.0.0: version "1.0.3" @@ -4171,11 +4443,11 @@ cross-env@^7.0.3: cross-spawn "^7.0.1" cross-fetch@^3.1.5: - version "3.1.6" - resolved "https://registry.yarnpkg.com/cross-fetch/-/cross-fetch-3.1.6.tgz#bae05aa31a4da760969756318feeee6e70f15d6c" - integrity sha512-riRvo06crlE8HiqOwIpQhxwdOk4fOeR7FVM/wXoxchFEqMNUjvbs3bfo4OTgMEMHzppd4DxFBDbyySj8Cv781g== + version "3.1.8" + resolved "https://registry.yarnpkg.com/cross-fetch/-/cross-fetch-3.1.8.tgz#0327eba65fd68a7d119f8fb2bf9334a1a7956f82" + integrity sha512-cvA+JwZoU0Xq+h6WkMvAUqPEYy92Obet6UdKLfW60qn99ftItKjB5T+BkyWOFWe2pUyfQ+IJHmpOTznqk1M6Kg== dependencies: - node-fetch "^2.6.11" + node-fetch "^2.6.12" cross-spawn@^7.0.1, cross-spawn@^7.0.2, cross-spawn@^7.0.3: version "7.0.3" @@ -4204,9 +4476,9 @@ css-blank-pseudo@^3.0.3: postcss-selector-parser "^6.0.9" css-declaration-sorter@^6.3.1: - version "6.3.1" - resolved "https://registry.yarnpkg.com/css-declaration-sorter/-/css-declaration-sorter-6.3.1.tgz#be5e1d71b7a992433fb1c542c7a1b835e45682ec" - integrity sha512-fBffmak0bPAnyqc/HO8C3n2sHrp9wcqQz6ES9koRF2/mLOVAx9zIQ3Y7R29sYCteTPqMCwns4WYQoCX91Xl3+w== + version "6.4.1" + resolved "https://registry.yarnpkg.com/css-declaration-sorter/-/css-declaration-sorter-6.4.1.tgz#28beac7c20bad7f1775be3a7129d7eae409a3a71" + integrity sha512-rtdthzxKuyq6IzqX6jEcIzQF/YqccluefyCYheovBOLhFT/drQA9zj/UbRAa9J7C0o6EG6u3E6g+vKkay7/k3g== css-has-pseudo@^3.0.4: version "3.0.4" @@ -4216,14 +4488,14 @@ css-has-pseudo@^3.0.4: postcss-selector-parser "^6.0.9" css-loader@^6.5.1: - version "6.7.3" - resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-6.7.3.tgz#1e8799f3ccc5874fdd55461af51137fcc5befbcd" - integrity sha512-qhOH1KlBMnZP8FzRO6YCH9UHXQhVMcEGLyNdb7Hv2cpcmJbW0YrddO+tG1ab5nT41KpHIYGsbeHqxB9xPu1pKQ== + version "6.8.1" + resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-6.8.1.tgz#0f8f52699f60f5e679eab4ec0fcd68b8e8a50a88" + integrity sha512-xDAXtEVGlD0gJ07iclwWVkLoZOpEvAWaSyf6W18S2pOC//K8+qUDIx8IIT3D+HjnmkJPQeesOPv5aiUaJsCM2g== dependencies: icss-utils "^5.1.0" - postcss "^8.4.19" + postcss "^8.4.21" postcss-modules-extract-imports "^3.0.0" - postcss-modules-local-by-default "^4.0.0" + postcss-modules-local-by-default "^4.0.3" postcss-modules-scope "^3.0.0" postcss-modules-values "^4.0.0" postcss-value-parser "^4.2.0" @@ -4307,31 +4579,31 @@ css-what@^6.0.1: integrity sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw== cssdb@^7.1.0: - version "7.2.0" - resolved "https://registry.yarnpkg.com/cssdb/-/cssdb-7.2.0.tgz#f44bd4abc430f0ff7f4c64b8a1fb857a753f77a8" - integrity sha512-JYlIsE7eKHSi0UNuCyo96YuIDFqvhGgHw4Ck6lsN+DP0Tp8M64UTDT2trGbkMDqnCoEjks7CkS0XcjU0rkvBdg== + version "7.7.1" + resolved "https://registry.yarnpkg.com/cssdb/-/cssdb-7.7.1.tgz#759e333f516e47f26dd2c7be06147d4f4716356d" + integrity sha512-kM+Fs0BFyhJNeE6wbOrlnRsugRdL6vn7QcON0aBDZ7XRd7RI2pMlk+nxoHuTb4Et+aBobXgK0I+6NGLA0LLgTw== cssesc@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-3.0.0.tgz#37741919903b868565e1c09ea747445cd18983ee" integrity sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg== -cssnano-preset-default@^5.2.13: - version "5.2.13" - resolved "https://registry.yarnpkg.com/cssnano-preset-default/-/cssnano-preset-default-5.2.13.tgz#e7353b0c57975d1bdd97ac96e68e5c1b8c68e990" - integrity sha512-PX7sQ4Pb+UtOWuz8A1d+Rbi+WimBIxJTRyBdgGp1J75VU0r/HFQeLnMYgHiCAp6AR4rqrc7Y4R+1Rjk3KJz6DQ== +cssnano-preset-default@^5.2.14: + version "5.2.14" + resolved "https://registry.yarnpkg.com/cssnano-preset-default/-/cssnano-preset-default-5.2.14.tgz#309def4f7b7e16d71ab2438052093330d9ab45d8" + integrity sha512-t0SFesj/ZV2OTylqQVOrFgEh5uanxbO6ZAdeCrNsUQ6fVuXwYTxJPNAGvGTxHbD68ldIJNec7PyYZDBrfDQ+6A== dependencies: css-declaration-sorter "^6.3.1" cssnano-utils "^3.1.0" postcss-calc "^8.2.3" - postcss-colormin "^5.3.0" + postcss-colormin "^5.3.1" postcss-convert-values "^5.1.3" postcss-discard-comments "^5.1.2" postcss-discard-duplicates "^5.1.0" postcss-discard-empty "^5.1.1" postcss-discard-overridden "^5.1.0" postcss-merge-longhand "^5.1.7" - postcss-merge-rules "^5.1.3" + postcss-merge-rules "^5.1.4" postcss-minify-font-values "^5.1.0" postcss-minify-gradients "^5.1.1" postcss-minify-params "^5.1.4" @@ -4346,7 +4618,7 @@ cssnano-preset-default@^5.2.13: postcss-normalize-url "^5.1.0" postcss-normalize-whitespace "^5.1.1" postcss-ordered-values "^5.1.3" - postcss-reduce-initial "^5.1.1" + postcss-reduce-initial "^5.1.2" postcss-reduce-transforms "^5.1.0" postcss-svgo "^5.1.0" postcss-unique-selectors "^5.1.1" @@ -4357,11 +4629,11 @@ cssnano-utils@^3.1.0: integrity sha512-JQNR19/YZhz4psLX/rQ9M83e3z2Wf/HdJbryzte4a3NSuafyp9w/I4U+hx5C2S9g41qlstH7DEWnZaaj83OuEA== cssnano@^5.0.6: - version "5.1.14" - resolved "https://registry.yarnpkg.com/cssnano/-/cssnano-5.1.14.tgz#07b0af6da73641276fe5a6d45757702ebae2eb05" - integrity sha512-Oou7ihiTocbKqi0J1bB+TRJIQX5RMR3JghA8hcWSw9mjBLQ5Y3RWqEDoYG3sRNlAbCIXpqMoZGbq5KDR3vdzgw== + version "5.1.15" + resolved "https://registry.yarnpkg.com/cssnano/-/cssnano-5.1.15.tgz#ded66b5480d5127fcb44dac12ea5a983755136bf" + integrity sha512-j+BKgDcLDQA+eDifLx0EO4XSA56b7uut3BQFH+wbSaSTuGLuiyTa/wbRYthUXX8LC9mLg+WWKe8h+qJuwTAbHw== dependencies: - cssnano-preset-default "^5.2.13" + cssnano-preset-default "^5.2.14" lilconfig "^2.0.3" yaml "^1.10.2" @@ -4394,10 +4666,10 @@ csstype@^2.5.2: resolved "https://registry.yarnpkg.com/csstype/-/csstype-2.6.21.tgz#2efb85b7cc55c80017c66a5ad7cbd931fda3a90e" integrity sha512-Z1PhmomIfypOpoMjRQB70jfvy/wxT50qW08YXO5lMIJkrdq4yOTR+AW7FqutScmB9NkLwxo+jU+kZLbofZZq/w== -csstype@^3.0.2, csstype@^3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.1.1.tgz#841b532c45c758ee546a11d5bd7b7b473c8c30b9" - integrity sha512-DJR/VvkAvSZW9bTouZue2sSxDwdTN92uHjqeKVm+0dAqdfNykRzQ95tay8aXMBAAPpUiq4Qcug2L7neoRh2Egw== +csstype@^3.0.2, csstype@^3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.1.2.tgz#1d4bf9d572f11c14031f0436e1c10bc1f571f50b" + integrity sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ== "d3-color@1 - 3": version "3.1.0" @@ -4475,10 +4747,12 @@ data-urls@^2.0.0: whatwg-mimetype "^2.3.0" whatwg-url "^8.0.0" -date-fns@^2.24.0: - version "2.29.3" - resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-2.29.3.tgz#27402d2fc67eb442b511b70bbdf98e6411cd68a8" - integrity sha512-dDCnyH2WnnKusqvZZ6+jA1O51Ibt8ZMRNkDZdyAyK4YfbDwa/cEmuztzG5pk6hqlp9aSBPYcjOlktquahGwGeA== +date-fns@^2.30.0: + version "2.30.0" + resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-2.30.0.tgz#f367e644839ff57894ec6ac480de40cae4b0f4d0" + integrity sha512-fnULvOpxnC5/Vg3NCiWelDsLiUc9bRwAPs/+LfTLNvetFCtCTN+yQz15C/fs4AwX1R9K5GLtLfn8QW+dWisaAw== + dependencies: + "@babel/runtime" "^7.21.0" dayjs@1.10.6: version "1.10.6" @@ -4486,11 +4760,11 @@ dayjs@1.10.6: integrity sha512-AztC/IOW4L1Q41A86phW5Thhcrco3xuAA+YX/BLpLWWjRcTj5TOt/QImBLmCKlrF7u7k47arTnOyL6GnbG8Hvw== dayjs@^1.11.7: - version "1.11.7" - resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.11.7.tgz#4b296922642f70999544d1144a2c25730fce63e2" - integrity sha512-+Yw9U6YO5TQohxLcIkrXBeY73WP3ejHWVvx8XCk3gxvQDCTEmS48ZrSZCKciI7Bhl/uCMyxYtE9UqRILmFphkQ== + version "1.11.9" + resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.11.9.tgz#9ca491933fadd0a60a2c19f6c237c03517d71d1a" + integrity sha512-QvzAURSbQ0pKdIye2txOzNaHmxtUBXerpY0FJsFXUMKbIZeFm5ht1LS/jFsrncjnmtv8HsG0W2g6c0zUjZWmpA== -debug@2.6.9, debug@^2.6.0, debug@^2.6.9: +debug@2.6.9, debug@^2.6.0: version "2.6.9" resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== @@ -4528,15 +4802,33 @@ dedent@^0.7.0: resolved "https://registry.yarnpkg.com/dedent/-/dedent-0.7.0.tgz#2495ddbaf6eb874abb0e1be9df22d2e5a544326c" integrity sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA== -deep-is@^0.1.3, deep-is@~0.1.3: +deep-is@^0.1.3: version "0.1.4" resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831" integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ== deepmerge@^4.2.2: - version "4.2.2" - resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.2.2.tgz#44d2ea3679b8f4d4ffba33f03d865fc1e7bf4955" - integrity sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg== + version "4.3.1" + resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.3.1.tgz#44b5f2147cd3b00d4b56137685966f26fd25dd4a" + integrity sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A== + +default-browser-id@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/default-browser-id/-/default-browser-id-3.0.0.tgz#bee7bbbef1f4e75d31f98f4d3f1556a14cea790c" + integrity sha512-OZ1y3y0SqSICtE8DE4S8YOE9UZOJ8wO16fKWVP5J1Qz42kV9jcnMVFrEE/noXb/ss3Q4pZIH79kxofzyNNtUNA== + dependencies: + bplist-parser "^0.2.0" + untildify "^4.0.0" + +default-browser@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/default-browser/-/default-browser-4.0.0.tgz#53c9894f8810bf86696de117a6ce9085a3cbc7da" + integrity sha512-wX5pXO1+BrhMkSbROFsyxUm0i/cJEScyNhA4PPxc41ICuv05ZZB/MX28s8aZx6xjmatvebIapF6hLEKEcpneUA== + dependencies: + bundle-name "^3.0.0" + default-browser-id "^3.0.0" + execa "^7.1.1" + titleize "^3.0.0" default-gateway@^6.0.3: version "6.0.3" @@ -4550,19 +4842,19 @@ define-lazy-prop@^2.0.0: resolved "https://registry.yarnpkg.com/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz#3f7ae421129bcaaac9bc74905c98a0009ec9ee7f" integrity sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og== -define-properties@^1.1.3, define-properties@^1.1.4: - version "1.1.4" - resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.4.tgz#0b14d7bd7fbeb2f3572c3a7eda80ea5d57fb05b1" - integrity sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA== +define-lazy-prop@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz#dbb19adfb746d7fc6d734a06b72f4a00d021255f" + integrity sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg== + +define-properties@^1.1.3, define-properties@^1.1.4, define-properties@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.2.0.tgz#52988570670c9eacedd8064f4a990f2405849bd5" + integrity sha512-xvqAVKGfT1+UAvPwKTVw/njhdQ8ZhXK4lI0bCIuCMrp2up9nPnaDftrLtmpTazqd1o+UY4zgzU+avtMbDP+ldA== dependencies: has-property-descriptors "^1.0.0" object-keys "^1.1.1" -defined@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/defined/-/defined-1.0.1.tgz#c0b9db27bfaffd95d6f61399419b893df0f91ebf" - integrity sha512-hsBd2qSVCRE+5PmNdHt1uzyrFu5d3RwmFDKzyNZMFq/EwDNJF7Ee5+D5oEKF0hU6LhtoUF1macFvOe4AskQC1Q== - delayed-stream@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" @@ -4578,7 +4870,7 @@ depd@~1.1.2: resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" integrity sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ== -dequal@^2.0.0: +dequal@^2.0.0, dequal@^2.0.3: version "2.0.3" resolved "https://registry.yarnpkg.com/dequal/-/dequal-2.0.3.tgz#2644214f1997d39ed0ee0ece72335490a7ac67be" integrity sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA== @@ -4606,15 +4898,6 @@ detect-port-alt@^1.1.6: address "^1.0.1" debug "^2.6.0" -detective@^5.2.1: - version "5.2.1" - resolved "https://registry.yarnpkg.com/detective/-/detective-5.2.1.tgz#6af01eeda11015acb0e73f933242b70f24f91034" - integrity sha512-v9XE1zRnz1wRtgurGu0Bs8uHKFSTdteYZNbIPFVhUZ39L/S79ppMpdmVOZAnoz1jfEFodc48n6MX483Xo3t1yw== - dependencies: - acorn-node "^1.8.2" - defined "^1.0.0" - minimist "^1.2.6" - dfa@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/dfa/-/dfa-1.2.0.tgz#96ac3204e2d29c49ea5b57af8d92c2ae12790657" @@ -4653,9 +4936,9 @@ dns-equal@^1.0.0: integrity sha512-z+paD6YUQsk+AbGCEM4PrOXSss5gd66QfcVBFTKR/HpFL9jCqikS94HYwKww6fQyO7IxrIIyUu+g0Ka9tUS2Cg== dns-packet@^5.2.2: - version "5.4.0" - resolved "https://registry.yarnpkg.com/dns-packet/-/dns-packet-5.4.0.tgz#1f88477cf9f27e78a213fb6d118ae38e759a879b" - integrity sha512-EgqGeaBB8hLiHLZtp/IbaDQTL8pZ0+IvwzSHA6d7VyMDM+B9hgddEMa9xjK5oYnw0ci0JQ6g2XCD7/f6cafU6g== + version "5.6.1" + resolved "https://registry.yarnpkg.com/dns-packet/-/dns-packet-5.6.1.tgz#ae888ad425a9d1478a0674256ab866de1012cf2f" + integrity sha512-l4gcSouhcgIKRvyy99RNVOgxXiicE+2jZoNmaNmZ6JXiGajBOJAesk1OBlJuM5k2c+eudGdLxDqXuPCKIj6kpw== dependencies: "@leichtgewicht/ip-codec" "^2.0.1" @@ -4775,16 +5058,16 @@ ee-first@1.1.1: integrity sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow== ejs@^3.1.6: - version "3.1.8" - resolved "https://registry.yarnpkg.com/ejs/-/ejs-3.1.8.tgz#758d32910c78047585c7ef1f92f9ee041c1c190b" - integrity sha512-/sXZeMlhS0ArkfX2Aw780gJzXSMPnKjtspYZv+f3NiKLlubezAHDU5+9xz6gd3/NhG3txQCo6xlglmTS+oTGEQ== + version "3.1.9" + resolved "https://registry.yarnpkg.com/ejs/-/ejs-3.1.9.tgz#03c9e8777fe12686a9effcef22303ca3d8eeb361" + integrity sha512-rC+QVNMJWv+MtPgkt0y+0rVEIdbtxVADApW9JXrUVlzHetgcyczP/E7DJmWJ4fJCZF2cPcBk0laWO9ZHMG3DmQ== dependencies: jake "^10.8.5" -electron-to-chromium@^1.4.251: - version "1.4.284" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.284.tgz#61046d1e4cab3a25238f6bf7413795270f125592" - integrity sha512-M8WEXFuKXMYMVr45fo8mq0wUrrJHheiKZf6BArTKk9ZBYCKJEOU5H8cdWgDT+qCVZf7Na4lVUaZsA+h6uA9+PA== +electron-to-chromium@^1.4.477: + version "1.4.506" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.506.tgz#59f64a211102db4c3ebae2f39cc0e8e1b12b3a07" + integrity sha512-xxGct4GPAKSRlrLBtJxJFYy74W11zX6PO9GyHgl/U+2s3Dp0ZEwAklDfNHXOWcvH7zWMpsmgbR0ggEuaYAVvHA== emittery@^0.10.2: version "0.10.2" @@ -4821,10 +5104,10 @@ encodeurl@~1.0.2: resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" integrity sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w== -enhanced-resolve@^5.10.0: - version "5.12.0" - resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.12.0.tgz#300e1c90228f5b570c4d35babf263f6da7155634" - integrity sha512-QHTXI/sZQmko1cbDoNAa3mJ5qhWUUNAq3vR0/YiD379fWQrcfuoX1+HW2S0MTt7XmoPLapdaDKUtelUSPic7hQ== +enhanced-resolve@^5.12.0, enhanced-resolve@^5.15.0: + version "5.15.0" + resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.15.0.tgz#1af946c7d93603eb88e9896cee4904dc012e9c35" + integrity sha512-LXYT42KJ7lpIKECr2mAXIaMldcNCh/7E0KBKOu4KSfkHmP+mZmSs+8V5gBAqisWBy0OO4W5Oyys0GO1Y8KtdKg== dependencies: graceful-fs "^4.2.4" tapable "^2.2.0" @@ -4848,46 +5131,89 @@ error-stack-parser@^2.0.6: dependencies: stackframe "^1.3.4" -es-abstract@^1.17.2, es-abstract@^1.19.0, es-abstract@^1.20.4: - version "1.20.5" - resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.20.5.tgz#e6dc99177be37cacda5988e692c3fa8b218e95d2" - integrity sha512-7h8MM2EQhsCA7pU/Nv78qOXFpD8Rhqd12gYiSJVkrH9+e8VuA8JlPJK/hQjjlLv6pJvx/z1iRFKzYb0XT/RuAQ== +es-abstract@^1.17.2, es-abstract@^1.20.4, es-abstract@^1.21.2, es-abstract@^1.22.1: + version "1.22.1" + resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.22.1.tgz#8b4e5fc5cefd7f1660f0f8e1a52900dfbc9d9ccc" + integrity sha512-ioRRcXMO6OFyRpyzV3kE1IIBd4WG5/kltnzdxSCqoP8CMGs/Li+M1uF5o7lOkZVFjDs+NLesthnF66Pg/0q0Lw== dependencies: + array-buffer-byte-length "^1.0.0" + arraybuffer.prototype.slice "^1.0.1" + available-typed-arrays "^1.0.5" call-bind "^1.0.2" + es-set-tostringtag "^2.0.1" es-to-primitive "^1.2.1" - function-bind "^1.1.1" function.prototype.name "^1.1.5" - get-intrinsic "^1.1.3" + get-intrinsic "^1.2.1" get-symbol-description "^1.0.0" + globalthis "^1.0.3" gopd "^1.0.1" has "^1.0.3" has-property-descriptors "^1.0.0" + has-proto "^1.0.1" has-symbols "^1.0.3" - internal-slot "^1.0.3" + internal-slot "^1.0.5" + is-array-buffer "^3.0.2" is-callable "^1.2.7" is-negative-zero "^2.0.2" is-regex "^1.1.4" is-shared-array-buffer "^1.0.2" is-string "^1.0.7" + is-typed-array "^1.1.10" is-weakref "^1.0.2" - object-inspect "^1.12.2" + object-inspect "^1.12.3" object-keys "^1.1.1" object.assign "^4.1.4" - regexp.prototype.flags "^1.4.3" + regexp.prototype.flags "^1.5.0" + safe-array-concat "^1.0.0" safe-regex-test "^1.0.0" + string.prototype.trim "^1.2.7" string.prototype.trimend "^1.0.6" string.prototype.trimstart "^1.0.6" + typed-array-buffer "^1.0.0" + typed-array-byte-length "^1.0.0" + typed-array-byte-offset "^1.0.0" + typed-array-length "^1.0.4" unbox-primitive "^1.0.2" + which-typed-array "^1.1.10" es-array-method-boxes-properly@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/es-array-method-boxes-properly/-/es-array-method-boxes-properly-1.0.0.tgz#873f3e84418de4ee19c5be752990b2e44718d09e" integrity sha512-wd6JXUmyHmt8T5a2xreUwKcGPq6f1f+WwIJkijUqiGcJz1qqnZgP6XIK+QyIWU5lT7imeNxUll48bziG+TSYcA== -es-module-lexer@^0.9.0: - version "0.9.3" - resolved "https://registry.yarnpkg.com/es-module-lexer/-/es-module-lexer-0.9.3.tgz#6f13db00cc38417137daf74366f535c8eb438f19" - integrity sha512-1HQ2M2sPtxwnvOvT1ZClHyQDiggdNjURWpY2we6aMKCQiUVxTmVs2UYPLIrD84sS+kMdUwfBSylbJPwNnBrnHQ== +es-iterator-helpers@^1.0.12: + version "1.0.14" + resolved "https://registry.yarnpkg.com/es-iterator-helpers/-/es-iterator-helpers-1.0.14.tgz#19cd7903697d97e21198f3293b55e8985791c365" + integrity sha512-JgtVnwiuoRuzLvqelrvN3Xu7H9bu2ap/kQ2CrM62iidP8SKuD99rWU3CJy++s7IVL2qb/AjXPGR/E7i9ngd/Cw== + dependencies: + asynciterator.prototype "^1.0.0" + call-bind "^1.0.2" + define-properties "^1.2.0" + es-abstract "^1.22.1" + es-set-tostringtag "^2.0.1" + function-bind "^1.1.1" + get-intrinsic "^1.2.1" + globalthis "^1.0.3" + has-property-descriptors "^1.0.0" + has-proto "^1.0.1" + has-symbols "^1.0.3" + internal-slot "^1.0.5" + iterator.prototype "^1.1.0" + safe-array-concat "^1.0.0" + +es-module-lexer@^1.2.1: + version "1.3.0" + resolved "https://registry.yarnpkg.com/es-module-lexer/-/es-module-lexer-1.3.0.tgz#6be9c9e0b4543a60cd166ff6f8b4e9dae0b0c16f" + integrity sha512-vZK7T0N2CBmBOixhmjdqx2gWVbFZ4DXZ/NyRMZVlJXPa7CyFS+/a4QQsDGDQy9ZfEzxFuNEsMLeQJnKP2p5/JA== + +es-set-tostringtag@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/es-set-tostringtag/-/es-set-tostringtag-2.0.1.tgz#338d502f6f674301d710b80c8592de8a15f09cd8" + integrity sha512-g3OMbtlwY3QewlqAiMLI47KywjWZoEytKr8pf6iTC8uJq5bIAH52Z9pnQ8pVL6whrCto53JZDuUIsifGeLorTg== + dependencies: + get-intrinsic "^1.1.3" + has "^1.0.3" + has-tostringtag "^1.0.0" es-shim-unscopables@^1.0.0: version "1.0.0" @@ -4931,17 +5257,21 @@ escape-string-regexp@^4.0.0: integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== escodegen@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-2.0.0.tgz#5e32b12833e8aa8fa35e1bf0befa89380484c7dd" - integrity sha512-mmHKys/C8BFUGI+MAWNcSYoORYLMdPzjrknd2Vc+bUsjN5bXcr8EhrNB+UTqfL1y3I9c4fw2ihgtMPQLBRiQxw== + version "2.1.0" + resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-2.1.0.tgz#ba93bbb7a43986d29d6041f99f5262da773e2e17" + integrity sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w== dependencies: esprima "^4.0.1" estraverse "^5.2.0" esutils "^2.0.2" - optionator "^0.8.1" optionalDependencies: source-map "~0.6.1" +eslint-config-prettier@^9.0.0: + version "9.0.0" + resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-9.0.0.tgz#eb25485946dd0c66cd216a46232dc05451518d1f" + integrity sha512-IcJsTkJae2S35pRsRAwoCE+925rJJStOdkKnLVgtE+tEpqU0EVVM7OqrwxqgptKdX29NUwC82I5pXsGFIgSevw== + eslint-config-react-app@^7.0.1: version "7.0.1" resolved "https://registry.yarnpkg.com/eslint-config-react-app/-/eslint-config-react-app-7.0.1.tgz#73ba3929978001c5c86274c017ea57eb5fa644b4" @@ -4962,21 +5292,56 @@ eslint-config-react-app@^7.0.1: eslint-plugin-react-hooks "^4.3.0" eslint-plugin-testing-library "^5.0.1" -eslint-import-resolver-node@^0.3.6: - version "0.3.6" - resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.6.tgz#4048b958395da89668252001dbd9eca6b83bacbd" - integrity sha512-0En0w03NRVMn9Uiyn8YRPDKvWjxCWkslUEhGNTdGx15RvPJYQ+lbOlqrlNI2vEAs4pDYK4f/HN2TbDmk5TP0iw== +eslint-config-standard-with-typescript@^39.0.0: + version "39.0.0" + resolved "https://registry.yarnpkg.com/eslint-config-standard-with-typescript/-/eslint-config-standard-with-typescript-39.0.0.tgz#310847a474298cd64a8664a1d5b5434fb30e37b9" + integrity sha512-CiV2LS4NUeeRmDTDf1ocUMpMxitSyW0g+Y/N7ecElwGj188GahbcQgqfBNyVsIXQxHlZVBlOjkbg3oUI0R3KBg== + dependencies: + "@typescript-eslint/parser" "^6.4.0" + eslint-config-standard "17.1.0" + +eslint-config-standard@17.1.0: + version "17.1.0" + resolved "https://registry.yarnpkg.com/eslint-config-standard/-/eslint-config-standard-17.1.0.tgz#40ffb8595d47a6b242e07cbfd49dc211ed128975" + integrity sha512-IwHwmaBNtDK4zDHQukFDW5u/aTb8+meQWZvNFWkiGmbWjD6bqyuSSBxxXKkCftCUzc1zwCH2m/baCNDLGmuO5Q== + +eslint-import-resolver-node@^0.3.7: + version "0.3.9" + resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz#d4eaac52b8a2e7c3cd1903eb00f7e053356118ac" + integrity sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g== dependencies: debug "^3.2.7" - resolve "^1.20.0" + is-core-module "^2.13.0" + resolve "^1.22.4" + +eslint-import-resolver-typescript@^3.6.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/eslint-import-resolver-typescript/-/eslint-import-resolver-typescript-3.6.0.tgz#36f93e1eb65a635e688e16cae4bead54552e3bbd" + integrity sha512-QTHR9ddNnn35RTxlaEnx2gCxqFlF2SEN0SE2d17SqwyM7YOSI2GHWRYp5BiRkObTUNYPupC/3Fq2a0PpT+EKpg== + dependencies: + debug "^4.3.4" + enhanced-resolve "^5.12.0" + eslint-module-utils "^2.7.4" + fast-glob "^3.3.1" + get-tsconfig "^4.5.0" + is-core-module "^2.11.0" + is-glob "^4.0.3" -eslint-module-utils@^2.7.3: - version "2.7.4" - resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.7.4.tgz#4f3e41116aaf13a20792261e61d3a2e7e0583974" - integrity sha512-j4GT+rqzCoRKHwURX7pddtIPGySnX9Si/cgMI5ztrcqOPtk5dDEeZ34CQVPphnqkJytlc97Vuk05Um2mJ3gEQA== +eslint-module-utils@^2.7.4, eslint-module-utils@^2.8.0: + version "2.8.0" + resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.8.0.tgz#e439fee65fc33f6bba630ff621efc38ec0375c49" + integrity sha512-aWajIYfsqCKRDgUfjEXNN/JlrzauMuSEy5sbd7WXbtW3EH6A6MpwEh42c7qD+MqQo9QMJ6fWLAeIJynx0g6OAw== dependencies: debug "^3.2.7" +eslint-plugin-es-x@^7.1.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-es-x/-/eslint-plugin-es-x-7.2.0.tgz#5779d742ad31f8fd780b9481331481e142b72311" + integrity sha512-9dvv5CcvNjSJPqnS5uZkqb3xmbeqRLnvXKK7iI5+oK/yTusyc46zbBZKENGsOfojm/mKfszyZb+wNqNPAPeGXA== + dependencies: + "@eslint-community/eslint-utils" "^4.1.2" + "@eslint-community/regexpp" "^4.6.0" + eslint-plugin-flowtype@^8.0.3: version "8.0.3" resolved "https://registry.yarnpkg.com/eslint-plugin-flowtype/-/eslint-plugin-flowtype-8.0.3.tgz#e1557e37118f24734aa3122e7536a038d34a4912" @@ -4985,24 +5350,28 @@ eslint-plugin-flowtype@^8.0.3: lodash "^4.17.21" string-natural-compare "^3.0.1" -eslint-plugin-import@^2.25.3: - version "2.26.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.26.0.tgz#f812dc47be4f2b72b478a021605a59fc6fe8b88b" - integrity sha512-hYfi3FXaM8WPLf4S1cikh/r4IxnO6zrhZbEGz2b660EJRbuxgpDS5gkCuYgGWg2xxh2rBuIr4Pvhve/7c31koA== +eslint-plugin-import@^2.25.2, eslint-plugin-import@^2.25.3: + version "2.28.1" + resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.28.1.tgz#63b8b5b3c409bfc75ebaf8fb206b07ab435482c4" + integrity sha512-9I9hFlITvOV55alzoKBI+K9q74kv0iKMeY6av5+umsNwayt59fz692daGyjR+oStBQgx6nwR9rXldDev3Clw+A== dependencies: - array-includes "^3.1.4" - array.prototype.flat "^1.2.5" - debug "^2.6.9" + array-includes "^3.1.6" + array.prototype.findlastindex "^1.2.2" + array.prototype.flat "^1.3.1" + array.prototype.flatmap "^1.3.1" + debug "^3.2.7" doctrine "^2.1.0" - eslint-import-resolver-node "^0.3.6" - eslint-module-utils "^2.7.3" + eslint-import-resolver-node "^0.3.7" + eslint-module-utils "^2.8.0" has "^1.0.3" - is-core-module "^2.8.1" + is-core-module "^2.13.0" is-glob "^4.0.3" minimatch "^3.1.2" - object.values "^1.1.5" - resolve "^1.22.0" - tsconfig-paths "^3.14.1" + object.fromentries "^2.0.6" + object.groupby "^1.0.0" + object.values "^1.1.6" + semver "^6.3.1" + tsconfig-paths "^3.14.2" eslint-plugin-jest@^25.3.0: version "25.7.0" @@ -5012,38 +5381,69 @@ eslint-plugin-jest@^25.3.0: "@typescript-eslint/experimental-utils" "^5.0.0" eslint-plugin-jsx-a11y@^6.5.1: - version "6.6.1" - resolved "https://registry.yarnpkg.com/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.6.1.tgz#93736fc91b83fdc38cc8d115deedfc3091aef1ff" - integrity sha512-sXgFVNHiWffBq23uiS/JaP6eVR622DqwB4yTzKvGZGcPq6/yZ3WmOZfuBks/vHWo9GaFOqC2ZK4i6+C35knx7Q== + version "6.7.1" + resolved "https://registry.yarnpkg.com/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.7.1.tgz#fca5e02d115f48c9a597a6894d5bcec2f7a76976" + integrity sha512-63Bog4iIethyo8smBklORknVjB0T2dwB8Mr/hIC+fBS0uyHdYYpzM/Ed+YC8VxTjlXHEWFOdmgwcDn1U2L9VCA== dependencies: - "@babel/runtime" "^7.18.9" - aria-query "^4.2.2" - array-includes "^3.1.5" + "@babel/runtime" "^7.20.7" + aria-query "^5.1.3" + array-includes "^3.1.6" + array.prototype.flatmap "^1.3.1" ast-types-flow "^0.0.7" - axe-core "^4.4.3" - axobject-query "^2.2.0" + axe-core "^4.6.2" + axobject-query "^3.1.1" damerau-levenshtein "^1.0.8" emoji-regex "^9.2.2" has "^1.0.3" - jsx-ast-utils "^3.3.2" - language-tags "^1.0.5" + jsx-ast-utils "^3.3.3" + language-tags "=1.0.5" minimatch "^3.1.2" + object.entries "^1.1.6" + object.fromentries "^2.0.6" semver "^6.3.0" -eslint-plugin-react-hooks@^4.3.0: +"eslint-plugin-n@^15.0.0 || ^16.0.0 ": + version "16.0.2" + resolved "https://registry.yarnpkg.com/eslint-plugin-n/-/eslint-plugin-n-16.0.2.tgz#5b2c0ad8dd9b724244d30fad2cc49ff4308a2152" + integrity sha512-Y66uDfUNbBzypsr0kELWrIz+5skicECrLUqlWuXawNSLUq3ltGlCwu6phboYYOTSnoTdHgTLrc+5Ydo6KjzZog== + dependencies: + "@eslint-community/eslint-utils" "^4.4.0" + builtins "^5.0.1" + eslint-plugin-es-x "^7.1.0" + ignore "^5.2.4" + is-core-module "^2.12.1" + minimatch "^3.1.2" + resolve "^1.22.2" + semver "^7.5.3" + +eslint-plugin-prettier@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-prettier/-/eslint-plugin-prettier-5.0.0.tgz#6887780ed95f7708340ec79acfdf60c35b9be57a" + integrity sha512-AgaZCVuYDXHUGxj/ZGu1u8H8CYgDY3iG6w5kUFw4AzMVXzB7VvbKgYR4nATIN+OvUrghMbiDLeimVjVY5ilq3w== + dependencies: + prettier-linter-helpers "^1.0.0" + synckit "^0.8.5" + +eslint-plugin-promise@^6.0.0: + version "6.1.1" + resolved "https://registry.yarnpkg.com/eslint-plugin-promise/-/eslint-plugin-promise-6.1.1.tgz#269a3e2772f62875661220631bd4dafcb4083816" + integrity sha512-tjqWDwVZQo7UIPMeDReOpUgHCmCiH+ePnVT+5zVapL0uuHnegBUs2smM13CzOs2Xb5+MHMRFTs9v24yjba4Oig== + +eslint-plugin-react-hooks@^4.3.0, eslint-plugin-react-hooks@^4.6.0: version "4.6.0" resolved "https://registry.yarnpkg.com/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.6.0.tgz#4c3e697ad95b77e93f8646aaa1630c1ba607edd3" integrity sha512-oFc7Itz9Qxh2x4gNHStv3BqJq54ExXmfC+a1NjAta66IAN87Wu0R/QArgIS9qKzX3dXKPI9H5crl9QchNMY9+g== -eslint-plugin-react@^7.27.1: - version "7.31.11" - resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.31.11.tgz#011521d2b16dcf95795df688a4770b4eaab364c8" - integrity sha512-TTvq5JsT5v56wPa9OYHzsrOlHzKZKjV+aLgS+55NJP/cuzdiQPC7PfYoUjMoxlffKtvijpk7vA/jmuqRb9nohw== +eslint-plugin-react@^7.27.1, eslint-plugin-react@^7.33.2: + version "7.33.2" + resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.33.2.tgz#69ee09443ffc583927eafe86ffebb470ee737608" + integrity sha512-73QQMKALArI8/7xGLNI/3LylrEYrlKZSb5C9+q3OtOewTnMQi5cT+aE9E41sLCmli3I9PGGmD1yiZydyo4FEPw== dependencies: array-includes "^3.1.6" array.prototype.flatmap "^1.3.1" array.prototype.tosorted "^1.1.1" doctrine "^2.1.0" + es-iterator-helpers "^1.0.12" estraverse "^5.3.0" jsx-ast-utils "^2.4.1 || ^3.0.0" minimatch "^3.1.2" @@ -5052,16 +5452,23 @@ eslint-plugin-react@^7.27.1: object.hasown "^1.1.2" object.values "^1.1.6" prop-types "^15.8.1" - resolve "^2.0.0-next.3" - semver "^6.3.0" + resolve "^2.0.0-next.4" + semver "^6.3.1" string.prototype.matchall "^4.0.8" eslint-plugin-testing-library@^5.0.1: - version "5.9.1" - resolved "https://registry.yarnpkg.com/eslint-plugin-testing-library/-/eslint-plugin-testing-library-5.9.1.tgz#12e4bd34c48683ee98af4df2e3318ec9f51dcf8a" - integrity sha512-6BQp3tmb79jLLasPHJmy8DnxREe+2Pgf7L+7o09TSWPfdqqtQfRZmZNetr5mOs3yqZk/MRNxpN3RUpJe0wB4LQ== + version "5.11.1" + resolved "https://registry.yarnpkg.com/eslint-plugin-testing-library/-/eslint-plugin-testing-library-5.11.1.tgz#5b46cdae96d4a78918711c0b4792f90088e62d20" + integrity sha512-5eX9e1Kc2PqVRed3taaLnAAqPZGEX75C+M/rXzUAI3wIg/ZxzUm1OVAwfe/O+vE+6YXOLetSe9g5GKD2ecXipw== + dependencies: + "@typescript-eslint/utils" "^5.58.0" + +eslint-plugin-testing-library@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/eslint-plugin-testing-library/-/eslint-plugin-testing-library-6.0.1.tgz#c92325341f01fb2f76a3ab1c70d3c0c968c70b11" + integrity sha512-CEYtjpcF3hAaQtYsTZqciR7s5z+T0LCMTwJeW+pz6kBnGtc866wAKmhaiK2Gsjc2jWNP7Gt6zhNr2DE1ZW4e+g== dependencies: - "@typescript-eslint/utils" "^5.13.0" + "@typescript-eslint/utils" "^5.58.0" eslint-scope@5.1.1, eslint-scope@^5.1.1: version "5.1.1" @@ -5071,30 +5478,23 @@ eslint-scope@5.1.1, eslint-scope@^5.1.1: esrecurse "^4.3.0" estraverse "^4.1.1" -eslint-scope@^7.1.1: - version "7.1.1" - resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-7.1.1.tgz#fff34894c2f65e5226d3041ac480b4513a163642" - integrity sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw== +eslint-scope@^7.2.2: + version "7.2.2" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-7.2.2.tgz#deb4f92563390f32006894af62a22dba1c46423f" + integrity sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg== dependencies: esrecurse "^4.3.0" estraverse "^5.2.0" -eslint-utils@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-3.0.0.tgz#8aebaface7345bb33559db0a1f13a1d2d48c3672" - integrity sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA== - dependencies: - eslint-visitor-keys "^2.0.0" - -eslint-visitor-keys@^2.0.0, eslint-visitor-keys@^2.1.0: +eslint-visitor-keys@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz#f65328259305927392c938ed44eb0a5c9b2bd303" integrity sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw== -eslint-visitor-keys@^3.3.0: - version "3.3.0" - resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz#f6480fa6b1f30efe2d1968aa8ac745b862469826" - integrity sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA== +eslint-visitor-keys@^3.3.0, eslint-visitor-keys@^3.4.1, eslint-visitor-keys@^3.4.3: + version "3.4.3" + resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz#0cd72fe8550e3c2eae156a96a4dddcd1c8ac5800" + integrity sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag== eslint-webpack-plugin@^3.1.1: version "3.2.0" @@ -5107,69 +5507,67 @@ eslint-webpack-plugin@^3.1.1: normalize-path "^3.0.0" schema-utils "^4.0.0" -eslint@^8.3.0: - version "8.30.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.30.0.tgz#83a506125d089eef7c5b5910eeea824273a33f50" - integrity sha512-MGADB39QqYuzEGov+F/qb18r4i7DohCDOfatHaxI2iGlPuC65bwG2gxgO+7DkyL38dRFaRH7RaRAgU6JKL9rMQ== +eslint@^8.0.1, eslint@^8.3.0: + version "8.48.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.48.0.tgz#bf9998ba520063907ba7bfe4c480dc8be03c2155" + integrity sha512-sb6DLeIuRXxeM1YljSe1KEx9/YYeZFQWcV8Rq9HfigmdDEugjLEVEa1ozDjL6YDjBpQHPJxJzze+alxi4T3OLg== dependencies: - "@eslint/eslintrc" "^1.4.0" - "@humanwhocodes/config-array" "^0.11.8" + "@eslint-community/eslint-utils" "^4.2.0" + "@eslint-community/regexpp" "^4.6.1" + "@eslint/eslintrc" "^2.1.2" + "@eslint/js" "8.48.0" + "@humanwhocodes/config-array" "^0.11.10" "@humanwhocodes/module-importer" "^1.0.1" "@nodelib/fs.walk" "^1.2.8" - ajv "^6.10.0" + ajv "^6.12.4" chalk "^4.0.0" cross-spawn "^7.0.2" debug "^4.3.2" doctrine "^3.0.0" escape-string-regexp "^4.0.0" - eslint-scope "^7.1.1" - eslint-utils "^3.0.0" - eslint-visitor-keys "^3.3.0" - espree "^9.4.0" - esquery "^1.4.0" + eslint-scope "^7.2.2" + eslint-visitor-keys "^3.4.3" + espree "^9.6.1" + esquery "^1.4.2" esutils "^2.0.2" fast-deep-equal "^3.1.3" file-entry-cache "^6.0.1" find-up "^5.0.0" glob-parent "^6.0.2" globals "^13.19.0" - grapheme-splitter "^1.0.4" + graphemer "^1.4.0" ignore "^5.2.0" - import-fresh "^3.0.0" imurmurhash "^0.1.4" is-glob "^4.0.0" is-path-inside "^3.0.3" - js-sdsl "^4.1.4" js-yaml "^4.1.0" json-stable-stringify-without-jsonify "^1.0.1" levn "^0.4.1" lodash.merge "^4.6.2" minimatch "^3.1.2" natural-compare "^1.4.0" - optionator "^0.9.1" - regexpp "^3.2.0" + optionator "^0.9.3" strip-ansi "^6.0.1" - strip-json-comments "^3.1.0" text-table "^0.2.0" -espree@^9.4.0: - version "9.4.1" - resolved "https://registry.yarnpkg.com/espree/-/espree-9.4.1.tgz#51d6092615567a2c2cff7833445e37c28c0065bd" - integrity sha512-XwctdmTO6SIvCzd9810yyNzIrOrqNYV9Koizx4C/mRhf9uq0o4yHoCEU/670pOxOL/MSraektvSAji79kX90Vg== +espree@^9.6.0, espree@^9.6.1: + version "9.6.1" + resolved "https://registry.yarnpkg.com/espree/-/espree-9.6.1.tgz#a2a17b8e434690a5432f2f8018ce71d331a48c6f" + integrity sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ== dependencies: - acorn "^8.8.0" + acorn "^8.9.0" acorn-jsx "^5.3.2" - eslint-visitor-keys "^3.3.0" + eslint-visitor-keys "^3.4.1" esprima@^4.0.0, esprima@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== -esquery@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.4.0.tgz#2148ffc38b82e8c7057dfed48425b3e61f0f24a5" - integrity sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w== +esquery@^1.4.2: + version "1.5.0" + resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.5.0.tgz#6ce17738de8577694edd7361c57182ac8cb0db0b" + integrity sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg== dependencies: estraverse "^5.1.0" @@ -5230,6 +5628,21 @@ execa@^5.0.0: signal-exit "^3.0.3" strip-final-newline "^2.0.0" +execa@^7.1.1: + version "7.2.0" + resolved "https://registry.yarnpkg.com/execa/-/execa-7.2.0.tgz#657e75ba984f42a70f38928cedc87d6f2d4fe4e9" + integrity sha512-UduyVP7TLB5IcAQl+OzLyLcS/l32W/GLg+AhHJ+ow40FOk2U3SAllPwR44v4vmdFwIWqpdwxxpQbF1n5ta9seA== + dependencies: + cross-spawn "^7.0.3" + get-stream "^6.0.1" + human-signals "^4.3.0" + is-stream "^3.0.0" + merge-stream "^2.0.0" + npm-run-path "^5.1.0" + onetime "^6.0.0" + signal-exit "^3.0.7" + strip-final-newline "^3.0.0" + exit@^0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/exit/-/exit-0.1.2.tgz#0632638f8d877cc82107d30a0fff1a17cba1cd0c" @@ -5292,10 +5705,15 @@ fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== -fast-glob@^3.2.12, fast-glob@^3.2.9: - version "3.2.12" - resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.12.tgz#7f39ec99c2e6ab030337142da9e0c18f37afae80" - integrity sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w== +fast-diff@^1.1.2: + version "1.3.0" + resolved "https://registry.yarnpkg.com/fast-diff/-/fast-diff-1.3.0.tgz#ece407fa550a64d638536cd727e129c61616e0f0" + integrity sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw== + +fast-glob@^3.2.12, fast-glob@^3.2.9, fast-glob@^3.3.0, fast-glob@^3.3.1: + version "3.3.1" + resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.3.1.tgz#784b4e897340f3dbbef17413b3f11acf03c874c4" + integrity sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg== dependencies: "@nodelib/fs.stat" "^2.0.2" "@nodelib/fs.walk" "^1.2.3" @@ -5308,15 +5726,15 @@ fast-json-stable-stringify@^2.0.0, fast-json-stable-stringify@^2.1.0: resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== -fast-levenshtein@^2.0.6, fast-levenshtein@~2.0.6: +fast-levenshtein@^2.0.6: version "2.0.6" resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" integrity sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw== fastq@^1.6.0: - version "1.14.0" - resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.14.0.tgz#107f69d7295b11e0fccc264e1fc6389f623731ce" - integrity sha512-eR2D+V9/ExcbF9ls441yIuN6TI2ED1Y2ZcA5BmMtJsOkWOFRJQ0Jt0g1UwqXJJVAb+V+umH5Dfr8oh4EVP7VVg== + version "1.15.0" + resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.15.0.tgz#d04d07c6a2a68fe4599fea8d2e103a937fae6b3a" + integrity sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw== dependencies: reusify "^1.0.4" @@ -5356,7 +5774,7 @@ file-selector@^0.1.12: dependencies: tslib "^2.0.1" -filelist@^1.0.1: +filelist@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/filelist/-/filelist-1.0.4.tgz#f78978a1e944775ff9e62e744424f215e58352b5" integrity sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q== @@ -5426,14 +5844,15 @@ find-up@^5.0.0: path-exists "^4.0.0" flat-cache@^3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-3.0.4.tgz#61b0338302b2fe9f957dcc32fc2a87f1c3048b11" - integrity sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg== + version "3.1.0" + resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-3.1.0.tgz#0e54ab4a1a60fe87e2946b6b00657f1c99e1af3f" + integrity sha512-OHx4Qwrrt0E4jEIcI5/Xb+f+QmJYNj2rrK8wiIdQOIrB9WrrJL8cjZvXdXuBTkkEwEqLycb5BeZDV1o2i9bTew== dependencies: - flatted "^3.1.0" + flatted "^3.2.7" + keyv "^4.5.3" rimraf "^3.0.2" -flatted@^3.1.0: +flatted@^3.2.7: version "3.2.7" resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.2.7.tgz#609f39207cb614b89d0765b477cb2d437fbf9787" integrity sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ== @@ -5458,10 +5877,17 @@ fontkit@^2.0.2: unicode-properties "^1.4.0" unicode-trie "^2.0.0" +for-each@^0.3.3: + version "0.3.3" + resolved "https://registry.yarnpkg.com/for-each/-/for-each-0.3.3.tgz#69b447e88a0a5d32c3e7084f3f1710034b21376e" + integrity sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw== + dependencies: + is-callable "^1.1.3" + fork-ts-checker-webpack-plugin@^6.5.0: - version "6.5.2" - resolved "https://registry.yarnpkg.com/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-6.5.2.tgz#4f67183f2f9eb8ba7df7177ce3cf3e75cdafb340" - integrity sha512-m5cUmF30xkZ7h4tWUgTAcEaKmUW7tfyUyTqNNOz7OxWJ0v1VWKTcOvH8FWHUwSjlW/356Ijc9vi3XfcPstpQKA== + version "6.5.3" + resolved "https://registry.yarnpkg.com/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-6.5.3.tgz#eda2eff6e22476a2688d10661688c47f611b37f3" + integrity sha512-SbH/l9ikmMWycd5puHJKTkZJKddF4iRLyW3DeZ08HTI7NGyLS38MXd/KGgeWumQO7YNQbW2u/NtPT2YowbPaGQ== dependencies: "@babel/code-frame" "^7.8.3" "@types/json-schema" "^7.0.5" @@ -5501,9 +5927,9 @@ forwarded@0.2.0: integrity sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow== fraction.js@^4.2.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/fraction.js/-/fraction.js-4.2.0.tgz#448e5109a313a3527f5a3ab2119ec4cf0e0e2950" - integrity sha512-MhLuK+2gUcnZe8ZHlaaINnQLl0xRIGRfcGk2yl8xoQAfHrSsL3rYu6FCmBdkdbhc9EPlwyGHewaRsvwRMJtAlA== + version "4.3.4" + resolved "https://registry.yarnpkg.com/fraction.js/-/fraction.js-4.3.4.tgz#b2bac8249a610c3396106da97c5a71da75b94b1c" + integrity sha512-pwiTgt0Q7t+GHZA4yaLjObx4vXmmdcS0iSJ19o8d/goUGgItX9UZWKWNnLHehxviD8wU2IWRsnR8cD5+yOJP2Q== fresh@0.5.2: version "0.5.2" @@ -5529,10 +5955,10 @@ fs-extra@^9.0.0, fs-extra@^9.0.1: jsonfile "^6.0.1" universalify "^2.0.0" -fs-monkey@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/fs-monkey/-/fs-monkey-1.0.3.tgz#ae3ac92d53bb328efe0e9a1d9541f6ad8d48e2d3" - integrity sha512-cybjIfiiE+pTWicSCLFHSrXZ6EilF30oh91FDP9S2B051prEa7QWfrVTQm10/dDpswBDXZugPa1Ogu8Yh+HV0Q== +fs-monkey@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/fs-monkey/-/fs-monkey-1.0.4.tgz#ee8c1b53d3fe8bb7e5d2c5c5dfc0168afdd2f747" + integrity sha512-INM/fWAxMICjttnD0DX1rBvinKskj5G1w+oy/pnm9u/tSlnBrzFonJMcalKJ30P8RRsPzKcCG7Q8l0jx5Fh9YQ== fs.realpath@^1.0.0: version "1.0.0" @@ -5540,9 +5966,9 @@ fs.realpath@^1.0.0: integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== fsevents@^2.3.2, fsevents@~2.3.2: - version "2.3.2" - resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" - integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== + version "2.3.3" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6" + integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw== function-bind@^1.1.1: version "1.1.1" @@ -5550,16 +5976,16 @@ function-bind@^1.1.1: integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== function.prototype.name@^1.1.5: - version "1.1.5" - resolved "https://registry.yarnpkg.com/function.prototype.name/-/function.prototype.name-1.1.5.tgz#cce0505fe1ffb80503e6f9e46cc64e46a12a9621" - integrity sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA== + version "1.1.6" + resolved "https://registry.yarnpkg.com/function.prototype.name/-/function.prototype.name-1.1.6.tgz#cdf315b7d90ee77a4c6ee216c3c3362da07533fd" + integrity sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg== dependencies: call-bind "^1.0.2" - define-properties "^1.1.3" - es-abstract "^1.19.0" - functions-have-names "^1.2.2" + define-properties "^1.2.0" + es-abstract "^1.22.1" + functions-have-names "^1.2.3" -functions-have-names@^1.2.2: +functions-have-names@^1.2.3: version "1.2.3" resolved "https://registry.yarnpkg.com/functions-have-names/-/functions-have-names-1.2.3.tgz#0404fe4ee2ba2f607f0e0ec3c80bae994133b834" integrity sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ== @@ -5574,13 +6000,14 @@ get-caller-file@^2.0.5: resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== -get-intrinsic@^1.0.2, get-intrinsic@^1.1.1, get-intrinsic@^1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.1.3.tgz#063c84329ad93e83893c7f4f243ef63ffa351385" - integrity sha512-QJVz1Tj7MS099PevUG5jvnt9tSkXN8K14dxQlikJuPt4uD9hHAHjLyLBiLR5zELelBdD9QNRAXZzsJx0WaDL9A== +get-intrinsic@^1.0.2, get-intrinsic@^1.1.1, get-intrinsic@^1.1.3, get-intrinsic@^1.2.0, get-intrinsic@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.2.1.tgz#d295644fed4505fc9cde952c37ee12b477a83d82" + integrity sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw== dependencies: function-bind "^1.1.1" has "^1.0.3" + has-proto "^1.0.1" has-symbols "^1.0.3" get-own-enumerable-property-symbols@^3.0.0: @@ -5593,7 +6020,7 @@ get-package-type@^0.1.0: resolved "https://registry.yarnpkg.com/get-package-type/-/get-package-type-0.1.0.tgz#8de2d803cff44df3bc6c456e6668b36c3926e11a" integrity sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q== -get-stream@^6.0.0: +get-stream@^6.0.0, get-stream@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.1.tgz#a262d8eef67aced57c2852ad6167526a43cbf7b7" integrity sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg== @@ -5606,6 +6033,13 @@ get-symbol-description@^1.0.0: call-bind "^1.0.2" get-intrinsic "^1.1.1" +get-tsconfig@^4.5.0: + version "4.7.0" + resolved "https://registry.yarnpkg.com/get-tsconfig/-/get-tsconfig-4.7.0.tgz#06ce112a1463e93196aa90320c35df5039147e34" + integrity sha512-pmjiZ7xtB8URYm74PlGJozDNyhvsVLUcpBa8DZBG3bWHwaHa9bPiRpiSfovw+fjhwONSCWKRyk+JQHEGZmMrzw== + dependencies: + resolve-pkg-maps "^1.0.0" + glob-parent@^5.1.2, glob-parent@~5.1.2: version "5.1.2" resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" @@ -5625,6 +6059,18 @@ glob-to-regexp@^0.4.1: resolved "https://registry.yarnpkg.com/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz#c75297087c851b9a578bd217dd59a92f59fe546e" integrity sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw== +glob@7.1.6: + version "7.1.6" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6" + integrity sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.4" + once "^1.3.0" + path-is-absolute "^1.0.0" + glob@^7.1.1, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4, glob@^7.1.6: version "7.2.3" resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b" @@ -5659,12 +6105,19 @@ globals@^11.1.0: integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== globals@^13.19.0: - version "13.19.0" - resolved "https://registry.yarnpkg.com/globals/-/globals-13.19.0.tgz#7a42de8e6ad4f7242fbcca27ea5b23aca367b5c8" - integrity sha512-dkQ957uSRWHw7CFXLUtUHQI3g3aWApYhfNR2O6jn/907riyTYKVBmxYVROkBcY614FSSeSJh7Xm7SrUWCxvJMQ== + version "13.21.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-13.21.0.tgz#163aae12f34ef502f5153cfbdd3600f36c63c571" + integrity sha512-ybyme3s4yy/t/3s35bewwXKOf7cvzfreG2lH0lZl0JB7I4GxRP2ghxOK/Nb9EkRXdbBXZLfq/p/0W2JUONB/Gg== dependencies: type-fest "^0.20.2" +globalthis@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/globalthis/-/globalthis-1.0.3.tgz#5852882a52b80dc301b0660273e1ed082f0b6ccf" + integrity sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA== + dependencies: + define-properties "^1.1.3" + globby@^11.0.4, globby@^11.1.0: version "11.1.0" resolved "https://registry.yarnpkg.com/globby/-/globby-11.1.0.tgz#bd4be98bb042f83d796f7e3811991fbe82a0d34b" @@ -5685,14 +6138,14 @@ gopd@^1.0.1: get-intrinsic "^1.1.3" graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.4, graceful-fs@^4.2.6, graceful-fs@^4.2.9: - version "4.2.10" - resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.10.tgz#147d3a006da4ca3ce14728c7aefc287c367d7a6c" - integrity sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA== + version "4.2.11" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.11.tgz#4183e4e8bf08bb6e05bbb2f7d2e0c8f712ca40e3" + integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ== -grapheme-splitter@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz#9cf3a665c6247479896834af35cf1dbb4400767e" - integrity sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ== +graphemer@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/graphemer/-/graphemer-1.4.0.tgz#fb2f1d55e0e3a1849aeffc90c4fa0dd53a0e66c6" + integrity sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag== gzip-size@^6.0.0: version "6.0.0" @@ -5733,6 +6186,11 @@ has-property-descriptors@^1.0.0: dependencies: get-intrinsic "^1.1.1" +has-proto@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/has-proto/-/has-proto-1.0.1.tgz#1885c1305538958aff469fef37937c22795408e0" + integrity sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg== + has-symbols@^1.0.1, has-symbols@^1.0.2, has-symbols@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.3.tgz#bb7b2c4349251dce87b125f7bdf874aa7c8b39f8" @@ -5888,9 +6346,9 @@ html-encoding-sniffer@^2.0.1: whatwg-encoding "^1.0.5" html-entities@^2.1.0, html-entities@^2.3.2: - version "2.3.3" - resolved "https://registry.yarnpkg.com/html-entities/-/html-entities-2.3.3.tgz#117d7626bece327fc8baace8868fa6f5ef856e46" - integrity sha512-DV5Ln36z34NNTDgnz0EWGBLZENelNAtkiFA4kyNOG2tDI6Mz1uSWiq1wAKdyjnJwyDiDO7Fa2SO1CTxPXL8VxA== + version "2.4.0" + resolved "https://registry.yarnpkg.com/html-entities/-/html-entities-2.4.0.tgz#edd0cee70402584c8c76cc2c0556db09d1f45061" + integrity sha512-igBTJcNNNhvZFRtm8uA6xMY6xYleeDwn3PeBCkDz7tHttv4F2hsDI2aPgNERWzvRcNYHNT3ymRaQzllmXj4YsQ== html-escaper@^2.0.0: version "2.0.2" @@ -5916,9 +6374,9 @@ html-void-elements@^2.0.0: integrity sha512-0quDb7s97CfemeJAnW9wC0hw78MtW7NU3hqtCD75g2vFlDLt36llsYD7uB7SUzojLMP24N5IatXf7ylGXiGG9A== html-webpack-plugin@^5.5.0: - version "5.5.0" - resolved "https://registry.yarnpkg.com/html-webpack-plugin/-/html-webpack-plugin-5.5.0.tgz#c3911936f57681c1f9f4d8b68c158cd9dfe52f50" - integrity sha512-sy88PC2cRTVxvETRgUHFrL4No3UxvcH8G1NepGhqaTT+GXN2kTamqasot0inS5hXeg1cMbFDt27zzo9p35lZVw== + version "5.5.3" + resolved "https://registry.yarnpkg.com/html-webpack-plugin/-/html-webpack-plugin-5.5.3.tgz#72270f4a78e222b5825b296e5e3e1328ad525a3e" + integrity sha512-6YrDKTuqaP/TquFH7h4srYWsZx+x6k6+FbsTm0ziCwGHDP78Unr1r9F/H4+sGmMbX08GQcJ+K64x55b+7VM/jg== dependencies: "@types/html-minifier-terser" "^6.0.0" html-minifier-terser "^6.0.2" @@ -6009,10 +6467,15 @@ human-signals@^2.1.0: resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0" integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw== +human-signals@^4.3.0: + version "4.3.1" + resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-4.3.1.tgz#ab7f811e851fca97ffbd2c1fe9a958964de321b2" + integrity sha512-nZXjEF2nbo7lIw3mgYjItAfgQXog3OjJogSbKa2CQIIvSGWcKgeJnQlNXip6NglNzYH45nSRiEVimMvYL8DDqQ== + hyphen@^1.6.4: - version "1.6.5" - resolved "https://registry.yarnpkg.com/hyphen/-/hyphen-1.6.5.tgz#956a4c929c111441dc798ad88de3c941e1b383d3" - integrity sha512-MZbhHutRaHCUxjvJBYqL51Ntjbq16LemuJr2u+LpKd3UwyNHZsZAKh5uD+KmdAHtWpteupOqQTTezVGR/al43w== + version "1.6.6" + resolved "https://registry.yarnpkg.com/hyphen/-/hyphen-1.6.6.tgz#970678bb5182e9ee957f1a76ba109849d16dcc04" + integrity sha512-XtqmnT+b9n5MX+MsqluFAVTIenbtC25iskW0Z+jLd+awfhA+ZbWKWQMIvLJccGoa2bM1R6juWJ27cZxIFOmkWw== hyphenate-style-name@^1.0.3: version "1.0.4" @@ -6050,7 +6513,7 @@ identity-obj-proxy@^3.0.0: dependencies: harmony-reflect "^1.4.6" -ignore@^5.2.0: +ignore@^5.2.0, ignore@^5.2.4: version "5.2.4" resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.4.tgz#a291c0c6178ff1b960befe47fcdec301674a6324" integrity sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ== @@ -6061,11 +6524,11 @@ immediate@~3.0.5: integrity sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ== immer@^9.0.7: - version "9.0.16" - resolved "https://registry.yarnpkg.com/immer/-/immer-9.0.16.tgz#8e7caab80118c2b54b37ad43e05758cdefad0198" - integrity sha512-qenGE7CstVm1NrHQbMh8YaSzTZTFNP3zPqr3YU0S0UY441j4bJTg4A2Hh5KAhwgaiU6ZZ1Ar6y/2f4TblnMReQ== + version "9.0.21" + resolved "https://registry.yarnpkg.com/immer/-/immer-9.0.21.tgz#1e025ea31a40f24fb064f1fef23e931496330176" + integrity sha512-bc4NBHqOqSfRW7POMkHd51LvClaeMXpm8dx0e8oE2GORbq5aRK7Bxl4FyzVLdGtLmvLKL7BTDBG5ACQm4HWjTA== -import-fresh@^3.0.0, import-fresh@^3.1.0, import-fresh@^3.2.1: +import-fresh@^3.1.0, import-fresh@^3.2.1: version "3.3.0" resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b" integrity sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw== @@ -6114,12 +6577,12 @@ inline-style-parser@0.1.1: resolved "https://registry.yarnpkg.com/inline-style-parser/-/inline-style-parser-0.1.1.tgz#ec8a3b429274e9c0a1f1c4ffa9453a7fef72cea1" integrity sha512-7NXolsK4CAS5+xvdj5OMMbI962hU/wvwoxk+LWR9Ek9bVtyuuYScDN6eS0rUm6TxApFpw7CX1o4uJzcd4AyD3Q== -internal-slot@^1.0.3: - version "1.0.4" - resolved "https://registry.yarnpkg.com/internal-slot/-/internal-slot-1.0.4.tgz#8551e7baf74a7a6ba5f749cfb16aa60722f0d6f3" - integrity sha512-tA8URYccNzMo94s5MQZgH8NB/XTa6HsOo0MLfXTKKEnHVVdegzaQoFZ7Jp44bdvLvY2waT5dc+j5ICEswhi7UQ== +internal-slot@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/internal-slot/-/internal-slot-1.0.5.tgz#f2a2ee21f668f8627a4667f309dc0f4fb6674986" + integrity sha512-Y+R5hJrzs52QCG2laLn4udYVnxsfny9CpOhNhUvk/SSSVyF6T27FzRbF0sroPidSu3X8oEAkOn2K804mjpt6UQ== dependencies: - get-intrinsic "^1.1.3" + get-intrinsic "^1.2.0" has "^1.0.3" side-channel "^1.0.4" @@ -6129,9 +6592,9 @@ ipaddr.js@1.9.1: integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g== ipaddr.js@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-2.0.1.tgz#eca256a7a877e917aeb368b0a7497ddf42ef81c0" - integrity sha512-1qTgH9NG+IIJ4yfKs2e6Pp1bZg8wbDbKHT21HrLIeYBTRLgMYKnMTPAuI3Lcs61nfx5h1xlXnbJtH1kX5/d/ng== + version "2.1.0" + resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-2.1.0.tgz#2119bc447ff8c257753b196fc5f1ce08a4cdf39f" + integrity sha512-LlbxQ7xKzfBusov6UMi4MFpEg0m+mAm9xyNGEduwXMEDuf4WfzB/RZwMVYEd7IKGvh4IUkEXYxtAVu9T3OelJQ== is-alphabetical@^2.0.0: version "2.0.1" @@ -6146,6 +6609,15 @@ is-alphanumerical@^2.0.0: is-alphabetical "^2.0.0" is-decimal "^2.0.0" +is-array-buffer@^3.0.1, is-array-buffer@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/is-array-buffer/-/is-array-buffer-3.0.2.tgz#f2653ced8412081638ecb0ebbd0c41c6e0aecbbe" + integrity sha512-y+FyyR/w8vfIRq4eQcM1EYgSTnmHXPqaF+IgzgraytCFq5Xh8lllDVmAZolPJiZttZLeFSINPYMaEJ7/vWUa1w== + dependencies: + call-bind "^1.0.2" + get-intrinsic "^1.2.0" + is-typed-array "^1.1.10" + is-arrayish@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" @@ -6156,6 +6628,13 @@ is-arrayish@^0.3.1: resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.3.2.tgz#4574a2ae56f7ab206896fb431eaeed066fdf8f03" integrity sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ== +is-async-function@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-async-function/-/is-async-function-2.0.0.tgz#8e4418efd3e5d3a6ebb0164c05ef5afb69aa9646" + integrity sha512-Y1JXKrfykRJGdlDwdKlLpLyMIiWqWvuSd17TvZk68PLAOGOoF4Xyav1z0Xhoi+gCYjZVeC5SI+hYFOfvXmGRCA== + dependencies: + has-tostringtag "^1.0.0" + is-bigint@^1.0.1: version "1.0.4" resolved "https://registry.yarnpkg.com/is-bigint/-/is-bigint-1.0.4.tgz#08147a1875bc2b32005d41ccd8291dffc6691df3" @@ -6183,19 +6662,19 @@ is-buffer@^2.0.0, is-buffer@^2.0.5: resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-2.0.5.tgz#ebc252e400d22ff8d77fa09888821a24a658c191" integrity sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ== -is-callable@^1.1.4, is-callable@^1.2.7: +is-callable@^1.1.3, is-callable@^1.1.4, is-callable@^1.2.7: version "1.2.7" resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.7.tgz#3bc2a85ea742d9e36205dcacdd72ca1fdc51b055" integrity sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA== -is-core-module@^2.8.1, is-core-module@^2.9.0: - version "2.11.0" - resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.11.0.tgz#ad4cb3e3863e814523c96f3f58d26cc570ff0144" - integrity sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw== +is-core-module@^2.11.0, is-core-module@^2.12.1, is-core-module@^2.13.0, is-core-module@^2.9.0: + version "2.13.0" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.13.0.tgz#bb52aa6e2cbd49a30c2ba68c42bf3435ba6072db" + integrity sha512-Z7dk6Qo8pOCp3l4tsX2C5ZVas4V+UxwQodwZhLopL91TX8UyyHEXafPcyoeeWuLrwzHcr3igO78wNLwHJHsMCQ== dependencies: has "^1.0.3" -is-date-object@^1.0.1: +is-date-object@^1.0.1, is-date-object@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.5.tgz#0841d5536e724c25597bf6ea62e1bd38298df31f" integrity sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ== @@ -6212,11 +6691,23 @@ is-docker@^2.0.0, is-docker@^2.1.1: resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-2.2.1.tgz#33eeabe23cfe86f14bde4408a02c0cfb853acdaa" integrity sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ== +is-docker@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-3.0.0.tgz#90093aa3106277d8a77a5910dbae71747e15a200" + integrity sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ== + is-extglob@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ== +is-finalizationregistry@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-finalizationregistry/-/is-finalizationregistry-1.0.2.tgz#c8749b65f17c133313e661b1289b95ad3dbd62e6" + integrity sha512-0by5vtUJs8iFQb5TYUHHPudOR+qXYIMKtiUzvLIZITZUjknFmziyBJuLhVRc+Ds0dREFlskDNJKYIdIzu/9pfw== + dependencies: + call-bind "^1.0.2" + is-fullwidth-code-point@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" @@ -6227,6 +6718,13 @@ is-generator-fn@^2.0.0: resolved "https://registry.yarnpkg.com/is-generator-fn/-/is-generator-fn-2.1.0.tgz#7d140adc389aaf3011a8f2a2a4cfa6faadffb118" integrity sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ== +is-generator-function@^1.0.10: + version "1.0.10" + resolved "https://registry.yarnpkg.com/is-generator-function/-/is-generator-function-1.0.10.tgz#f1558baf1ac17e0deea7c0415c438351ff2b3c72" + integrity sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A== + dependencies: + has-tostringtag "^1.0.0" + is-glob@^4.0.0, is-glob@^4.0.1, is-glob@^4.0.3, is-glob@~4.0.1: version "4.0.3" resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" @@ -6244,6 +6742,18 @@ is-in-browser@^1.0.2, is-in-browser@^1.1.3: resolved "https://registry.yarnpkg.com/is-in-browser/-/is-in-browser-1.1.3.tgz#56ff4db683a078c6082eb95dad7dc62e1d04f835" integrity sha512-FeXIBgG/CPGd/WUxuEyvgGTEfwiG9Z4EKGxjNMRqviiIIfsmgrpnHLffEDdwUHqNva1VEW91o3xBT/m8Elgl9g== +is-inside-container@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-inside-container/-/is-inside-container-1.0.0.tgz#e81fba699662eb31dbdaf26766a61d4814717ea4" + integrity sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA== + dependencies: + is-docker "^3.0.0" + +is-map@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/is-map/-/is-map-2.0.2.tgz#00922db8c9bf73e81b7a335827bc2a43f2b91127" + integrity sha512-cOZFQQozTha1f4MxLFzlgKYPTyj26picdZTx82hbc/Xf4K/tZOOXSCkMvU4pKioRXGDLJRn0GM7Upe7kR721yg== + is-module@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-module/-/is-module-1.0.0.tgz#3258fb69f78c14d5b815d664336b4cffb6441591" @@ -6309,6 +6819,11 @@ is-root@^2.1.0: resolved "https://registry.yarnpkg.com/is-root/-/is-root-2.1.0.tgz#809e18129cf1129644302a4f8544035d51984a9c" integrity sha512-AGOriNp96vNBd3HtU+RzFEc75FfR5ymiYv8E553I71SCeXBiMsVDUtdio1OEFvrPyLIQ9tVR5RxXIFe5PUFjMg== +is-set@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/is-set/-/is-set-2.0.2.tgz#90755fa4c2562dc1c5d4024760d6119b94ca18ec" + integrity sha512-+2cnTEZeY5z/iXGbLhPrOAaK/Mau5k5eXq9j14CpRTftq0pAJu2MwVRSZhyZWBzx3o6X795Lz6Bpb6R0GKf37g== + is-shared-array-buffer@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz#8f259c573b60b6a32d4058a1a07430c0a7344c79" @@ -6321,6 +6836,11 @@ is-stream@^2.0.0: resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.1.tgz#fac1e3d53b97ad5a9d0ae9cef2389f5810a5c077" integrity sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg== +is-stream@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-3.0.0.tgz#e6bfd7aa6bef69f4f472ce9bb681e3e57b4319ac" + integrity sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA== + is-string@^1.0.5, is-string@^1.0.7: version "1.0.7" resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.0.7.tgz#0dd12bf2006f255bb58f695110eff7491eebc0fd" @@ -6335,6 +6855,13 @@ is-symbol@^1.0.2, is-symbol@^1.0.3: dependencies: has-symbols "^1.0.2" +is-typed-array@^1.1.10, is-typed-array@^1.1.9: + version "1.1.12" + resolved "https://registry.yarnpkg.com/is-typed-array/-/is-typed-array-1.1.12.tgz#d0bab5686ef4a76f7a73097b95470ab199c57d4a" + integrity sha512-Z14TF2JNG8Lss5/HMqt0//T9JeHXttXy5pH/DBU4vi98ozO2btxzq9MwYDZYnKwU8nRsz/+GVFVRDq3DkVuSPg== + dependencies: + which-typed-array "^1.1.11" + is-typedarray@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" @@ -6345,6 +6872,11 @@ is-url@^1.2.4: resolved "https://registry.yarnpkg.com/is-url/-/is-url-1.2.4.tgz#04a4df46d28c4cff3d73d01ff06abeb318a1aa52" integrity sha512-ITvGim8FhRiYe4IQ5uHSkj7pVaPDrCTkNd3yq3cV7iZAcJdHTUMPMEHcqSOy9xZ9qFenQCvi+2wjH9a1nXqHww== +is-weakmap@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/is-weakmap/-/is-weakmap-2.0.1.tgz#5008b59bdc43b698201d18f62b37b2ca243e8cf2" + integrity sha512-NSBR4kH5oVj1Uwvv970ruUkCV7O1mzgVFO4/rev2cLRda9Tm9HrL70ZPut4rOHgY0FNrUu9BCbXA2sdQ+x0chA== + is-weakref@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/is-weakref/-/is-weakref-1.0.2.tgz#9529f383a9338205e89765e0392efc2f100f06f2" @@ -6352,6 +6884,14 @@ is-weakref@^1.0.2: dependencies: call-bind "^1.0.2" +is-weakset@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/is-weakset/-/is-weakset-2.0.2.tgz#4569d67a747a1ce5a994dfd4ef6dcea76e7c0a1d" + integrity sha512-t2yVvttHkQktwnNNmBQ98AhENLdPUTDTE21uPqAQ0ARwQfGeQKRVS0NNurH7bTf7RrvcVn1OOge45CnBeHCSmg== + dependencies: + call-bind "^1.0.2" + get-intrinsic "^1.1.1" + is-wsl@^2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-2.2.0.tgz#74a4c76e77ca9fd3f932f290c17ea326cd157271" @@ -6359,6 +6899,11 @@ is-wsl@^2.2.0: dependencies: is-docker "^2.0.0" +isarray@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-2.0.5.tgz#8af1e4c1221244cc62459faf38940d4e644a5723" + integrity sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw== + isarray@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" @@ -6386,12 +6931,12 @@ istanbul-lib-instrument@^5.0.4, istanbul-lib-instrument@^5.1.0: semver "^6.3.0" istanbul-lib-report@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz#7518fe52ea44de372f460a76b5ecda9ffb73d8a6" - integrity sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw== + version "3.0.1" + resolved "https://registry.yarnpkg.com/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz#908305bac9a5bd175ac6a74489eafd0fc2445a7d" + integrity sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw== dependencies: istanbul-lib-coverage "^3.0.0" - make-dir "^3.0.0" + make-dir "^4.0.0" supports-color "^7.1.0" istanbul-lib-source-maps@^4.0.0: @@ -6404,22 +6949,32 @@ istanbul-lib-source-maps@^4.0.0: source-map "^0.6.1" istanbul-reports@^3.1.3: - version "3.1.5" - resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-3.1.5.tgz#cc9a6ab25cb25659810e4785ed9d9fb742578bae" - integrity sha512-nUsEMa9pBt/NOHqbcbeJEgqIlY/K7rVWUX6Lql2orY5e9roQOthbR3vtY4zzf2orPELg80fnxxk9zUyPlgwD1w== + version "3.1.6" + resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-3.1.6.tgz#2544bcab4768154281a2f0870471902704ccaa1a" + integrity sha512-TLgnMkKg3iTDsQ9PbPTdpfAK2DzjF9mqUG7RMgcQl8oFjad8ob4laGxv5XV5U9MAfx8D6tSJiUyuAwzLicaxlg== dependencies: html-escaper "^2.0.0" istanbul-lib-report "^3.0.0" +iterator.prototype@^1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/iterator.prototype/-/iterator.prototype-1.1.1.tgz#ab5b790e23ec00658f5974e032a2b05188bd3a5c" + integrity sha512-9E+nePc8C9cnQldmNl6bgpTY6zI4OPRZd97fhJ/iVZ1GifIUDVV5F6x1nEDqpe8KaMEZGT4xgrwKQDxXnjOIZQ== + dependencies: + define-properties "^1.2.0" + get-intrinsic "^1.2.1" + has-symbols "^1.0.3" + reflect.getprototypeof "^1.0.3" + jake@^10.8.5: - version "10.8.5" - resolved "https://registry.yarnpkg.com/jake/-/jake-10.8.5.tgz#f2183d2c59382cb274226034543b9c03b8164c46" - integrity sha512-sVpxYeuAhWt0OTWITwT98oyV0GsXyMlXCF+3L1SuafBVUIr/uILGRB+NqwkzhgXKvoJpDIpQvqkUALgdmQsQxw== + version "10.8.7" + resolved "https://registry.yarnpkg.com/jake/-/jake-10.8.7.tgz#63a32821177940c33f356e0ba44ff9d34e1c7d8f" + integrity sha512-ZDi3aP+fG/LchyBzUM804VjddnwfSfsdeYkwt8NcbKRvo4rFkjhs456iLFn3k2ZUWvNe4i48WACDbza8fhq2+w== dependencies: async "^3.2.3" chalk "^4.0.2" - filelist "^1.0.1" - minimatch "^3.0.4" + filelist "^1.0.4" + minimatch "^3.1.2" jest-changed-files@^27.5.1: version "27.5.1" @@ -6903,10 +7458,10 @@ jest@^27.4.3: import-local "^3.0.2" jest-cli "^27.5.1" -js-sdsl@^4.1.4: - version "4.2.0" - resolved "https://registry.yarnpkg.com/js-sdsl/-/js-sdsl-4.2.0.tgz#278e98b7bea589b8baaf048c20aeb19eb7ad09d0" - integrity sha512-dyBIzQBDkCqCu+0upx25Y2jGdbTGxE9fshMsCdK0ViOongpV+n5tXRcZY9v7CaVQ79AGS9KA1KHtojxiM7aXSQ== +jiti@^1.18.2: + version "1.19.3" + resolved "https://registry.yarnpkg.com/jiti/-/jiti-1.19.3.tgz#ef554f76465b3c2b222dc077834a71f0d4a37569" + integrity sha512-5eEbBDQT/jF1xg6l36P+mWGGoH9Spuy0PCdSr2dtWRDGC6ph/w9ZCL4lmESW8f8F7MwT3XKescfP0wnZWAKL9w== "js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0: version "4.0.0" @@ -6971,6 +7526,11 @@ jsesc@~0.5.0: resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d" integrity sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA== +json-buffer@3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.1.tgz#9338802a30d3b6605fbe0613e094008ca8c05a13" + integrity sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ== + json-parse-even-better-errors@^2.3.0, json-parse-even-better-errors@^2.3.1: version "2.3.1" resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz#7c47805a94319928e05777405dc12e1f7a4ee02d" @@ -6996,17 +7556,17 @@ json-stable-stringify-without-jsonify@^1.0.1: resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" integrity sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw== -json5@^1.0.1: +json5@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/json5/-/json5-1.0.2.tgz#63d98d60f21b313b77c4d6da18bfa69d80e1d593" integrity sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA== dependencies: minimist "^1.2.0" -json5@^2.1.2, json5@^2.2.0, json5@^2.2.1: - version "2.2.2" - resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.2.tgz#64471c5bdcc564c18f7c1d4df2e2297f2457c5ab" - integrity sha512-46Tk9JiOL2z7ytNQWFLpj99RZkVgeHf87yGQKsIkaPz1qSH9UczKH1rO7K3wgRselo0tYMUNfecYpm/p1vC7tQ== +json5@^2.1.2, json5@^2.2.0, json5@^2.2.3: + version "2.2.3" + resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.3.tgz#78cd6f1a19bdc12b73db5ad0c61efd66c1e29283" + integrity sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg== jsonfile@^6.0.1: version "6.1.0" @@ -7023,82 +7583,91 @@ jsonpointer@^5.0.0: integrity sha512-p/nXbhSEcu3pZRdkW1OfJhpsVtW1gd4Wa1fnQc9YLiTfAjn0312eMKimbdIQzuZl9aa9xUGaRlP9T/CJE/ditQ== jss-plugin-camel-case@^10.5.1: - version "10.9.2" - resolved "https://registry.yarnpkg.com/jss-plugin-camel-case/-/jss-plugin-camel-case-10.9.2.tgz#76dddfa32f9e62d17daa4e3504991fd0933b89e1" - integrity sha512-wgBPlL3WS0WDJ1lPJcgjux/SHnDuu7opmgQKSraKs4z8dCCyYMx9IDPFKBXQ8Q5dVYij1FFV0WdxyhuOOAXuTg== + version "10.10.0" + resolved "https://registry.yarnpkg.com/jss-plugin-camel-case/-/jss-plugin-camel-case-10.10.0.tgz#27ea159bab67eb4837fa0260204eb7925d4daa1c" + integrity sha512-z+HETfj5IYgFxh1wJnUAU8jByI48ED+v0fuTuhKrPR+pRBYS2EDwbusU8aFOpCdYhtRc9zhN+PJ7iNE8pAWyPw== dependencies: "@babel/runtime" "^7.3.1" hyphenate-style-name "^1.0.3" - jss "10.9.2" + jss "10.10.0" jss-plugin-default-unit@^10.5.1: - version "10.9.2" - resolved "https://registry.yarnpkg.com/jss-plugin-default-unit/-/jss-plugin-default-unit-10.9.2.tgz#3e7f4a1506b18d8fe231554fd982439feb2a9c53" - integrity sha512-pYg0QX3bBEFtTnmeSI3l7ad1vtHU42YEEpgW7pmIh+9pkWNWb5dwS/4onSfAaI0kq+dOZHzz4dWe+8vWnanoSg== + version "10.10.0" + resolved "https://registry.yarnpkg.com/jss-plugin-default-unit/-/jss-plugin-default-unit-10.10.0.tgz#db3925cf6a07f8e1dd459549d9c8aadff9804293" + integrity sha512-SvpajxIECi4JDUbGLefvNckmI+c2VWmP43qnEy/0eiwzRUsafg5DVSIWSzZe4d2vFX1u9nRDP46WCFV/PXVBGQ== dependencies: "@babel/runtime" "^7.3.1" - jss "10.9.2" + jss "10.10.0" jss-plugin-global@^10.5.1: - version "10.9.2" - resolved "https://registry.yarnpkg.com/jss-plugin-global/-/jss-plugin-global-10.9.2.tgz#e7f2ad4a5e8e674fb703b04b57a570b8c3e5c2c2" - integrity sha512-GcX0aE8Ef6AtlasVrafg1DItlL/tWHoC4cGir4r3gegbWwF5ZOBYhx04gurPvWHC8F873aEGqge7C17xpwmp2g== + version "10.10.0" + resolved "https://registry.yarnpkg.com/jss-plugin-global/-/jss-plugin-global-10.10.0.tgz#1c55d3c35821fab67a538a38918292fc9c567efd" + integrity sha512-icXEYbMufiNuWfuazLeN+BNJO16Ge88OcXU5ZDC2vLqElmMybA31Wi7lZ3lf+vgufRocvPj8443irhYRgWxP+A== dependencies: "@babel/runtime" "^7.3.1" - jss "10.9.2" + jss "10.10.0" jss-plugin-nested@^10.5.1: - version "10.9.2" - resolved "https://registry.yarnpkg.com/jss-plugin-nested/-/jss-plugin-nested-10.9.2.tgz#3aa2502816089ecf3981e1a07c49b276d67dca63" - integrity sha512-VgiOWIC6bvgDaAL97XCxGD0BxOKM0K0zeB/ECyNaVF6FqvdGB9KBBWRdy2STYAss4VVA7i5TbxFZN+WSX1kfQA== + version "10.10.0" + resolved "https://registry.yarnpkg.com/jss-plugin-nested/-/jss-plugin-nested-10.10.0.tgz#db872ed8925688806e77f1fc87f6e62264513219" + integrity sha512-9R4JHxxGgiZhurDo3q7LdIiDEgtA1bTGzAbhSPyIOWb7ZubrjQe8acwhEQ6OEKydzpl8XHMtTnEwHXCARLYqYA== dependencies: "@babel/runtime" "^7.3.1" - jss "10.9.2" + jss "10.10.0" tiny-warning "^1.0.2" jss-plugin-props-sort@^10.5.1: - version "10.9.2" - resolved "https://registry.yarnpkg.com/jss-plugin-props-sort/-/jss-plugin-props-sort-10.9.2.tgz#645f6c8f179309667b3e6212f66b59a32fb3f01f" - integrity sha512-AP1AyUTbi2szylgr+O0OB7gkIxEGzySLITZ2GpsaoX72YMCGI2jYAc+WUhPfvUnZYiauF4zTnN4V4TGuvFjJlw== + version "10.10.0" + resolved "https://registry.yarnpkg.com/jss-plugin-props-sort/-/jss-plugin-props-sort-10.10.0.tgz#67f4dd4c70830c126f4ec49b4b37ccddb680a5d7" + integrity sha512-5VNJvQJbnq/vRfje6uZLe/FyaOpzP/IH1LP+0fr88QamVrGJa0hpRRyAa0ea4U/3LcorJfBFVyC4yN2QC73lJg== dependencies: "@babel/runtime" "^7.3.1" - jss "10.9.2" + jss "10.10.0" jss-plugin-rule-value-function@^10.5.1: - version "10.9.2" - resolved "https://registry.yarnpkg.com/jss-plugin-rule-value-function/-/jss-plugin-rule-value-function-10.9.2.tgz#9afe07596e477123cbf11120776be6a64494541f" - integrity sha512-vf5ms8zvLFMub6swbNxvzsurHfUZ5Shy5aJB2gIpY6WNA3uLinEcxYyraQXItRHi5ivXGqYciFDRM2ZoVoRZ4Q== + version "10.10.0" + resolved "https://registry.yarnpkg.com/jss-plugin-rule-value-function/-/jss-plugin-rule-value-function-10.10.0.tgz#7d99e3229e78a3712f78ba50ab342e881d26a24b" + integrity sha512-uEFJFgaCtkXeIPgki8ICw3Y7VMkL9GEan6SqmT9tqpwM+/t+hxfMUdU4wQ0MtOiMNWhwnckBV0IebrKcZM9C0g== dependencies: "@babel/runtime" "^7.3.1" - jss "10.9.2" + jss "10.10.0" tiny-warning "^1.0.2" jss-plugin-vendor-prefixer@^10.5.1: - version "10.9.2" - resolved "https://registry.yarnpkg.com/jss-plugin-vendor-prefixer/-/jss-plugin-vendor-prefixer-10.9.2.tgz#410a0f3b9f8dbbfba58f4d329134df4849aa1237" - integrity sha512-SxcEoH+Rttf9fEv6KkiPzLdXRmI6waOTcMkbbEFgdZLDYNIP9UKNHFy6thhbRKqv0XMQZdrEsbDyV464zE/dUA== + version "10.10.0" + resolved "https://registry.yarnpkg.com/jss-plugin-vendor-prefixer/-/jss-plugin-vendor-prefixer-10.10.0.tgz#c01428ef5a89f2b128ec0af87a314d0c767931c7" + integrity sha512-UY/41WumgjW8r1qMCO8l1ARg7NHnfRVWRhZ2E2m0DMYsr2DD91qIXLyNhiX83hHswR7Wm4D+oDYNC1zWCJWtqg== dependencies: "@babel/runtime" "^7.3.1" css-vendor "^2.0.8" - jss "10.9.2" + jss "10.10.0" -jss@10.9.2, jss@^10.5.1: - version "10.9.2" - resolved "https://registry.yarnpkg.com/jss/-/jss-10.9.2.tgz#9379be1f195ef98011dfd31f9448251bd61b95a9" - integrity sha512-b8G6rWpYLR4teTUbGd4I4EsnWjg7MN0Q5bSsjKhVkJVjhQDy2KzkbD2AW3TuT0RYZVmZZHKIrXDn6kjU14qkUg== +jss@10.10.0, jss@^10.5.1: + version "10.10.0" + resolved "https://registry.yarnpkg.com/jss/-/jss-10.10.0.tgz#a75cc85b0108c7ac8c7b7d296c520a3e4fbc6ccc" + integrity sha512-cqsOTS7jqPsPMjtKYDUpdFC0AbhYFLTcuGRqymgmdJIeQ8cH7+AgX7YSgQy79wXloZq2VvATYxUOUQEvS1V/Zw== dependencies: "@babel/runtime" "^7.3.1" csstype "^3.0.2" is-in-browser "^1.1.3" tiny-warning "^1.0.2" -"jsx-ast-utils@^2.4.1 || ^3.0.0", jsx-ast-utils@^3.3.2: - version "3.3.3" - resolved "https://registry.yarnpkg.com/jsx-ast-utils/-/jsx-ast-utils-3.3.3.tgz#76b3e6e6cece5c69d49a5792c3d01bd1a0cdc7ea" - integrity sha512-fYQHZTZ8jSfmWZ0iyzfwiU4WDX4HpHbMCZ3gPlWYiCl3BoeOTsqKBqnTVfH2rYT7eP5c3sVbeSPHnnJOaTrWiw== +"jsx-ast-utils@^2.4.1 || ^3.0.0", jsx-ast-utils@^3.3.3: + version "3.3.5" + resolved "https://registry.yarnpkg.com/jsx-ast-utils/-/jsx-ast-utils-3.3.5.tgz#4766bd05a8e2a11af222becd19e15575e52a853a" + integrity sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ== + dependencies: + array-includes "^3.1.6" + array.prototype.flat "^1.3.1" + object.assign "^4.1.4" + object.values "^1.1.6" + +keyv@^4.5.3: + version "4.5.3" + resolved "https://registry.yarnpkg.com/keyv/-/keyv-4.5.3.tgz#00873d2b046df737963157bd04f294ca818c9c25" + integrity sha512-QCiSav9WaX1PgETJ+SpNnx2PRRapJ/oRSXM4VO5OGYGSjrxbKPVFVhB3l2OCbLCk329N8qyAtsJjSjvVBWzEug== dependencies: - array-includes "^3.1.5" - object.assign "^4.1.3" + json-buffer "3.0.1" kind-of@^6.0.2: version "6.0.3" @@ -7116,21 +7685,36 @@ kleur@^4.0.3: integrity sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ== klona@^2.0.4, klona@^2.0.5: - version "2.0.5" - resolved "https://registry.yarnpkg.com/klona/-/klona-2.0.5.tgz#d166574d90076395d9963aa7a928fabb8d76afbc" - integrity sha512-pJiBpiXMbt7dkzXe8Ghj/u4FfXOOa98fPW+bihOJ4SjnoijweJrNThJfd3ifXpXhREjpoF2mZVH1GfS9LV3kHQ== + version "2.0.6" + resolved "https://registry.yarnpkg.com/klona/-/klona-2.0.6.tgz#85bffbf819c03b2f53270412420a4555ef882e22" + integrity sha512-dhG34DXATL5hSxJbIexCft8FChFXtmskoZYnoPWjXQuebWYCNkVeV3KkGegCK9CP1oswI/vQibS2GY7Em/sJJA== -language-subtag-registry@^0.3.20: +language-subtag-registry@~0.3.2: version "0.3.22" resolved "https://registry.yarnpkg.com/language-subtag-registry/-/language-subtag-registry-0.3.22.tgz#2e1500861b2e457eba7e7ae86877cbd08fa1fd1d" integrity sha512-tN0MCzyWnoz/4nHS6uxdlFWoUZT7ABptwKPQ52Ea7URk6vll88bWBVhodtnlfEuCcKWNGoc+uGbw1cwa9IKh/w== -language-tags@^1.0.5: - version "1.0.7" - resolved "https://registry.yarnpkg.com/language-tags/-/language-tags-1.0.7.tgz#41cc248730f3f12a452c2e2efe32bc0bbce67967" - integrity sha512-bSytju1/657hFjgUzPAPqszxH62ouE8nQFoFaVlIQfne4wO/wXC9A4+m8jYve7YBBvi59eq0SUpcshvG8h5Usw== +language-tags@=1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/language-tags/-/language-tags-1.0.5.tgz#d321dbc4da30ba8bf3024e040fa5c14661f9193a" + integrity sha512-qJhlO9cGXi6hBGKoxEG/sKZDAHD5Hnu9Hs4WbOY3pCWXDhw0N8x1NenNzm2EnNLkLkk7J2SdxAkDSbb6ftT+UQ== + dependencies: + language-subtag-registry "~0.3.2" + +launch-editor@^2.6.0: + version "2.6.0" + resolved "https://registry.yarnpkg.com/launch-editor/-/launch-editor-2.6.0.tgz#4c0c1a6ac126c572bd9ff9a30da1d2cae66defd7" + integrity sha512-JpDCcQnyAAzZZaZ7vEiSqL690w7dAEyLao+KC96zBplnYbJS7TYNjvM3M7y3dGz+v7aIsJk3hllWuc0kWAjyRQ== + dependencies: + picocolors "^1.0.0" + shell-quote "^1.7.3" + +"legacy-swc-helpers@npm:@swc/helpers@=0.4.14": + version "0.4.14" + resolved "https://registry.yarnpkg.com/@swc/helpers/-/helpers-0.4.14.tgz#1352ac6d95e3617ccb7c1498ff019654f1e12a74" + integrity sha512-4C7nX/dvpzB7za4Ql9K81xK3HPxCpHMgwTZVyf+9JQ6VUbn9jjZVN7/Nkdz/Ugzs2CSjqnL/UPXroiVBVHUWUw== dependencies: - language-subtag-registry "^0.3.20" + tslib "^2.4.0" leven@^3.1.0: version "3.1.0" @@ -7145,14 +7729,6 @@ levn@^0.4.1: prelude-ls "^1.2.1" type-check "~0.4.0" -levn@~0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee" - integrity sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA== - dependencies: - prelude-ls "~1.1.2" - type-check "~0.3.2" - lie@3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/lie/-/lie-3.1.1.tgz#9a436b2cc7746ca59de7a41fa469b3efb76bd87e" @@ -7160,10 +7736,10 @@ lie@3.1.1: dependencies: immediate "~3.0.5" -lilconfig@^2.0.3, lilconfig@^2.0.5, lilconfig@^2.0.6: - version "2.0.6" - resolved "https://registry.yarnpkg.com/lilconfig/-/lilconfig-2.0.6.tgz#32a384558bd58af3d4c6e077dd1ad1d397bc69d4" - integrity sha512-9JROoBW7pobfsx+Sq2JsASvCo6Pfo6WWoUW79HuB1BCoBXD4PLWJPqDF6fNj67pqBYTbAHkE57M1kS/+L1neOg== +lilconfig@^2.0.3, lilconfig@^2.0.5, lilconfig@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/lilconfig/-/lilconfig-2.1.0.tgz#78e23ac89ebb7e1bfbf25b18043de756548e7f52" + integrity sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ== lines-and-columns@^1.1.6: version "1.2.4" @@ -7262,6 +7838,13 @@ lower-case@^2.0.2: dependencies: tslib "^2.0.3" +lru-cache@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920" + integrity sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w== + dependencies: + yallist "^3.0.2" + lru-cache@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" @@ -7276,13 +7859,20 @@ magic-string@^0.25.0, magic-string@^0.25.7: dependencies: sourcemap-codec "^1.4.8" -make-dir@^3.0.0, make-dir@^3.0.2, make-dir@^3.1.0: +make-dir@^3.0.2, make-dir@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-3.1.0.tgz#415e967046b3a7f1d185277d84aa58203726a13f" integrity sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw== dependencies: semver "^6.0.0" +make-dir@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-4.0.0.tgz#c3c2307a771277cd9638305f915c29ae741b614e" + integrity sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw== + dependencies: + semver "^7.5.3" + makeerror@1.0.12: version "1.0.12" resolved "https://registry.yarnpkg.com/makeerror/-/makeerror-1.0.12.tgz#3e5dd2079a82e812e983cc6610c4a2cb0eaa801a" @@ -7309,9 +7899,9 @@ mdast-util-definitions@^5.0.0: unist-util-visit "^4.0.0" mdast-util-from-markdown@^1.0.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/mdast-util-from-markdown/-/mdast-util-from-markdown-1.3.0.tgz#0214124154f26154a2b3f9d401155509be45e894" - integrity sha512-HN3W1gRIuN/ZW295c7zi7g9lVBllMgZE40RxCX37wrTPWXCWtpvOZdfnuK+1WNpvZje6XuJeI3Wnb4TJEUem+g== + version "1.3.1" + resolved "https://registry.yarnpkg.com/mdast-util-from-markdown/-/mdast-util-from-markdown-1.3.1.tgz#9421a5a247f10d31d2faed2a30df5ec89ceafcf0" + integrity sha512-4xTO/M8c82qBcnQc1tgpNtubGUW/Y1tBQ1B0i5CtSoelOLKFYlElIr3bvgREYYO5iRqbMY1YuqZng0GVOI8Qww== dependencies: "@types/mdast" "^3.0.0" "@types/unist" "^2.0.0" @@ -7368,11 +7958,11 @@ media-typer@0.3.0: integrity sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ== memfs@^3.1.2, memfs@^3.4.3: - version "3.4.12" - resolved "https://registry.yarnpkg.com/memfs/-/memfs-3.4.12.tgz#d00f8ad8dab132dc277c659dc85bfd14b07d03bd" - integrity sha512-BcjuQn6vfqP+k100e0E9m61Hyqa//Brp+I3f0OBmN0ATHlFA8vx3Lt8z57R3u2bPqe3WGDBC+nF72fTH7isyEw== + version "3.6.0" + resolved "https://registry.yarnpkg.com/memfs/-/memfs-3.6.0.tgz#d7a2110f86f79dd950a8b6df6d57bc984aa185f6" + integrity sha512-EGowvkkgbMcIChjMTMkESFDbZeSh8xZ7kNSF0hAiAN4Jh6jgHCRS0Ga/+C8y6Au+oqpezRHCfPsmJ2+DwAgiwQ== dependencies: - fs-monkey "^1.0.3" + fs-monkey "^1.0.4" merge-descriptors@1.0.1: version "1.0.1" @@ -7395,9 +7985,9 @@ methods@~1.1.2: integrity sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w== micromark-core-commonmark@^1.0.1: - version "1.0.6" - resolved "https://registry.yarnpkg.com/micromark-core-commonmark/-/micromark-core-commonmark-1.0.6.tgz#edff4c72e5993d93724a3c206970f5a15b0585ad" - integrity sha512-K+PkJTxqjFfSNkfAhp4GB+cZPfQd6dxtTXnf+RjZOV7T4EEXnvgzOcnp+eSTmpGk9d1S9sL6/lqrgSNn/s0HZA== + version "1.1.0" + resolved "https://registry.yarnpkg.com/micromark-core-commonmark/-/micromark-core-commonmark-1.1.0.tgz#1386628df59946b2d39fb2edfd10f3e8e0a75bb8" + integrity sha512-BgHO1aRbolh2hcrzL2d1La37V0Aoz73ymF8rAcKnohLy93titmv62E0gP8Hrx9PKcKrqCZ1BbLGbP3bEhoXYlw== dependencies: decode-named-character-reference "^1.0.0" micromark-factory-destination "^1.0.0" @@ -7417,18 +8007,18 @@ micromark-core-commonmark@^1.0.1: uvu "^0.5.0" micromark-factory-destination@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/micromark-factory-destination/-/micromark-factory-destination-1.0.0.tgz#fef1cb59ad4997c496f887b6977aa3034a5a277e" - integrity sha512-eUBA7Rs1/xtTVun9TmV3gjfPz2wEwgK5R5xcbIM5ZYAtvGF6JkyaDsj0agx8urXnO31tEO6Ug83iVH3tdedLnw== + version "1.1.0" + resolved "https://registry.yarnpkg.com/micromark-factory-destination/-/micromark-factory-destination-1.1.0.tgz#eb815957d83e6d44479b3df640f010edad667b9f" + integrity sha512-XaNDROBgx9SgSChd69pjiGKbV+nfHGDPVYFs5dOoDd7ZnMAE+Cuu91BCpsY8RT2NP9vo/B8pds2VQNCLiu0zhg== dependencies: micromark-util-character "^1.0.0" micromark-util-symbol "^1.0.0" micromark-util-types "^1.0.0" micromark-factory-label@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/micromark-factory-label/-/micromark-factory-label-1.0.2.tgz#6be2551fa8d13542fcbbac478258fb7a20047137" - integrity sha512-CTIwxlOnU7dEshXDQ+dsr2n+yxpP0+fn271pu0bwDIS8uqfFcumXpj5mLn3hSC8iw2MUr6Gx8EcKng1dD7i6hg== + version "1.1.0" + resolved "https://registry.yarnpkg.com/micromark-factory-label/-/micromark-factory-label-1.1.0.tgz#cc95d5478269085cfa2a7282b3de26eb2e2dec68" + integrity sha512-OLtyez4vZo/1NjxGhcpDSbHQ+m0IIGnT8BoPamh+7jVlzLJBH98zzuCoUeMxvM6WsNeh8wx8cKvqLiPHEACn0w== dependencies: micromark-util-character "^1.0.0" micromark-util-symbol "^1.0.0" @@ -7436,28 +8026,27 @@ micromark-factory-label@^1.0.0: uvu "^0.5.0" micromark-factory-space@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/micromark-factory-space/-/micromark-factory-space-1.0.0.tgz#cebff49968f2b9616c0fcb239e96685cb9497633" - integrity sha512-qUmqs4kj9a5yBnk3JMLyjtWYN6Mzfcx8uJfi5XAveBniDevmZasdGBba5b4QsvRcAkmvGo5ACmSUmyGiKTLZew== + version "1.1.0" + resolved "https://registry.yarnpkg.com/micromark-factory-space/-/micromark-factory-space-1.1.0.tgz#c8f40b0640a0150751d3345ed885a080b0d15faf" + integrity sha512-cRzEj7c0OL4Mw2v6nwzttyOZe8XY/Z8G0rzmWQZTBi/jjwyw/U4uqKtUORXQrR5bAZZnbTI/feRV/R7hc4jQYQ== dependencies: micromark-util-character "^1.0.0" micromark-util-types "^1.0.0" micromark-factory-title@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/micromark-factory-title/-/micromark-factory-title-1.0.2.tgz#7e09287c3748ff1693930f176e1c4a328382494f" - integrity sha512-zily+Nr4yFqgMGRKLpTVsNl5L4PMu485fGFDOQJQBl2NFpjGte1e86zC0da93wf97jrc4+2G2GQudFMHn3IX+A== + version "1.1.0" + resolved "https://registry.yarnpkg.com/micromark-factory-title/-/micromark-factory-title-1.1.0.tgz#dd0fe951d7a0ac71bdc5ee13e5d1465ad7f50ea1" + integrity sha512-J7n9R3vMmgjDOCY8NPw55jiyaQnH5kBdV2/UXCtZIpnHH3P6nHUKaH7XXEYuWwx/xUJcawa8plLBEjMPU24HzQ== dependencies: micromark-factory-space "^1.0.0" micromark-util-character "^1.0.0" micromark-util-symbol "^1.0.0" micromark-util-types "^1.0.0" - uvu "^0.5.0" micromark-factory-whitespace@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/micromark-factory-whitespace/-/micromark-factory-whitespace-1.0.0.tgz#e991e043ad376c1ba52f4e49858ce0794678621c" - integrity sha512-Qx7uEyahU1lt1RnsECBiuEbfr9INjQTGa6Err+gF3g0Tx4YEviPbqqGKNv/NrBaE7dVHdn1bVZKM/n5I/Bak7A== + version "1.1.0" + resolved "https://registry.yarnpkg.com/micromark-factory-whitespace/-/micromark-factory-whitespace-1.1.0.tgz#798fb7489f4c8abafa7ca77eed6b5745853c9705" + integrity sha512-v2WlmiymVSp5oMg+1Q0N1Lxmt6pMhIHD457whWM7/GUlEks1hI9xj5w3zbc4uuMKXGisksZk8DzP2UyGbGqNsQ== dependencies: micromark-factory-space "^1.0.0" micromark-util-character "^1.0.0" @@ -7465,48 +8054,48 @@ micromark-factory-whitespace@^1.0.0: micromark-util-types "^1.0.0" micromark-util-character@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/micromark-util-character/-/micromark-util-character-1.1.0.tgz#d97c54d5742a0d9611a68ca0cd4124331f264d86" - integrity sha512-agJ5B3unGNJ9rJvADMJ5ZiYjBRyDpzKAOk01Kpi1TKhlT1APx3XZk6eN7RtSz1erbWHC2L8T3xLZ81wdtGRZzg== + version "1.2.0" + resolved "https://registry.yarnpkg.com/micromark-util-character/-/micromark-util-character-1.2.0.tgz#4fedaa3646db249bc58caeb000eb3549a8ca5dcc" + integrity sha512-lXraTwcX3yH/vMDaFWCQJP1uIszLVebzUa3ZHdrgxr7KEU/9mL4mVgCpGbyhvNLNlauROiNUq7WN5u7ndbY6xg== dependencies: micromark-util-symbol "^1.0.0" micromark-util-types "^1.0.0" micromark-util-chunked@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/micromark-util-chunked/-/micromark-util-chunked-1.0.0.tgz#5b40d83f3d53b84c4c6bce30ed4257e9a4c79d06" - integrity sha512-5e8xTis5tEZKgesfbQMKRCyzvffRRUX+lK/y+DvsMFdabAicPkkZV6gO+FEWi9RfuKKoxxPwNL+dFF0SMImc1g== + version "1.1.0" + resolved "https://registry.yarnpkg.com/micromark-util-chunked/-/micromark-util-chunked-1.1.0.tgz#37a24d33333c8c69a74ba12a14651fd9ea8a368b" + integrity sha512-Ye01HXpkZPNcV6FiyoW2fGZDUw4Yc7vT0E9Sad83+bEDiCJ1uXu0S3mr8WLpsz3HaG3x2q0HM6CTuPdcZcluFQ== dependencies: micromark-util-symbol "^1.0.0" micromark-util-classify-character@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/micromark-util-classify-character/-/micromark-util-classify-character-1.0.0.tgz#cbd7b447cb79ee6997dd274a46fc4eb806460a20" - integrity sha512-F8oW2KKrQRb3vS5ud5HIqBVkCqQi224Nm55o5wYLzY/9PwHGXC01tr3d7+TqHHz6zrKQ72Okwtvm/xQm6OVNZA== + version "1.1.0" + resolved "https://registry.yarnpkg.com/micromark-util-classify-character/-/micromark-util-classify-character-1.1.0.tgz#6a7f8c8838e8a120c8e3c4f2ae97a2bff9190e9d" + integrity sha512-SL0wLxtKSnklKSUplok1WQFoGhUdWYKggKUiqhX+Swala+BtptGCu5iPRc+xvzJ4PXE/hwM3FNXsfEVgoZsWbw== dependencies: micromark-util-character "^1.0.0" micromark-util-symbol "^1.0.0" micromark-util-types "^1.0.0" micromark-util-combine-extensions@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/micromark-util-combine-extensions/-/micromark-util-combine-extensions-1.0.0.tgz#91418e1e74fb893e3628b8d496085639124ff3d5" - integrity sha512-J8H058vFBdo/6+AsjHp2NF7AJ02SZtWaVUjsayNFeAiydTxUwViQPxN0Hf8dp4FmCQi0UUFovFsEyRSUmFH3MA== + version "1.1.0" + resolved "https://registry.yarnpkg.com/micromark-util-combine-extensions/-/micromark-util-combine-extensions-1.1.0.tgz#192e2b3d6567660a85f735e54d8ea6e3952dbe84" + integrity sha512-Q20sp4mfNf9yEqDL50WwuWZHUrCO4fEyeDCnMGmG5Pr0Cz15Uo7KBs6jq+dq0EgX4DPwwrh9m0X+zPV1ypFvUA== dependencies: micromark-util-chunked "^1.0.0" micromark-util-types "^1.0.0" micromark-util-decode-numeric-character-reference@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-1.0.0.tgz#dcc85f13b5bd93ff8d2868c3dba28039d490b946" - integrity sha512-OzO9AI5VUtrTD7KSdagf4MWgHMtET17Ua1fIpXTpuhclCqD8egFWo85GxSGvxgkGS74bEahvtM0WP0HjvV0e4w== + version "1.1.0" + resolved "https://registry.yarnpkg.com/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-1.1.0.tgz#b1e6e17009b1f20bc652a521309c5f22c85eb1c6" + integrity sha512-m9V0ExGv0jB1OT21mrWcuf4QhP46pH1KkfWy9ZEezqHKAxkj4mPCy3nIH1rkbdMlChLHX531eOrymlwyZIf2iw== dependencies: micromark-util-symbol "^1.0.0" micromark-util-decode-string@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/micromark-util-decode-string/-/micromark-util-decode-string-1.0.2.tgz#942252ab7a76dec2dbf089cc32505ee2bc3acf02" - integrity sha512-DLT5Ho02qr6QWVNYbRZ3RYOSSWWFuH3tJexd3dgN1odEuPNxCngTCXJum7+ViRAd9BbdxCvMToPOD/IvVhzG6Q== + version "1.1.0" + resolved "https://registry.yarnpkg.com/micromark-util-decode-string/-/micromark-util-decode-string-1.1.0.tgz#dc12b078cba7a3ff690d0203f95b5d5537f2809c" + integrity sha512-YphLGCK8gM1tG1bd54azwyrQRjCFcmgj2S2GoJDNnh4vYtnL38JS8M4gpxzOPNyHdNEpheyWXCTnnTDY3N+NVQ== dependencies: decode-named-character-reference "^1.0.0" micromark-util-character "^1.0.0" @@ -7514,42 +8103,42 @@ micromark-util-decode-string@^1.0.0: micromark-util-symbol "^1.0.0" micromark-util-encode@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/micromark-util-encode/-/micromark-util-encode-1.0.1.tgz#2c1c22d3800870ad770ece5686ebca5920353383" - integrity sha512-U2s5YdnAYexjKDel31SVMPbfi+eF8y1U4pfiRW/Y8EFVCy/vgxk/2wWTxzcqE71LHtCuCzlBDRU2a5CQ5j+mQA== + version "1.1.0" + resolved "https://registry.yarnpkg.com/micromark-util-encode/-/micromark-util-encode-1.1.0.tgz#92e4f565fd4ccb19e0dcae1afab9a173bbeb19a5" + integrity sha512-EuEzTWSTAj9PA5GOAs992GzNh2dGQO52UvAbtSOMvXTxv3Criqb6IOzJUBCmEqrrXSblJIJBbFFv6zPxpreiJw== micromark-util-html-tag-name@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/micromark-util-html-tag-name/-/micromark-util-html-tag-name-1.1.0.tgz#eb227118befd51f48858e879b7a419fc0df20497" - integrity sha512-BKlClMmYROy9UiV03SwNmckkjn8QHVaWkqoAqzivabvdGcwNGMMMH/5szAnywmsTBUzDsU57/mFi0sp4BQO6dA== + version "1.2.0" + resolved "https://registry.yarnpkg.com/micromark-util-html-tag-name/-/micromark-util-html-tag-name-1.2.0.tgz#48fd7a25826f29d2f71479d3b4e83e94829b3588" + integrity sha512-VTQzcuQgFUD7yYztuQFKXT49KghjtETQ+Wv/zUjGSGBioZnkA4P1XXZPT1FHeJA6RwRXSF47yvJ1tsJdoxwO+Q== micromark-util-normalize-identifier@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-1.0.0.tgz#4a3539cb8db954bbec5203952bfe8cedadae7828" - integrity sha512-yg+zrL14bBTFrQ7n35CmByWUTFsgst5JhA4gJYoty4Dqzj4Z4Fr/DHekSS5aLfH9bdlfnSvKAWsAgJhIbogyBg== + version "1.1.0" + resolved "https://registry.yarnpkg.com/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-1.1.0.tgz#7a73f824eb9f10d442b4d7f120fecb9b38ebf8b7" + integrity sha512-N+w5vhqrBihhjdpM8+5Xsxy71QWqGn7HYNUvch71iV2PM7+E3uWGox1Qp90loa1ephtCxG2ftRV/Conitc6P2Q== dependencies: micromark-util-symbol "^1.0.0" micromark-util-resolve-all@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/micromark-util-resolve-all/-/micromark-util-resolve-all-1.0.0.tgz#a7c363f49a0162e931960c44f3127ab58f031d88" - integrity sha512-CB/AGk98u50k42kvgaMM94wzBqozSzDDaonKU7P7jwQIuH2RU0TeBqGYJz2WY1UdihhjweivStrJ2JdkdEmcfw== + version "1.1.0" + resolved "https://registry.yarnpkg.com/micromark-util-resolve-all/-/micromark-util-resolve-all-1.1.0.tgz#4652a591ee8c8fa06714c9b54cd6c8e693671188" + integrity sha512-b/G6BTMSg+bX+xVCshPTPyAu2tmA0E4X98NSR7eIbeC6ycCqCeE7wjfDIgzEbkzdEVJXRtOG4FbEm/uGbCRouA== dependencies: micromark-util-types "^1.0.0" micromark-util-sanitize-uri@^1.0.0, micromark-util-sanitize-uri@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-1.1.0.tgz#f12e07a85106b902645e0364feb07cf253a85aee" - integrity sha512-RoxtuSCX6sUNtxhbmsEFQfWzs8VN7cTctmBPvYivo98xb/kDEoTCtJQX5wyzIYEmk/lvNFTat4hL8oW0KndFpg== + version "1.2.0" + resolved "https://registry.yarnpkg.com/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-1.2.0.tgz#613f738e4400c6eedbc53590c67b197e30d7f90d" + integrity sha512-QO4GXv0XZfWey4pYFndLUKEAktKkG5kZTdUNaTAkzbuJxn2tNBOr+QtxR2XpWaMhbImT2dPzyLrPXLlPhph34A== dependencies: micromark-util-character "^1.0.0" micromark-util-encode "^1.0.0" micromark-util-symbol "^1.0.0" micromark-util-subtokenize@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/micromark-util-subtokenize/-/micromark-util-subtokenize-1.0.2.tgz#ff6f1af6ac836f8bfdbf9b02f40431760ad89105" - integrity sha512-d90uqCnXp/cy4G881Ub4psE57Sf8YD0pim9QdjCRNjfas2M1u6Lbt+XZK9gnHL2XFhnozZiEdCa9CNfXSfQ6xA== + version "1.1.0" + resolved "https://registry.yarnpkg.com/micromark-util-subtokenize/-/micromark-util-subtokenize-1.1.0.tgz#941c74f93a93eaf687b9054aeb94642b0e92edb1" + integrity sha512-kUQHyzRoxvZO2PuLzMt2P/dwVsTiivCK8icYTeR+3WgbuPqfHgPPy7nFKbeqRivBvn/3N3GBiNC+JRTMSxEC7A== dependencies: micromark-util-chunked "^1.0.0" micromark-util-symbol "^1.0.0" @@ -7557,19 +8146,19 @@ micromark-util-subtokenize@^1.0.0: uvu "^0.5.0" micromark-util-symbol@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/micromark-util-symbol/-/micromark-util-symbol-1.0.1.tgz#b90344db62042ce454f351cf0bebcc0a6da4920e" - integrity sha512-oKDEMK2u5qqAptasDAwWDXq0tG9AssVwAx3E9bBF3t/shRIGsWIRG+cGafs2p/SnDSOecnt6hZPCE2o6lHfFmQ== + version "1.1.0" + resolved "https://registry.yarnpkg.com/micromark-util-symbol/-/micromark-util-symbol-1.1.0.tgz#813cd17837bdb912d069a12ebe3a44b6f7063142" + integrity sha512-uEjpEYY6KMs1g7QfJ2eX1SQEV+ZT4rUD3UcF6l57acZvLNK7PBZL+ty82Z1qhK1/yXIY4bdx04FKMgR0g4IAag== micromark-util-types@^1.0.0, micromark-util-types@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/micromark-util-types/-/micromark-util-types-1.0.2.tgz#f4220fdb319205812f99c40f8c87a9be83eded20" - integrity sha512-DCfg/T8fcrhrRKTPjRrw/5LLvdGV7BHySf/1LOZx7TzWZdYRjogNtyNq885z3nNallwr3QUKARjqvHqX1/7t+w== + version "1.1.0" + resolved "https://registry.yarnpkg.com/micromark-util-types/-/micromark-util-types-1.1.0.tgz#e6676a8cae0bb86a2171c498167971886cb7e283" + integrity sha512-ukRBgie8TIAcacscVHSiddHjO4k/q3pnedmzMQ4iwDcK0FtFCohKOlFbaOL/mPgfnPsL3C1ZyxJa4sbWrBl3jg== micromark@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/micromark/-/micromark-3.1.0.tgz#eeba0fe0ac1c9aaef675157b52c166f125e89f62" - integrity sha512-6Mj0yHLdUZjHnOPgr5xfWIMqMWS12zDN6iws9SLuSz76W8jTtAv24MN4/CL7gJrl5vtxGInkkqDv/JIoRsQOvA== + version "3.2.0" + resolved "https://registry.yarnpkg.com/micromark/-/micromark-3.2.0.tgz#1af9fef3f995ea1ea4ac9c7e2f19c48fd5c006e9" + integrity sha512-uD66tJj54JLYq0De10AhWycZWGQNUvDI55xPgk2sQM5kn1JYlhbCMTtEeT27+vAhW2FBQxLlOmS3pmA7/2z4aA== dependencies: "@types/debug" "^4.0.0" debug "^4.0.0" @@ -7619,10 +8208,15 @@ mimic-fn@^2.1.0: resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== +mimic-fn@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-4.0.0.tgz#60a90550d5cb0b239cca65d893b1a53b29871ecc" + integrity sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw== + mini-css-extract-plugin@^2.4.5: - version "2.7.2" - resolved "https://registry.yarnpkg.com/mini-css-extract-plugin/-/mini-css-extract-plugin-2.7.2.tgz#e049d3ea7d3e4e773aad585c6cb329ce0c7b72d7" - integrity sha512-EdlUizq13o0Pd+uCp+WO/JpkLvHRVGt97RqfeGhXqAcorYo1ypJSpkV+WDT0vY/kmh/p7wRdJNJtuyK540PXDw== + version "2.7.6" + resolved "https://registry.yarnpkg.com/mini-css-extract-plugin/-/mini-css-extract-plugin-2.7.6.tgz#282a3d38863fddcd2e0c220aaed5b90bc156564d" + integrity sha512-Qk7HcgaPkGG6eD77mLvZS1nmxlao3j+9PkrT9Uc7HAE1id3F41+DdBRYRYkbyfNRGzm8/YWtzhw7nVPmwhqTQw== dependencies: schema-utils "^4.0.0" @@ -7639,16 +8233,16 @@ minimatch@^3.0.4, minimatch@^3.0.5, minimatch@^3.1.1, minimatch@^3.1.2: brace-expansion "^1.1.7" minimatch@^5.0.1: - version "5.1.2" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-5.1.2.tgz#0939d7d6f0898acbd1508abe534d1929368a8fff" - integrity sha512-bNH9mmM9qsJ2X4r2Nat1B//1dJVcn3+iBLa3IgqJ7EbGaDNepL9QSHOxN4ng33s52VMMhhIfgCYDk3C4ZmlDAg== + version "5.1.6" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-5.1.6.tgz#1cfcb8cf5522ea69952cd2af95ae09477f122a96" + integrity sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g== dependencies: brace-expansion "^2.0.1" minimist@^1.2.0, minimist@^1.2.6: - version "1.2.7" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.7.tgz#daa1c4d91f507390437c6a8bc01078e7000c4d18" - integrity sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g== + version "1.2.8" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c" + integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA== mkdirp@~0.5.1: version "0.5.6" @@ -7685,10 +8279,19 @@ multicast-dns@^7.2.5: dns-packet "^5.2.2" thunky "^1.0.2" -nanoid@^3.3.4: - version "3.3.4" - resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.4.tgz#730b67e3cd09e2deacf03c027c81c9d9dbc5e8ab" - integrity sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw== +mz@^2.7.0: + version "2.7.0" + resolved "https://registry.yarnpkg.com/mz/-/mz-2.7.0.tgz#95008057a56cafadc2bc63dde7f9ff6955948e32" + integrity sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q== + dependencies: + any-promise "^1.0.0" + object-assign "^4.0.1" + thenify-all "^1.0.0" + +nanoid@^3.3.6: + version "3.3.6" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.6.tgz#443380c856d6e9f9824267d960b4236ad583ea4c" + integrity sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA== natural-compare-lite@^1.4.0: version "1.4.0" @@ -7718,10 +8321,10 @@ no-case@^3.0.4: lower-case "^2.0.2" tslib "^2.0.3" -node-fetch@^2.6.11: - version "2.6.11" - resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.11.tgz#cde7fc71deef3131ef80a738919f999e6edfff25" - integrity sha512-4I6pdBY1EthSqDmJkiNk3JIT8cswwR9nfeW/cPdUagJYEQG7R95WRH74wpz7ma8Gh/9dI9FP+OU+0E4FvtA55w== +node-fetch@^2.6.12: + version "2.7.0" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.7.0.tgz#d0f0fa6e3e2dc1d27efcd8ad99d550bda94d187d" + integrity sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A== dependencies: whatwg-url "^5.0.0" @@ -7735,10 +8338,10 @@ node-int64@^0.4.0: resolved "https://registry.yarnpkg.com/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b" integrity sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw== -node-releases@^2.0.6: - version "2.0.8" - resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.8.tgz#0f349cdc8fcfa39a92ac0be9bc48b7706292b9ae" - integrity sha512-dFSmB8fFHEH/s81Xi+Y/15DQY6VHW81nXRj86EMSL3lmuTmK1e+aT4wrFCkTbm+gSwkw4KpX+rT/pMM2c1mF+A== +node-releases@^2.0.13: + version "2.0.13" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.13.tgz#d5ed1627c23e3461e819b02e57b75e4899b1c81d" + integrity sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ== normalize-path@^3.0.0, normalize-path@~3.0.0: version "3.0.0" @@ -7769,6 +8372,13 @@ npm-run-path@^4.0.1: dependencies: path-key "^3.0.0" +npm-run-path@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-5.1.0.tgz#bc62f7f3f6952d9894bd08944ba011a6ee7b7e00" + integrity sha512-sJOdmRGrY2sjNTRMbSvluQqg+8X7ZK61yvzBEIDhz4f8z1TZFYABsqjjCBd/0PUNE9M6QDgHJXQkGUEm7Q+l9Q== + dependencies: + path-key "^4.0.0" + nth-check@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-1.0.2.tgz#b2bd295c37e3dd58a3bf0700376663ba4d9cf05c" @@ -7784,11 +8394,11 @@ nth-check@^2.0.1: boolbase "^1.0.0" nwsapi@^2.2.0: - version "2.2.2" - resolved "https://registry.yarnpkg.com/nwsapi/-/nwsapi-2.2.2.tgz#e5418863e7905df67d51ec95938d67bf801f0bb0" - integrity sha512-90yv+6538zuvUMnN+zCr8LuV6bPFdq50304114vJYJ8RDyK8D5O9Phpbd6SZWgI7PwzmmfN1upeOJlvybDSgCw== + version "2.2.7" + resolved "https://registry.yarnpkg.com/nwsapi/-/nwsapi-2.2.7.tgz#738e0707d3128cb750dddcfe90e4610482df0f30" + integrity sha512-ub5E4+FBPKwAZx0UwIQOjYWGHTEq5sPqHQNRN8Z9e4A7u3Tj1weLJsL59yH9vmvqEtBHaOmT6cYQKIZOxp35FQ== -object-assign@^4.1.1: +object-assign@^4.0.1, object-assign@^4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" integrity sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg== @@ -7798,17 +8408,17 @@ object-hash@^3.0.0: resolved "https://registry.yarnpkg.com/object-hash/-/object-hash-3.0.0.tgz#73f97f753e7baffc0e2cc9d6e079079744ac82e9" integrity sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw== -object-inspect@^1.12.2, object-inspect@^1.9.0: - version "1.12.2" - resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.12.2.tgz#c0641f26394532f28ab8d796ab954e43c009a8ea" - integrity sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ== +object-inspect@^1.12.3, object-inspect@^1.9.0: + version "1.12.3" + resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.12.3.tgz#ba62dffd67ee256c8c086dfae69e016cd1f198b9" + integrity sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g== object-keys@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== -object.assign@^4.1.3, object.assign@^4.1.4: +object.assign@^4.1.4: version "4.1.4" resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.4.tgz#9673c7c7c351ab8c4d0b516f4343ebf4dfb7799f" integrity sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ== @@ -7819,49 +8429,60 @@ object.assign@^4.1.3, object.assign@^4.1.4: object-keys "^1.1.1" object.entries@^1.1.6: - version "1.1.6" - resolved "https://registry.yarnpkg.com/object.entries/-/object.entries-1.1.6.tgz#9737d0e5b8291edd340a3e3264bb8a3b00d5fa23" - integrity sha512-leTPzo4Zvg3pmbQ3rDK69Rl8GQvIqMWubrkxONG9/ojtFE2rD9fjMKfSI5BxW3osRH1m6VdzmqK8oAY9aT4x5w== + version "1.1.7" + resolved "https://registry.yarnpkg.com/object.entries/-/object.entries-1.1.7.tgz#2b47760e2a2e3a752f39dd874655c61a7f03c131" + integrity sha512-jCBs/0plmPsOnrKAfFQXRG2NFjlhZgjjcBLSmTnEhU8U6vVTsVe8ANeQJCHTl3gSsI4J+0emOoCgoKlmQPMgmA== dependencies: call-bind "^1.0.2" - define-properties "^1.1.4" - es-abstract "^1.20.4" + define-properties "^1.2.0" + es-abstract "^1.22.1" object.fromentries@^2.0.6: - version "2.0.6" - resolved "https://registry.yarnpkg.com/object.fromentries/-/object.fromentries-2.0.6.tgz#cdb04da08c539cffa912dcd368b886e0904bfa73" - integrity sha512-VciD13dswC4j1Xt5394WR4MzmAQmlgN72phd/riNp9vtD7tp4QQWJ0R4wvclXcafgcYK8veHRed2W6XeGBvcfg== + version "2.0.7" + resolved "https://registry.yarnpkg.com/object.fromentries/-/object.fromentries-2.0.7.tgz#71e95f441e9a0ea6baf682ecaaf37fa2a8d7e616" + integrity sha512-UPbPHML6sL8PI/mOqPwsH4G6iyXcCGzLin8KvEPenOZN5lpCNBZZQ+V62vdjB1mQHrmqGQt5/OJzemUA+KJmEA== dependencies: call-bind "^1.0.2" - define-properties "^1.1.4" - es-abstract "^1.20.4" + define-properties "^1.2.0" + es-abstract "^1.22.1" object.getownpropertydescriptors@^2.1.0: - version "2.1.5" - resolved "https://registry.yarnpkg.com/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.5.tgz#db5a9002489b64eef903df81d6623c07e5b4b4d3" - integrity sha512-yDNzckpM6ntyQiGTik1fKV1DcVDRS+w8bvpWNCBanvH5LfRX9O8WTHqQzG4RZwRAM4I0oU7TV11Lj5v0g20ibw== + version "2.1.6" + resolved "https://registry.yarnpkg.com/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.6.tgz#5e5c384dd209fa4efffead39e3a0512770ccc312" + integrity sha512-lq+61g26E/BgHv0ZTFgRvi7NMEPuAxLkFU7rukXjc/AlwH4Am5xXVnIXy3un1bg/JPbXHrixRkK1itUzzPiIjQ== dependencies: array.prototype.reduce "^1.0.5" call-bind "^1.0.2" - define-properties "^1.1.4" - es-abstract "^1.20.4" + define-properties "^1.2.0" + es-abstract "^1.21.2" + safe-array-concat "^1.0.0" + +object.groupby@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/object.groupby/-/object.groupby-1.0.1.tgz#d41d9f3c8d6c778d9cbac86b4ee9f5af103152ee" + integrity sha512-HqaQtqLnp/8Bn4GL16cj+CUYbnpe1bh0TtEaWvybszDG4tgxCJuRpV8VGuvNaI1fAnI4lUJzDG55MXcOH4JZcQ== + dependencies: + call-bind "^1.0.2" + define-properties "^1.2.0" + es-abstract "^1.22.1" + get-intrinsic "^1.2.1" object.hasown@^1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/object.hasown/-/object.hasown-1.1.2.tgz#f919e21fad4eb38a57bc6345b3afd496515c3f92" - integrity sha512-B5UIT3J1W+WuWIU55h0mjlwaqxiE5vYENJXIXZ4VFe05pNYrkKuK0U/6aFcb0pKywYJh7IhfoqUfKVmrJJHZHw== + version "1.1.3" + resolved "https://registry.yarnpkg.com/object.hasown/-/object.hasown-1.1.3.tgz#6a5f2897bb4d3668b8e79364f98ccf971bda55ae" + integrity sha512-fFI4VcYpRHvSLXxP7yiZOMAd331cPfd2p7PFDVbgUsYOfCT3tICVqXWngbjr4m49OvsBwUBQ6O2uQoJvy3RexA== dependencies: - define-properties "^1.1.4" - es-abstract "^1.20.4" + define-properties "^1.2.0" + es-abstract "^1.22.1" -object.values@^1.1.0, object.values@^1.1.5, object.values@^1.1.6: - version "1.1.6" - resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.1.6.tgz#4abbaa71eba47d63589d402856f908243eea9b1d" - integrity sha512-FVVTkD1vENCsAcwNs9k6jea2uHC/X0+JcjG8YA60FN5CMaJmG95wT9jek/xX9nornqGRrBkKtzuAu2wuHpKqvw== +object.values@^1.1.0, object.values@^1.1.6: + version "1.1.7" + resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.1.7.tgz#617ed13272e7e1071b43973aa1655d9291b8442a" + integrity sha512-aU6xnDFYT3x17e/f0IiiwlGPTy2jzMySGfUB4fq6z7CV8l85CWHDk5ErhyhpfDHhrOMwGFhSQkhMGHaIotA6Ng== dependencies: call-bind "^1.0.2" - define-properties "^1.1.4" - es-abstract "^1.20.4" + define-properties "^1.2.0" + es-abstract "^1.22.1" obuf@^1.0.0, obuf@^1.1.2: version "1.1.2" @@ -7894,38 +8515,43 @@ onetime@^5.1.2: dependencies: mimic-fn "^2.1.0" +onetime@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/onetime/-/onetime-6.0.0.tgz#7c24c18ed1fd2e9bca4bd26806a33613c77d34b4" + integrity sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ== + dependencies: + mimic-fn "^4.0.0" + open@^8.0.9, open@^8.4.0: - version "8.4.0" - resolved "https://registry.yarnpkg.com/open/-/open-8.4.0.tgz#345321ae18f8138f82565a910fdc6b39e8c244f8" - integrity sha512-XgFPPM+B28FtCCgSb9I+s9szOC1vZRSwgWsRUA5ylIxRTgKozqjOCrVOqGsYABPYK5qnfqClxZTFBa8PKt2v6Q== + version "8.4.2" + resolved "https://registry.yarnpkg.com/open/-/open-8.4.2.tgz#5b5ffe2a8f793dcd2aad73e550cb87b59cb084f9" + integrity sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ== dependencies: define-lazy-prop "^2.0.0" is-docker "^2.1.1" is-wsl "^2.2.0" -optionator@^0.8.1: - version "0.8.3" - resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.3.tgz#84fa1d036fe9d3c7e21d99884b601167ec8fb495" - integrity sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA== +open@^9.1.0: + version "9.1.0" + resolved "https://registry.yarnpkg.com/open/-/open-9.1.0.tgz#684934359c90ad25742f5a26151970ff8c6c80b6" + integrity sha512-OS+QTnw1/4vrf+9hh1jc1jnYjzSG4ttTBB8UxOwAnInG3Uo4ssetzC1ihqaIHjLJnA5GGlRl6QlZXOTQhRBUvg== dependencies: - deep-is "~0.1.3" - fast-levenshtein "~2.0.6" - levn "~0.3.0" - prelude-ls "~1.1.2" - type-check "~0.3.2" - word-wrap "~1.2.3" + default-browser "^4.0.0" + define-lazy-prop "^3.0.0" + is-inside-container "^1.0.0" + is-wsl "^2.2.0" -optionator@^0.9.1: - version "0.9.1" - resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.1.tgz#4f236a6373dae0566a6d43e1326674f50c291499" - integrity sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw== +optionator@^0.9.3: + version "0.9.3" + resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.3.tgz#007397d44ed1872fdc6ed31360190f81814e2c64" + integrity sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg== dependencies: + "@aashutoshrathi/word-wrap" "^1.2.3" deep-is "^0.1.3" fast-levenshtein "^2.0.6" levn "^0.4.1" prelude-ls "^1.2.1" type-check "^0.4.0" - word-wrap "^1.2.3" p-limit@^2.0.0, p-limit@^2.2.0: version "2.3.0" @@ -8072,6 +8698,11 @@ path-key@^3.0.0, path-key@^3.1.0: resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== +path-key@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-4.0.0.tgz#295588dc3aee64154f877adb9d780b81c554bf18" + integrity sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ== + path-parse@^1.0.7: version "1.0.7" resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" @@ -8112,10 +8743,10 @@ pify@^2.3.0: resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" integrity sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog== -pirates@^4.0.4: - version "4.0.5" - resolved "https://registry.yarnpkg.com/pirates/-/pirates-4.0.5.tgz#feec352ea5c3268fb23a37c702ab1699f35a5f3b" - integrity sha512-8V9+HQPupnaXMA23c5hvl69zXvTwTzyAYasnkb0Tts4XvO4CliqONMOnvlq26rkhLC3nWDFBJf73LU1e1VZLaQ== +pirates@^4.0.1, pirates@^4.0.4: + version "4.0.6" + resolved "https://registry.yarnpkg.com/pirates/-/pirates-4.0.6.tgz#3018ae32ecfcff6c29ba2267cbf21166ac1f36b9" + integrity sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg== pkg-dir@^4.1.0, pkg-dir@^4.2.0: version "4.2.0" @@ -8184,12 +8815,12 @@ postcss-color-rebeccapurple@^7.1.1: dependencies: postcss-value-parser "^4.2.0" -postcss-colormin@^5.3.0: - version "5.3.0" - resolved "https://registry.yarnpkg.com/postcss-colormin/-/postcss-colormin-5.3.0.tgz#3cee9e5ca62b2c27e84fce63affc0cfb5901956a" - integrity sha512-WdDO4gOFG2Z8n4P8TWBpshnL3JpmNmJwdnfP2gbk2qBA8PWwOYcmjmI/t3CmMeL72a7Hkd+x/Mg9O2/0rD54Pg== +postcss-colormin@^5.3.1: + version "5.3.1" + resolved "https://registry.yarnpkg.com/postcss-colormin/-/postcss-colormin-5.3.1.tgz#86c27c26ed6ba00d96c79e08f3ffb418d1d1988f" + integrity sha512-UsWQG0AqTFQmpBegeLLc1+c3jIqBNB0zlDGRWR+dQ3pRKJL1oeMzyqmH3o2PIfn9MBdNrVPWhDbT769LxCTLJQ== dependencies: - browserslist "^4.16.6" + browserslist "^4.21.4" caniuse-api "^3.0.0" colord "^2.9.1" postcss-value-parser "^4.2.0" @@ -8301,10 +8932,10 @@ postcss-image-set-function@^4.0.7: dependencies: postcss-value-parser "^4.2.0" -postcss-import@^14.1.0: - version "14.1.0" - resolved "https://registry.yarnpkg.com/postcss-import/-/postcss-import-14.1.0.tgz#a7333ffe32f0b8795303ee9e40215dac922781f0" - integrity sha512-flwI+Vgm4SElObFVPpTIT7SU7R3qk2L7PyduMcokiaVKuWv9d/U+Gm/QAd8NDLuykTWTkcrjOeD2Pp1rMeBTGw== +postcss-import@^15.1.0: + version "15.1.0" + resolved "https://registry.yarnpkg.com/postcss-import/-/postcss-import-15.1.0.tgz#41c64ed8cc0e23735a9698b3249ffdbf704adc70" + integrity sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew== dependencies: postcss-value-parser "^4.0.0" read-cache "^1.0.0" @@ -8315,10 +8946,10 @@ postcss-initial@^4.0.1: resolved "https://registry.yarnpkg.com/postcss-initial/-/postcss-initial-4.0.1.tgz#529f735f72c5724a0fb30527df6fb7ac54d7de42" integrity sha512-0ueD7rPqX8Pn1xJIjay0AZeIuDoF+V+VvMt/uOnn+4ezUKhZM/NokDeP6DwMNyIoYByuN/94IQnt5FEkaN59xQ== -postcss-js@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/postcss-js/-/postcss-js-4.0.0.tgz#31db79889531b80dc7bc9b0ad283e418dce0ac00" - integrity sha512-77QESFBwgX4irogGVPgQ5s07vLvFqWr228qZY+w6lW599cRlK/HmnlivnnVUxkjHnCu4J16PDMHcH+e+2HbvTQ== +postcss-js@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/postcss-js/-/postcss-js-4.0.1.tgz#61598186f3703bab052f1c4f7d805f3991bee9d2" + integrity sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw== dependencies: camelcase-css "^2.0.1" @@ -8330,13 +8961,13 @@ postcss-lab-function@^4.2.1: "@csstools/postcss-progressive-custom-properties" "^1.1.0" postcss-value-parser "^4.2.0" -postcss-load-config@^3.1.4: - version "3.1.4" - resolved "https://registry.yarnpkg.com/postcss-load-config/-/postcss-load-config-3.1.4.tgz#1ab2571faf84bb078877e1d07905eabe9ebda855" - integrity sha512-6DiM4E7v4coTE4uzA8U//WhtPwyhiim3eyjEMFCnUpzbrkK9wJHgKDT2mR+HbtSrd/NubVaYTOpSpjUl8NQeRg== +postcss-load-config@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/postcss-load-config/-/postcss-load-config-4.0.1.tgz#152383f481c2758274404e4962743191d73875bd" + integrity sha512-vEJIc8RdiBRu3oRAI0ymerOn+7rPuMvRXslTvZUKZonDHFIczxztIyJ1urxM1x9JXEikvpWWTUUqal5j/8QgvA== dependencies: lilconfig "^2.0.5" - yaml "^1.10.2" + yaml "^2.1.1" postcss-loader@^6.2.1: version "6.2.1" @@ -8365,10 +8996,10 @@ postcss-merge-longhand@^5.1.7: postcss-value-parser "^4.2.0" stylehacks "^5.1.1" -postcss-merge-rules@^5.1.3: - version "5.1.3" - resolved "https://registry.yarnpkg.com/postcss-merge-rules/-/postcss-merge-rules-5.1.3.tgz#8f97679e67cc8d08677a6519afca41edf2220894" - integrity sha512-LbLd7uFC00vpOuMvyZop8+vvhnfRGpp2S+IMQKeuOZZapPRY4SMq5ErjQeHbHsjCUgJkRNrlU+LmxsKIqPKQlA== +postcss-merge-rules@^5.1.4: + version "5.1.4" + resolved "https://registry.yarnpkg.com/postcss-merge-rules/-/postcss-merge-rules-5.1.4.tgz#2f26fa5cacb75b1402e213789f6766ae5e40313c" + integrity sha512-0R2IuYpgU93y9lhVbO/OylTtKMVcHb67zjWIfCiKR9rWL3GUk1677LAqD/BcHizukdZEjT8Ru3oHRoAYoJy44g== dependencies: browserslist "^4.21.4" caniuse-api "^3.0.0" @@ -8412,10 +9043,10 @@ postcss-modules-extract-imports@^3.0.0: resolved "https://registry.yarnpkg.com/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.0.0.tgz#cda1f047c0ae80c97dbe28c3e76a43b88025741d" integrity sha512-bdHleFnP3kZ4NYDhuGlVK+CMrQ/pqUm8bx/oGL93K6gVwiclvX5x0n76fYMKuIGKzlABOy13zsvqjb0f92TEXw== -postcss-modules-local-by-default@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.0.tgz#ebbb54fae1598eecfdf691a02b3ff3b390a5a51c" - integrity sha512-sT7ihtmGSF9yhm6ggikHdV0hlziDTX7oFoXtuVWeDd3hHObNkcHRo9V3yg7vCAY7cONyxJC/XXCmmiHHcvX7bQ== +postcss-modules-local-by-default@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.3.tgz#b08eb4f083050708998ba2c6061b50c2870ca524" + integrity sha512-2/u2zraspoACtrbFRnTijMiQtb4GW4BvatjaG/bCjYQo8kLTdevCUlwuBHx2sCnSyrI3x3qj4ZK1j5LQBgzmwA== dependencies: icss-utils "^5.0.0" postcss-selector-parser "^6.0.2" @@ -8435,12 +9066,12 @@ postcss-modules-values@^4.0.0: dependencies: icss-utils "^5.0.0" -postcss-nested@6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/postcss-nested/-/postcss-nested-6.0.0.tgz#1572f1984736578f360cffc7eb7dca69e30d1735" - integrity sha512-0DkamqrPcmkBDsLn+vQDIrtkSbNkv5AD/M322ySo9kqFkCIYklym2xEmWkwo+Y3/qZo34tzEPNUw4y7yMCdv5w== +postcss-nested@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/postcss-nested/-/postcss-nested-6.0.1.tgz#f83dc9846ca16d2f4fa864f16e9d9f7d0961662c" + integrity sha512-mEp4xPMi5bSWiMbsgoPfcP74lsWLHkQbZc3sY+jWYd65CUwXrUaTp0fmNpa01ZcETKlIgUdFN/MpS2xZtqL9dQ== dependencies: - postcss-selector-parser "^6.0.10" + postcss-selector-parser "^6.0.11" postcss-nesting@^10.2.0: version "10.2.0" @@ -8616,10 +9247,10 @@ postcss-pseudo-class-any-link@^7.1.6: dependencies: postcss-selector-parser "^6.0.10" -postcss-reduce-initial@^5.1.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/postcss-reduce-initial/-/postcss-reduce-initial-5.1.1.tgz#c18b7dfb88aee24b1f8e4936541c29adbd35224e" - integrity sha512-//jeDqWcHPuXGZLoolFrUXBDyuEGbr9S2rMo19bkTIjBQ4PqkaO+oI8wua5BOUxpfi97i3PCoInsiFIEBfkm9w== +postcss-reduce-initial@^5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/postcss-reduce-initial/-/postcss-reduce-initial-5.1.2.tgz#798cd77b3e033eae7105c18c9d371d989e1382d6" + integrity sha512-dE/y2XRaqAi6OvjzD22pjTUQ8eOfc6m/natGHgKFBK9DxFmIm69YmaRVQrGgFlEfc1HePIurY0TmDeROK05rIg== dependencies: browserslist "^4.21.4" caniuse-api "^3.0.0" @@ -8643,10 +9274,10 @@ postcss-selector-not@^6.0.1: dependencies: postcss-selector-parser "^6.0.10" -postcss-selector-parser@^6.0.10, postcss-selector-parser@^6.0.2, postcss-selector-parser@^6.0.4, postcss-selector-parser@^6.0.5, postcss-selector-parser@^6.0.9: - version "6.0.11" - resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.0.11.tgz#2e41dc39b7ad74046e1615185185cd0b17d0c8dc" - integrity sha512-zbARubNdogI9j7WY4nQJBiNqQf3sLS3wCP4WfOidu+p28LofJqDH1tcXypGrcmMHhDk2t9wGhCsYe/+szLTy1g== +postcss-selector-parser@^6.0.10, postcss-selector-parser@^6.0.11, postcss-selector-parser@^6.0.2, postcss-selector-parser@^6.0.4, postcss-selector-parser@^6.0.5, postcss-selector-parser@^6.0.9: + version "6.0.13" + resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.0.13.tgz#d05d8d76b1e8e173257ef9d60b706a8e5e99bf1b" + integrity sha512-EaV1Gl4mUEV4ddhDnv/xtj7sxwrwxdetHdWUGnT4VJQf+4d05v6lHYZr8N573k5Z0BViss7BDhfWtKS3+sfAqQ== dependencies: cssesc "^3.0.0" util-deprecate "^1.0.2" @@ -8679,12 +9310,12 @@ postcss@^7.0.35: picocolors "^0.2.1" source-map "^0.6.1" -postcss@^8.3.5, postcss@^8.4.18, postcss@^8.4.19, postcss@^8.4.4: - version "8.4.20" - resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.20.tgz#64c52f509644cecad8567e949f4081d98349dc56" - integrity sha512-6Q04AXR1212bXr5fh03u8aAwbLxAQNGQ/Q1LNa0VfOI06ZAlhPHtQvE4OIdpj4kLThXilalPnmDSOD65DcHt+g== +postcss@^8.3.5, postcss@^8.4.21, postcss@^8.4.23, postcss@^8.4.4: + version "8.4.29" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.29.tgz#33bc121cf3b3688d4ddef50be869b2a54185a1dd" + integrity sha512-cbI+jaqIeu/VGqXEarWkRCCffhjgXc0qjBtXpqJhTBohMUjUQnbBr0xqX3vEKudc4iviTewcJo5ajcec5+wdJw== dependencies: - nanoid "^3.3.4" + nanoid "^3.3.6" picocolors "^1.0.0" source-map-js "^1.0.2" @@ -8693,10 +9324,17 @@ prelude-ls@^1.2.1: resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396" integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g== -prelude-ls@~1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" - integrity sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w== +prettier-linter-helpers@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz#d23d41fe1375646de2d0104d3454a3008802cf7b" + integrity sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w== + dependencies: + fast-diff "^1.1.2" + +prettier@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-3.0.3.tgz#432a51f7ba422d1469096c0fdc28e235db8f9643" + integrity sha512-L/4pUDMxcNa8R/EthV08Zt42WBO4h1rarVtK0K+QJG0X187OLo7l699jWw0GKuwzkPQ//jMFA/8Xm6Fh3J/DAg== pretty-bytes@^5.3.0, pretty-bytes@^5.4.1: version "5.6.0" @@ -8788,9 +9426,9 @@ psl@^1.1.33: integrity sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag== punycode@^2.1.0, punycode@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" - integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== + version "2.3.0" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.0.tgz#f67fa67c94da8f4d0cfff981aee4118064199b8f" + integrity sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA== q@^1.1.2: version "1.5.1" @@ -8821,11 +9459,6 @@ queue@^6.0.1: dependencies: inherits "~2.0.3" -quick-lru@^5.1.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/quick-lru/-/quick-lru-5.1.1.tgz#366493e6b3e42a3a6885e2e99d18f80fb7a8c932" - integrity sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA== - raf@^3.4.1: version "3.4.1" resolved "https://registry.yarnpkg.com/raf/-/raf-3.4.1.tgz#0742e99a4a6552f445d73e3ee0328af0ff1ede39" @@ -8868,16 +9501,16 @@ react-app-polyfill@^3.0.0: whatwg-fetch "^3.6.2" react-datepicker@^4.8.0: - version "4.8.0" - resolved "https://registry.yarnpkg.com/react-datepicker/-/react-datepicker-4.8.0.tgz#11b8918d085a1ce4781eee4c8e4641b3cd592010" - integrity sha512-u69zXGHMpxAa4LeYR83vucQoUCJQ6m/WBsSxmUMu/M8ahTSVMMyiyQzauHgZA2NUr9y0FUgOAix71hGYUb6tvg== + version "4.16.0" + resolved "https://registry.yarnpkg.com/react-datepicker/-/react-datepicker-4.16.0.tgz#b9dd389bb5611a1acc514bba1dd944be21dd877f" + integrity sha512-hNQ0PAg/LQoVbDUO/RWAdm/RYmPhN3cz7LuQ3hqbs24OSp69QCiKOJRrQ4jk1gv1jNR5oYu8SjjgfDh8q6Q1yw== dependencies: - "@popperjs/core" "^2.9.2" + "@popperjs/core" "^2.11.8" classnames "^2.2.6" - date-fns "^2.24.0" + date-fns "^2.30.0" prop-types "^15.7.2" - react-onclickoutside "^6.12.0" - react-popper "^2.2.5" + react-onclickoutside "^6.12.2" + react-popper "^2.3.0" react-dev-utils@^12.0.1: version "12.0.1" @@ -8940,14 +9573,14 @@ react-error-overlay@^6.0.11: integrity sha512-/6UZ2qgEyH2aqzYZgQPxEnz33NJ2gNsnHA2o5+o4wW9bLM/JYQitNP9xPhsXwC08hMMovfGe/8retsdDsczPRg== react-fast-compare@^3.0.1: - version "3.2.0" - resolved "https://registry.yarnpkg.com/react-fast-compare/-/react-fast-compare-3.2.0.tgz#641a9da81b6a6320f270e89724fb45a0b39e43bb" - integrity sha512-rtGImPZ0YyLrscKI9xTpV8psd6I8VAtjKCzQDlzyDvqJA8XOW78TXYQwNRNd8g8JZnDu8q9Fu/1v4HPAVwVdHA== + version "3.2.2" + resolved "https://registry.yarnpkg.com/react-fast-compare/-/react-fast-compare-3.2.2.tgz#929a97a532304ce9fee4bcae44234f1ce2c21d49" + integrity sha512-nsO+KSNgo1SbJqJEYRE9ERzo7YtYbou/OqjSQKxV7jcKox7+usiUVZOAC+XnDOABXggQTno0Y1CpVnuWEc1boQ== react-hook-form@^7.45.1: - version "7.45.1" - resolved "https://registry.yarnpkg.com/react-hook-form/-/react-hook-form-7.45.1.tgz#e352c7f4dbc7540f0756abbb4dcfd1122fecc9bb" - integrity sha512-6dWoFJwycbuFfw/iKMcl+RdAOAOHDiF11KWYhNDRN/OkUt+Di5qsZHwA0OwsVnu9y135gkHpTw9DJA+WzCeR9w== + version "7.45.4" + resolved "https://registry.yarnpkg.com/react-hook-form/-/react-hook-form-7.45.4.tgz#73d228b704026ae95d7e5f7b207a681b173ec62a" + integrity sha512-HGDV1JOOBPZj10LB3+OZgfDBTn+IeEsNOKiq/cxbQAIbKaiJUe/KV8DBUzsx0Gx/7IG/orWqRRm736JwOfUSWQ== react-is@^16.13.1, react-is@^16.7.0: version "16.13.1" @@ -8985,12 +9618,12 @@ react-markdown@^8.0.7: unist-util-visit "^4.0.0" vfile "^5.0.0" -react-onclickoutside@^6.12.0: - version "6.12.2" - resolved "https://registry.yarnpkg.com/react-onclickoutside/-/react-onclickoutside-6.12.2.tgz#8e6cf80c7d17a79f2c908399918158a7b02dda01" - integrity sha512-NMXGa223OnsrGVp5dJHkuKxQ4czdLmXSp5jSV9OqiCky9LOpPATn3vLldc+q5fK3gKbEHvr7J1u0yhBh/xYkpA== +react-onclickoutside@^6.12.2: + version "6.13.0" + resolved "https://registry.yarnpkg.com/react-onclickoutside/-/react-onclickoutside-6.13.0.tgz#e165ea4e5157f3da94f4376a3ab3e22a565f4ffc" + integrity sha512-ty8So6tcUpIb+ZE+1HAhbLROvAIJYyJe/1vRrrcmW+jLsaM+/powDRqxzo6hSh9CuRZGSL1Q8mvcF5WRD93a0A== -react-popper@^2.2.5: +react-popper@^2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/react-popper/-/react-popper-2.3.0.tgz#17891c620e1320dce318bad9fede46a5f71c70ba" integrity sha512-e1hj8lL3uM+sgSR4Lxzn5h1GxBlpa4CQz0XLF8kx4MDrDRWY0Ena4c97PUeSX9i5W3UAfDP0z0FXCTQkoXUl3Q== @@ -9004,19 +9637,19 @@ react-refresh@^0.11.0: integrity sha512-F27qZr8uUqwhWZboondsPx8tnC3Ct3SxZA3V5WyEvujRyyNv0VYPhoBg1gZ8/MV5tubQp76Trw8lTv9hzRBa+A== react-router-dom@^6.6.0: - version "6.6.0" - resolved "https://registry.yarnpkg.com/react-router-dom/-/react-router-dom-6.6.0.tgz#ad20b37b69e9fe7c6389663a0767ba40a19f71fe" - integrity sha512-qC4jnvpfCPKVle1mKLD75IvZLcbVJyFMlSn16WY9ZiOed3dgSmqhslCf/u3tmSccWOujkdsT/OwGq12bELmvjg== + version "6.15.0" + resolved "https://registry.yarnpkg.com/react-router-dom/-/react-router-dom-6.15.0.tgz#6da7db61e56797266fbbef0d5e324d6ac443ee40" + integrity sha512-aR42t0fs7brintwBGAv2+mGlCtgtFQeOzK0BM1/OiqEzRejOZtpMZepvgkscpMUnKb8YO84G7s3LsHnnDNonbQ== dependencies: - "@remix-run/router" "1.2.0" - react-router "6.6.0" + "@remix-run/router" "1.8.0" + react-router "6.15.0" -react-router@6.6.0: - version "6.6.0" - resolved "https://registry.yarnpkg.com/react-router/-/react-router-6.6.0.tgz#9ae27cfc6bf7f2b28e1f028fe01fdbec96a3a41d" - integrity sha512-+VPfCIaFbkW7BAiB/2oeprxKAt1KLbl+zXZ10CXOYezKWgBmTKyh8XjI53eLqY5kd7uY+V4rh3UW44FclwUU+Q== +react-router@6.15.0: + version "6.15.0" + resolved "https://registry.yarnpkg.com/react-router/-/react-router-6.15.0.tgz#bf2cb5a4a7ed57f074d4ea88db0d95033f39cac8" + integrity sha512-NIytlzvzLwJkCQj2HLefmeakxxWHWAP+02EGqWEZy+DgfHHKQMUoBBjUQLOtFInBMhWtb3hiUy6MfFgwLjXhqg== dependencies: - "@remix-run/router" "1.2.0" + "@remix-run/router" "1.8.0" react-scripts@^5.0.1: version "5.0.1" @@ -9074,9 +9707,9 @@ react-scripts@^5.0.1: fsevents "^2.3.2" react-toastify@^9.1.1: - version "9.1.1" - resolved "https://registry.yarnpkg.com/react-toastify/-/react-toastify-9.1.1.tgz#9280caea4a13dc1739c350d90660a630807bf10b" - integrity sha512-pkFCla1z3ve045qvjEmn2xOJOy4ZciwRXm1oMPULVkELi5aJdHCN/FHnuqXq8IwGDLB7PPk2/J6uP9D8ejuiRw== + version "9.1.3" + resolved "https://registry.yarnpkg.com/react-toastify/-/react-toastify-9.1.3.tgz#1e798d260d606f50e0fab5ee31daaae1d628c5ff" + integrity sha512-fPfb8ghtn/XMxw3LkxQBk3IyagNpF/LIKjOBflbexr2AWxAH1MJgvnESwEwBn9liLFXgTKWgBSdZpw9m4OTHTg== dependencies: clsx "^1.1.1" @@ -9098,15 +9731,16 @@ react@^18.2.0: loose-envify "^1.1.0" reactflow@^11.4.0: - version "11.4.0" - resolved "https://registry.yarnpkg.com/reactflow/-/reactflow-11.4.0.tgz#aeb4b030ba93e8e656094f59226e55ec538f55b4" - integrity sha512-Y+LZ3XZX7UejW4vukeyLwDDfqNT0RxyNNSHD1FJOIu2IvyVMkj+wKTcbp3ehm7brBkMOOaPyugcEWlLwFXcrjg== + version "11.8.3" + resolved "https://registry.yarnpkg.com/reactflow/-/reactflow-11.8.3.tgz#ad5cdf22408298956c92ab652929ff92206af9dc" + integrity sha512-wuVxJOFqi1vhA4WAEJLK0JWx2TsTiWpxTXTRp/wvpqKInQgQcB49I2QNyNYsKJCQ6jjXektS7H+LXoaVK/pG4A== dependencies: - "@reactflow/background" "11.1.0" - "@reactflow/controls" "11.1.0" - "@reactflow/core" "11.4.0" - "@reactflow/minimap" "11.3.0" - "@reactflow/node-toolbar" "1.1.0" + "@reactflow/background" "11.2.8" + "@reactflow/controls" "11.1.19" + "@reactflow/core" "11.8.3" + "@reactflow/minimap" "11.6.3" + "@reactflow/node-resizer" "2.1.5" + "@reactflow/node-toolbar" "1.2.7" read-cache@^1.0.0: version "1.0.0" @@ -9116,9 +9750,9 @@ read-cache@^1.0.0: pify "^2.3.0" readable-stream@^2.0.1: - version "2.3.7" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57" - integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw== + version "2.3.8" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.8.tgz#91125e8042bba1b9887f49345f6277027ce8be9b" + integrity sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA== dependencies: core-util-is "~1.0.0" inherits "~2.0.3" @@ -9129,9 +9763,9 @@ readable-stream@^2.0.1: util-deprecate "~1.0.1" readable-stream@^3.0.6: - version "3.6.0" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198" - integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA== + version "3.6.2" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.2.tgz#56a9b36ea965c00c5a93ef31eb111a0f11056967" + integrity sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA== dependencies: inherits "^2.0.3" string_decoder "^1.1.1" @@ -9151,6 +9785,18 @@ recursive-readdir@^2.2.2: dependencies: minimatch "^3.0.5" +reflect.getprototypeof@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/reflect.getprototypeof/-/reflect.getprototypeof-1.0.4.tgz#aaccbf41aca3821b87bb71d9dcbc7ad0ba50a3f3" + integrity sha512-ECkTw8TmJwW60lOTR+ZkODISW6RQ8+2CL3COqtiJKLd6MmB45hN51HprHFziKLGkAuTGQhBb91V8cy+KHlaCjw== + dependencies: + call-bind "^1.0.2" + define-properties "^1.2.0" + es-abstract "^1.22.1" + get-intrinsic "^1.2.1" + globalthis "^1.0.3" + which-builtin-type "^1.1.3" + refractor@^4.7.0: version "4.8.1" resolved "https://registry.yarnpkg.com/refractor/-/refractor-4.8.1.tgz#fbdd889333a3d86c9c864479622855c9b38e9d42" @@ -9173,15 +9819,20 @@ regenerate@^1.4.2: resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.4.2.tgz#b9346d8827e8f5a32f7ba29637d398b69014848a" integrity sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A== -regenerator-runtime@^0.13.11, regenerator-runtime@^0.13.9: +regenerator-runtime@^0.13.9: version "0.13.11" resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz#f6dca3e7ceec20590d07ada785636a90cdca17f9" integrity sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg== -regenerator-transform@^0.15.1: - version "0.15.1" - resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.15.1.tgz#f6c4e99fc1b4591f780db2586328e4d9a9d8dc56" - integrity sha512-knzmNAcuyxV+gQCufkYcvOqX/qIIfHLv0u5x79kRxuGojfYVky1f15TzZEu2Avte8QGepvUNTnLskf8E6X6Vyg== +regenerator-runtime@^0.14.0: + version "0.14.0" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.14.0.tgz#5e19d68eb12d486f797e15a3c6a918f7cec5eb45" + integrity sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA== + +regenerator-transform@^0.15.2: + version "0.15.2" + resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.15.2.tgz#5bbae58b522098ebdf09bca2f83838929001c7a4" + integrity sha512-hfMp2BoF0qOk3uc5V20ALGDS2ddjQaLrdl7xrGXvAIow7qeWRM2VA2HuCHkUKk9slq3VwEwLNK3DFBqDfPGYtg== dependencies: "@babel/runtime" "^7.8.4" @@ -9190,37 +9841,27 @@ regex-parser@^2.2.11: resolved "https://registry.yarnpkg.com/regex-parser/-/regex-parser-2.2.11.tgz#3b37ec9049e19479806e878cabe7c1ca83ccfe58" integrity sha512-jbD/FT0+9MBU2XAZluI7w2OBs1RBi6p9M83nkoZayQXXU9e8Robt69FcZc7wU4eJD/YFTjn1JdCk3rbMJajz8Q== -regexp.prototype.flags@^1.4.3: - version "1.4.3" - resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz#87cab30f80f66660181a3bb7bf5981a872b367ac" - integrity sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA== +regexp.prototype.flags@^1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.5.0.tgz#fe7ce25e7e4cca8db37b6634c8a2c7009199b9cb" + integrity sha512-0SutC3pNudRKgquxGoRGIz946MZVHqbNfPjBdxeOhBrdgDKlRoXmYLQN9xRbrR09ZXWeGAdPuif7egofn6v5LA== dependencies: call-bind "^1.0.2" - define-properties "^1.1.3" - functions-have-names "^1.2.2" - -regexpp@^3.2.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-3.2.0.tgz#0425a2768d8f23bad70ca4b90461fa2f1213e1b2" - integrity sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg== + define-properties "^1.2.0" + functions-have-names "^1.2.3" -regexpu-core@^5.2.1: - version "5.2.2" - resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-5.2.2.tgz#3e4e5d12103b64748711c3aad69934d7718e75fc" - integrity sha512-T0+1Zp2wjF/juXMrMxHxidqGYn8U4R+zleSJhX9tQ1PUsS8a9UtYfbsF9LdiVgNX3kiX8RNaKM42nfSgvFJjmw== +regexpu-core@^5.3.1: + version "5.3.2" + resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-5.3.2.tgz#11a2b06884f3527aec3e93dbbf4a3b958a95546b" + integrity sha512-RAM5FlZz+Lhmo7db9L298p2vHP5ZywrVXmVXpmAD9GuL5MPH6t9ROw1iA/wfHkQ76Qe7AaPF0nGuim96/IrQMQ== dependencies: + "@babel/regjsgen" "^0.8.0" regenerate "^1.4.2" regenerate-unicode-properties "^10.1.0" - regjsgen "^0.7.1" regjsparser "^0.9.1" unicode-match-property-ecmascript "^2.0.0" unicode-match-property-value-ecmascript "^2.1.0" -regjsgen@^0.7.1: - version "0.7.1" - resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.7.1.tgz#ee5ef30e18d3f09b7c369b76e7c2373ed25546f6" - integrity sha512-RAt+8H2ZEzHeYWxZ3H2z6tF18zyyOnlcdaafLrm21Bguj7uZy6ULibiAFdXEtKQY4Sy7wDTwDiOazasMLc4KPA== - regjsparser@^0.9.1: version "0.9.1" resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.9.1.tgz#272d05aa10c7c1f67095b1ff0addae8442fc5709" @@ -9229,9 +9870,9 @@ regjsparser@^0.9.1: jsesc "~0.5.0" rehype-parse@^8.0.0, rehype-parse@^8.0.2: - version "8.0.4" - resolved "https://registry.yarnpkg.com/rehype-parse/-/rehype-parse-8.0.4.tgz#3d17c9ff16ddfef6bbcc8e6a25a99467b482d688" - integrity sha512-MJJKONunHjoTh4kc3dsM1v3C9kGrrxvA3U8PxZlP2SjH8RNUSrb+lF7Y0KVaUDnGH2QZ5vAn7ulkiajM9ifuqg== + version "8.0.5" + resolved "https://registry.yarnpkg.com/rehype-parse/-/rehype-parse-8.0.5.tgz#ccffc21e08e288c7846614f8dc1dc23d603a4a80" + integrity sha512-Ds3RglaY/+clEX2U2mHflt7NlMA72KspZ0JLUJgBBLpRddBcEw3H8uYZQliQriku22NZpYMfjDdSgHcjxue24A== dependencies: "@types/hast" "^2.0.0" hast-util-from-parse5 "^7.0.0" @@ -9251,9 +9892,9 @@ rehype-prism-plus@1.5.0: unist-util-visit "^4.0.0" rehype-stringify@^9.0.0: - version "9.0.3" - resolved "https://registry.yarnpkg.com/rehype-stringify/-/rehype-stringify-9.0.3.tgz#70e3bd6d4d29e7acf36b802deed350305d2c3c17" - integrity sha512-kWiZ1bgyWlgOxpqD5HnxShKAdXtb2IUljn3hQAhySeak6IOQPPt6DeGnsIh4ixm7yKJWzm8TXFuC/lPfcWHJqw== + version "9.0.4" + resolved "https://registry.yarnpkg.com/rehype-stringify/-/rehype-stringify-9.0.4.tgz#31dbb9de6f5034c6964760a1b1083218059c4343" + integrity sha512-Uk5xu1YKdqobe5XpSskwPvo1XeHUUucWEQSl8hTrXt5selvca1e8K1EZ37E6YoZ4BT8BCqCdVfQW7OfHfthtVQ== dependencies: "@types/hast" "^2.0.0" hast-util-to-html "^8.0.0" @@ -9341,6 +9982,11 @@ resolve-from@^5.0.0: resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-5.0.0.tgz#c35225843df8f776df21c57557bc087e9dfdfc69" integrity sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw== +resolve-pkg-maps@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz#616b3dc2c57056b5588c31cdf4b3d64db133720f" + integrity sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw== + resolve-url-loader@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/resolve-url-loader/-/resolve-url-loader-4.0.0.tgz#d50d4ddc746bb10468443167acf800dcd6c3ad57" @@ -9353,20 +9999,20 @@ resolve-url-loader@^4.0.0: source-map "0.6.1" resolve.exports@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/resolve.exports/-/resolve.exports-1.1.0.tgz#5ce842b94b05146c0e03076985d1d0e7e48c90c9" - integrity sha512-J1l+Zxxp4XK3LUDZ9m60LRJF/mAe4z6a4xyabPHk7pvK5t35dACV32iIjJDFeWZFfZlO29w6SZ67knR0tHzJtQ== + version "1.1.1" + resolved "https://registry.yarnpkg.com/resolve.exports/-/resolve.exports-1.1.1.tgz#05cfd5b3edf641571fd46fa608b610dda9ead999" + integrity sha512-/NtpHNDN7jWhAaQ9BvBUYZ6YTXsRBgfqWFWP7BZBaoMJO/I3G5OFzvTuWNlZC3aPjins1F+TNrLKsGbH4rfsRQ== -resolve@^1.1.7, resolve@^1.14.2, resolve@^1.19.0, resolve@^1.20.0, resolve@^1.22.0, resolve@^1.22.1: - version "1.22.1" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.1.tgz#27cb2ebb53f91abb49470a928bba7558066ac177" - integrity sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw== +resolve@^1.1.7, resolve@^1.14.2, resolve@^1.19.0, resolve@^1.20.0, resolve@^1.22.2, resolve@^1.22.4: + version "1.22.4" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.4.tgz#1dc40df46554cdaf8948a486a10f6ba1e2026c34" + integrity sha512-PXNdCiPqDqeUou+w1C2eTQbNfxKSuMxqTCuvlmmMsk1NWHL5fRrhY6Pl0qEYYc6+QqGClco1Qj8XnjPego4wfg== dependencies: - is-core-module "^2.9.0" + is-core-module "^2.13.0" path-parse "^1.0.7" supports-preserve-symlinks-flag "^1.0.0" -resolve@^2.0.0-next.3: +resolve@^2.0.0-next.4: version "2.0.0-next.4" resolved "https://registry.yarnpkg.com/resolve/-/resolve-2.0.0-next.4.tgz#3d37a113d6429f496ec4752d2a2e58efb1fd4660" integrity sha512-iMDbmAWtfU+MHpxt/I5iWI7cY6YVEZUQ3MBgPQ++XD1PELuJHIl82xBmObyP2KyQmkNB2dsqF7seoQQiAn5yDQ== @@ -9414,6 +10060,13 @@ rollup@^2.43.1: optionalDependencies: fsevents "~2.3.2" +run-applescript@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/run-applescript/-/run-applescript-5.0.0.tgz#e11e1c932e055d5c6b40d98374e0268d9b11899c" + integrity sha512-XcT5rBksx1QdIhlFOCtgZkB99ZEouFZ1E2Kc2LHqNW13U3/74YGdkQRmThTwxy4QIyookibDKYZOPqX//6BlAg== + dependencies: + execa "^5.0.0" + run-parallel@^1.1.9: version "1.2.0" resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.2.0.tgz#66d1368da7bdf921eb9d95bd1a9229e7f21a43ee" @@ -9428,6 +10081,16 @@ sade@^1.7.3: dependencies: mri "^1.1.0" +safe-array-concat@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/safe-array-concat/-/safe-array-concat-1.0.0.tgz#2064223cba3c08d2ee05148eedbc563cd6d84060" + integrity sha512-9dVEFruWIsnie89yym+xWTAYASdpw3CJV7Li/6zBewGf9z2i1j31rP6jnY0pHEO4QZh6N0K11bFjWmdR8UGdPQ== + dependencies: + call-bind "^1.0.2" + get-intrinsic "^1.2.0" + has-symbols "^1.0.3" + isarray "^2.0.5" + safe-buffer@5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: version "5.1.2" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" @@ -9510,24 +10173,24 @@ schema-utils@^2.6.5: ajv "^6.12.4" ajv-keywords "^3.5.2" -schema-utils@^3.0.0, schema-utils@^3.1.0, schema-utils@^3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-3.1.1.tgz#bc74c4b6b6995c1d88f76a8b77bea7219e0c8281" - integrity sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw== +schema-utils@^3.0.0, schema-utils@^3.1.1, schema-utils@^3.2.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-3.3.0.tgz#f50a88877c3c01652a15b622ae9e9795df7a60fe" + integrity sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg== dependencies: "@types/json-schema" "^7.0.8" ajv "^6.12.5" ajv-keywords "^3.5.2" schema-utils@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-4.0.0.tgz#60331e9e3ae78ec5d16353c467c34b3a0a1d3df7" - integrity sha512-1edyXKgh6XnJsJSQ8mKWXnN/BVaIbFMLpouRUrXgVq7WYne5kw3MW7UPhO44uRXQSIpTSXoJbmrR2X0w9kUTyg== + version "4.2.0" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-4.2.0.tgz#70d7c93e153a273a805801882ebd3bff20d89c8b" + integrity sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw== dependencies: "@types/json-schema" "^7.0.9" - ajv "^8.8.0" + ajv "^8.9.0" ajv-formats "^2.1.1" - ajv-keywords "^5.0.0" + ajv-keywords "^5.1.0" select-hose@^2.0.0: version "2.0.0" @@ -9541,15 +10204,15 @@ selfsigned@^2.1.1: dependencies: node-forge "^1" -semver@^6.0.0, semver@^6.1.1, semver@^6.1.2, semver@^6.3.0: - version "6.3.0" - resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" - integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== +semver@^6.0.0, semver@^6.3.0, semver@^6.3.1: + version "6.3.1" + resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.1.tgz#556d2ef8689146e46dcea4bfdd095f3434dffcb4" + integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== -semver@^7.3.2, semver@^7.3.5, semver@^7.3.7, semver@^7.3.8: - version "7.3.8" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.8.tgz#07a78feafb3f7b32347d725e33de7e2a2df67798" - integrity sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A== +semver@^7.0.0, semver@^7.3.2, semver@^7.3.5, semver@^7.3.7, semver@^7.3.8, semver@^7.5.3, semver@^7.5.4: + version "7.5.4" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.4.tgz#483986ec4ed38e1c6c48c34894a9182dbff68a6e" + integrity sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA== dependencies: lru-cache "^6.0.0" @@ -9579,10 +10242,10 @@ serialize-javascript@^4.0.0: dependencies: randombytes "^2.1.0" -serialize-javascript@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-6.0.0.tgz#efae5d88f45d7924141da8b5c3a7a7e663fefeb8" - integrity sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag== +serialize-javascript@^6.0.0, serialize-javascript@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-6.0.1.tgz#b206efb27c3da0b0ab6b52f48d170b7996458e5c" + integrity sha512-owoXEFjWRllis8/M1Q+Cw5k8ZH40e3zhp/ovX+Xr/vi1qj6QesbyXXViFbpNvWvPNAD62SutwEXavefrLJWj7w== dependencies: randombytes "^2.1.0" @@ -9632,9 +10295,9 @@ shebang-regex@^3.0.0: integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== shell-quote@^1.7.3: - version "1.7.4" - resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.7.4.tgz#33fe15dee71ab2a81fcbd3a52106c5cfb9fb75d8" - integrity sha512-8o/QEhSSRb1a5i7TFR0iM4G16Z0vYB2OQVs4G3aAFXjn3T6yEx8AZxy1PgDF7I00LZHYA3WxaSYIf5e5sAX8Rw== + version "1.8.1" + resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.8.1.tgz#6dbf4db75515ad5bac63b4f1894c3a154c766680" + integrity sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA== side-channel@^1.0.4: version "1.0.4" @@ -9645,7 +10308,7 @@ side-channel@^1.0.4: get-intrinsic "^1.0.2" object-inspect "^1.9.0" -signal-exit@^3.0.2, signal-exit@^3.0.3: +signal-exit@^3.0.2, signal-exit@^3.0.3, signal-exit@^3.0.7: version "3.0.7" resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== @@ -9826,19 +10489,28 @@ string-width@^4.1.0, string-width@^4.2.0: strip-ansi "^6.0.1" string.prototype.matchall@^4.0.6, string.prototype.matchall@^4.0.8: - version "4.0.8" - resolved "https://registry.yarnpkg.com/string.prototype.matchall/-/string.prototype.matchall-4.0.8.tgz#3bf85722021816dcd1bf38bb714915887ca79fd3" - integrity sha512-6zOCOcJ+RJAQshcTvXPHoxoQGONa3e/Lqx90wUA+wEzX78sg5Bo+1tQo4N0pohS0erG9qtCqJDjNCQBjeWVxyg== + version "4.0.9" + resolved "https://registry.yarnpkg.com/string.prototype.matchall/-/string.prototype.matchall-4.0.9.tgz#148779de0f75d36b13b15885fec5cadde994520d" + integrity sha512-6i5hL3MqG/K2G43mWXWgP+qizFW/QH/7kCNN13JrJS5q48FN5IKksLDscexKP3dnmB6cdm9jlNgAsWNLpSykmA== dependencies: call-bind "^1.0.2" - define-properties "^1.1.4" - es-abstract "^1.20.4" - get-intrinsic "^1.1.3" + define-properties "^1.2.0" + es-abstract "^1.22.1" + get-intrinsic "^1.2.1" has-symbols "^1.0.3" - internal-slot "^1.0.3" - regexp.prototype.flags "^1.4.3" + internal-slot "^1.0.5" + regexp.prototype.flags "^1.5.0" side-channel "^1.0.4" +string.prototype.trim@^1.2.7: + version "1.2.7" + resolved "https://registry.yarnpkg.com/string.prototype.trim/-/string.prototype.trim-1.2.7.tgz#a68352740859f6893f14ce3ef1bb3037f7a90533" + integrity sha512-p6TmeT1T3411M8Cgg9wBTMRtY2q9+PNy9EV1i2lIXUN/btt763oIfxwN3RR8VU6wHX8j/1CFy0L+YuThm6bgOg== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.4" + es-abstract "^1.20.4" + string.prototype.trimend@^1.0.6: version "1.0.6" resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.6.tgz#c4a27fa026d979d79c04f17397f250a462944533" @@ -9896,9 +10568,9 @@ strip-ansi@^6.0.0, strip-ansi@^6.0.1: ansi-regex "^5.0.1" strip-ansi@^7.0.1: - version "7.0.1" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.0.1.tgz#61740a08ce36b61e50e65653f07060d000975fb2" - integrity sha512-cXNxvT8dFNRVfhVME3JAe98mkXDYN2O1l7jmcwMnOslDeESg1rF/OZMtK0nRAhiari1unG5cD4jG3rapUAkLbw== + version "7.1.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.1.0.tgz#d5b6568ca689d8561370b0707685d22434faff45" + integrity sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ== dependencies: ansi-regex "^6.0.1" @@ -9922,20 +10594,25 @@ strip-final-newline@^2.0.0: resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad" integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA== -strip-json-comments@^3.1.0, strip-json-comments@^3.1.1: +strip-final-newline@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-3.0.0.tgz#52894c313fbff318835280aed60ff71ebf12b8fd" + integrity sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw== + +strip-json-comments@^3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== style-loader@^3.3.1: - version "3.3.1" - resolved "https://registry.yarnpkg.com/style-loader/-/style-loader-3.3.1.tgz#057dfa6b3d4d7c7064462830f9113ed417d38575" - integrity sha512-GPcQ+LDJbrcxHORTRes6Jy2sfvK2kS6hpSfI/fXhPt+spVzxF6LJ1dHLN9zIGmVaaP044YKaIatFaufENRiDoQ== + version "3.3.3" + resolved "https://registry.yarnpkg.com/style-loader/-/style-loader-3.3.3.tgz#bba8daac19930169c0c9c96706749a597ae3acff" + integrity sha512-53BiGLXAcll9maCYtZi2RCQZKa8NQQai5C4horqKyRmHj9H7QmcUyucrH+4KW/gBQbXM2AsB0axoEcFZPlfPcw== style-to-object@^0.4.0: - version "0.4.1" - resolved "https://registry.yarnpkg.com/style-to-object/-/style-to-object-0.4.1.tgz#53cf856f7cf7f172d72939d9679556469ba5de37" - integrity sha512-HFpbb5gr2ypci7Qw+IOhnP2zOU7e77b+rzM+wTzXzfi1PrtBCX0E7Pk4wL4iTLnhzZ+JgEGAhX81ebTg/aYjQw== + version "0.4.2" + resolved "https://registry.yarnpkg.com/style-to-object/-/style-to-object-0.4.2.tgz#a8247057111dea8bd3b8a1a66d2d0c9cf9218a54" + integrity sha512-1JGpfPB3lo42ZX8cuPrheZbfQ6kqPPnPHlKMyeRYtfKD+0jG+QsXgXN57O/dvJlzlB2elI6dGmrPnl5VPQFPaA== dependencies: inline-style-parser "0.1.1" @@ -9947,10 +10624,23 @@ stylehacks@^5.1.1: browserslist "^4.21.4" postcss-selector-parser "^6.0.4" -stylis@4.1.3: - version "4.1.3" - resolved "https://registry.yarnpkg.com/stylis/-/stylis-4.1.3.tgz#fd2fbe79f5fed17c55269e16ed8da14c84d069f7" - integrity sha512-GP6WDNWf+o403jrEp9c5jibKavrtLW+/qYGhFxFrG8maXhwTBI7gLLhiBb0o7uFccWN+EOS9aMO6cGHWAO07OA== +stylis@4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/stylis/-/stylis-4.2.0.tgz#79daee0208964c8fe695a42fcffcac633a211a51" + integrity sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw== + +sucrase@^3.32.0: + version "3.34.0" + resolved "https://registry.yarnpkg.com/sucrase/-/sucrase-3.34.0.tgz#1e0e2d8fcf07f8b9c3569067d92fbd8690fb576f" + integrity sha512-70/LQEZ07TEcxiU2dz51FKaE6hCTWC6vr7FOk3Gr0U60C3shtAN+H+BFr9XlYe5xqf3RA8nrc+VIwzCfnxuXJw== + dependencies: + "@jridgewell/gen-mapping" "^0.3.2" + commander "^4.0.0" + glob "7.1.6" + lines-and-columns "^1.1.6" + mz "^2.7.0" + pirates "^4.0.1" + ts-interface-checker "^0.1.9" supports-color@^5.3.0: version "5.5.0" @@ -10029,10 +10719,11 @@ svgo@^2.7.0: stable "^0.1.8" swr@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/swr/-/swr-2.0.0.tgz#91d999359e2be92de1a41f6b6711d72be20ffdbd" - integrity sha512-IhUx5yPkX+Fut3h0SqZycnaNLXLXsb2ECFq0Y29cxnK7d8r7auY2JWNbCW3IX+EqXUg3rwNJFlhrw5Ye/b6k7w== + version "2.2.2" + resolved "https://registry.yarnpkg.com/swr/-/swr-2.2.2.tgz#abcb1f9c97e10527789884169d58b878472d4c98" + integrity sha512-CbR41AoMD4TQBQw9ic3GTXspgfM9Y8Mdhb5Ob4uIKXhWqnRLItwA5fpGvB7SmSw3+zEjb0PdhiEumtUvYoQ+bQ== dependencies: + client-only "^0.0.1" use-sync-external-store "^1.2.0" symbol-tree@^3.2.4: @@ -10040,34 +10731,41 @@ symbol-tree@^3.2.4: resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.4.tgz#430637d248ba77e078883951fb9aa0eed7c63fa2" integrity sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw== +synckit@^0.8.5: + version "0.8.5" + resolved "https://registry.yarnpkg.com/synckit/-/synckit-0.8.5.tgz#b7f4358f9bb559437f9f167eb6bc46b3c9818fa3" + integrity sha512-L1dapNV6vu2s/4Sputv8xGsCdAVlb5nRDMFU/E27D44l5U6cw1g0dGd45uLc+OXjNMmF4ntiMdCimzcjFKQI8Q== + dependencies: + "@pkgr/utils" "^2.3.1" + tslib "^2.5.0" + tailwindcss@^3.0.2: - version "3.2.4" - resolved "https://registry.yarnpkg.com/tailwindcss/-/tailwindcss-3.2.4.tgz#afe3477e7a19f3ceafb48e4b083e292ce0dc0250" - integrity sha512-AhwtHCKMtR71JgeYDaswmZXhPcW9iuI9Sp2LvZPo9upDZ7231ZJ7eA9RaURbhpXGVlrjX4cFNlB4ieTetEb7hQ== + version "3.3.3" + resolved "https://registry.yarnpkg.com/tailwindcss/-/tailwindcss-3.3.3.tgz#90da807393a2859189e48e9e7000e6880a736daf" + integrity sha512-A0KgSkef7eE4Mf+nKJ83i75TMyq8HqY3qmFIJSWy8bNt0v1lG7jUcpGpoTFxAwYcWOphcTBLPPJg+bDfhDf52w== dependencies: + "@alloc/quick-lru" "^5.2.0" arg "^5.0.2" chokidar "^3.5.3" - color-name "^1.1.4" - detective "^5.2.1" didyoumean "^1.2.2" dlv "^1.1.3" fast-glob "^3.2.12" glob-parent "^6.0.2" is-glob "^4.0.3" - lilconfig "^2.0.6" + jiti "^1.18.2" + lilconfig "^2.1.0" micromatch "^4.0.5" normalize-path "^3.0.0" object-hash "^3.0.0" picocolors "^1.0.0" - postcss "^8.4.18" - postcss-import "^14.1.0" - postcss-js "^4.0.0" - postcss-load-config "^3.1.4" - postcss-nested "6.0.0" - postcss-selector-parser "^6.0.10" - postcss-value-parser "^4.2.0" - quick-lru "^5.1.1" - resolve "^1.22.1" + postcss "^8.4.23" + postcss-import "^15.1.0" + postcss-js "^4.0.1" + postcss-load-config "^4.0.1" + postcss-nested "^6.0.1" + postcss-selector-parser "^6.0.11" + resolve "^1.22.2" + sucrase "^3.32.0" tapable@^1.0.0: version "1.1.3" @@ -10102,24 +10800,24 @@ terminal-link@^2.0.0: ansi-escapes "^4.2.1" supports-hyperlinks "^2.0.0" -terser-webpack-plugin@^5.1.3, terser-webpack-plugin@^5.2.5: - version "5.3.6" - resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-5.3.6.tgz#5590aec31aa3c6f771ce1b1acca60639eab3195c" - integrity sha512-kfLFk+PoLUQIbLmB1+PZDMRSZS99Mp+/MHqDNmMA6tOItzRt+Npe3E+fsMs5mfcM0wCtrrdU387UnV+vnSffXQ== +terser-webpack-plugin@^5.2.5, terser-webpack-plugin@^5.3.7: + version "5.3.9" + resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-5.3.9.tgz#832536999c51b46d468067f9e37662a3b96adfe1" + integrity sha512-ZuXsqE07EcggTWQjXUj+Aot/OMcD0bMKGgF63f7UxYcu5/AJF53aIpK1YoP5xR9l6s/Hy2b+t1AM0bLNPRuhwA== dependencies: - "@jridgewell/trace-mapping" "^0.3.14" + "@jridgewell/trace-mapping" "^0.3.17" jest-worker "^27.4.5" schema-utils "^3.1.1" - serialize-javascript "^6.0.0" - terser "^5.14.1" + serialize-javascript "^6.0.1" + terser "^5.16.8" -terser@^5.0.0, terser@^5.10.0, terser@^5.14.1: - version "5.16.1" - resolved "https://registry.yarnpkg.com/terser/-/terser-5.16.1.tgz#5af3bc3d0f24241c7fb2024199d5c461a1075880" - integrity sha512-xvQfyfA1ayT0qdK47zskQgRZeWLoOQ8JQ6mIgRGVNwZKdQMU+5FkCBjmv4QjcrTzyZquRw2FVtlJSRUmMKQslw== +terser@^5.0.0, terser@^5.10.0, terser@^5.16.8: + version "5.19.3" + resolved "https://registry.yarnpkg.com/terser/-/terser-5.19.3.tgz#359baeba615aef13db4b8c4d77a2aa0d8814aa9e" + integrity sha512-pQzJ9UJzM0IgmT4FAtYI6+VqFf0lj/to58AV0Xfgg0Up37RyPG7Al+1cepC6/BVuAxR9oNb41/DL4DEoHJvTdg== dependencies: - "@jridgewell/source-map" "^0.3.2" - acorn "^8.5.0" + "@jridgewell/source-map" "^0.3.3" + acorn "^8.8.2" commander "^2.20.0" source-map-support "~0.5.20" @@ -10137,10 +10835,24 @@ text-table@^0.2.0: resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" integrity sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw== +thenify-all@^1.0.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/thenify-all/-/thenify-all-1.6.0.tgz#1a1918d402d8fc3f98fbf234db0bcc8cc10e9726" + integrity sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA== + dependencies: + thenify ">= 3.1.0 < 4" + +"thenify@>= 3.1.0 < 4": + version "3.3.1" + resolved "https://registry.yarnpkg.com/thenify/-/thenify-3.3.1.tgz#8932e686a4066038a016dd9e2ca46add9838a95f" + integrity sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw== + dependencies: + any-promise "^1.0.0" + throat@^6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/throat/-/throat-6.0.1.tgz#d514fedad95740c12c2d7fc70ea863eb51ade375" - integrity sha512-8hmiGIJMDlwjg7dlJ4yKGLK8EsYqKgPWbG3b4wjJddKNwc7N7Dpn08Df4szr/sZdMVeOstrdYSsqzX6BYbcB+w== + version "6.0.2" + resolved "https://registry.yarnpkg.com/throat/-/throat-6.0.2.tgz#51a3fbb5e11ae72e2cf74861ed5c8020f89f29fe" + integrity sha512-WKexMoJj3vEuK0yFEapj8y64V0A6xcuPuK9Gt1d0R+dzCSJc0lHqQytAbSB4cDAK0dWh4T0E2ETkoLE2WZ41OQ== thunky@^1.0.2: version "1.1.0" @@ -10162,6 +10874,11 @@ tiny-warning@^1.0.2: resolved "https://registry.yarnpkg.com/tiny-warning/-/tiny-warning-1.0.3.tgz#94a30db453df4c643d0fd566060d60a875d84754" integrity sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA== +titleize@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/titleize/-/titleize-3.0.0.tgz#71c12eb7fdd2558aa8a44b0be83b8a76694acd53" + integrity sha512-KxVu8EYHDPBdUYdKZdKtU2aj2XfEx9AfjXxE/Aj0vT06w2icA09Vus1rh6eSu1y01akYg6BjIK/hxyLJINoMLQ== + tmpl@1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/tmpl/-/tmpl-1.0.5.tgz#8683e0b902bb9c20c4f726e3c0b69f36518c07cc" @@ -10190,9 +10907,9 @@ toposort@^2.0.2: integrity sha512-0a5EOkAUp8D4moMi2W8ZF8jcga7BgZd91O/yabJCFY8az+XSzeGyTKs0Aoo897iV1Nj6guFq8orWDS96z91oGg== tough-cookie@^4.0.0: - version "4.1.2" - resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-4.1.2.tgz#e53e84b85f24e0b65dd526f46628db6c85f6b874" - integrity sha512-G9fqXWoYFZgTc2z8Q5zaHy/vJMjm+WV0AkAeHxVCQiEB1b+dGvWzFW6QV07cY5jQ5gRkeid2qIkzkxUnmoQZUQ== + version "4.1.3" + resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-4.1.3.tgz#97b9adb0728b42280aa3d814b6b999b2ff0318bf" + integrity sha512-aX/y5pVRkfRnfmuX+OdbSdXvPe6ieKX/G2s7e98f4poJHnqH3281gDPm/metm6E/WRamfx7WC4HUqkWHfQHprw== dependencies: psl "^1.1.33" punycode "^2.1.1" @@ -10233,13 +10950,23 @@ tryer@^1.0.1: resolved "https://registry.yarnpkg.com/tryer/-/tryer-1.0.1.tgz#f2c85406800b9b0f74c9f7465b81eaad241252f8" integrity sha512-c3zayb8/kWWpycWYg87P71E1S1ZL6b6IJxfb5fvsUgsf0S2MVGaDhDXXjDMpdCpfWXqptc+4mXwmiy1ypXqRAA== -tsconfig-paths@^3.14.1: - version "3.14.1" - resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-3.14.1.tgz#ba0734599e8ea36c862798e920bcf163277b137a" - integrity sha512-fxDhWnFSLt3VuTwtvJt5fpwxBHg5AdKWMsgcPOOIilyjymcYVZoCQF8fvFRezCNfblEXmi+PcM1eYHeOAgXCOQ== +ts-api-utils@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/ts-api-utils/-/ts-api-utils-1.0.2.tgz#7c094f753b6705ee4faee25c3c684ade52d66d99" + integrity sha512-Cbu4nIqnEdd+THNEsBdkolnOXhg0I8XteoHaEKgvsxpsbWda4IsUut2c187HxywQCvveojow0Dgw/amxtSKVkQ== + +ts-interface-checker@^0.1.9: + version "0.1.13" + resolved "https://registry.yarnpkg.com/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz#784fd3d679722bc103b1b4b8030bcddb5db2a699" + integrity sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA== + +tsconfig-paths@^3.14.2: + version "3.14.2" + resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-3.14.2.tgz#6e32f1f79412decd261f92d633a9dc1cfa99f088" + integrity sha512-o/9iXgCYc5L/JxCHPe3Hvh8Q/2xm5Z+p18PESBU6Ff33695QnCHBEjcytY2q19ua7Mbl/DavtBOLq+oG0RCL+g== dependencies: "@types/json5" "^0.0.29" - json5 "^1.0.1" + json5 "^1.0.2" minimist "^1.2.6" strip-bom "^3.0.0" @@ -10248,15 +10975,10 @@ tslib@^1.8.1: resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== -tslib@^2.0.1, tslib@^2.0.3: - version "2.4.1" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.4.1.tgz#0d0bfbaac2880b91e22df0768e55be9753a5b17e" - integrity sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA== - -tslib@^2.4.0: - version "2.5.0" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.5.0.tgz#42bfed86f5787aeb41d031866c8f402429e0fddf" - integrity sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg== +tslib@^2.0.1, tslib@^2.0.3, tslib@^2.4.0, tslib@^2.5.0, tslib@^2.6.0: + version "2.6.2" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.2.tgz#703ac29425e7b37cd6fd456e92404d46d1f3e4ae" + integrity sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q== tsutils@^3.21.0: version "3.21.0" @@ -10272,13 +10994,6 @@ type-check@^0.4.0, type-check@~0.4.0: dependencies: prelude-ls "^1.2.1" -type-check@~0.3.2: - version "0.3.2" - resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72" - integrity sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg== - dependencies: - prelude-ls "~1.1.2" - type-detect@4.0.8: version "4.0.8" resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c" @@ -10312,6 +11027,45 @@ type-is@~1.6.18: media-typer "0.3.0" mime-types "~2.1.24" +typed-array-buffer@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/typed-array-buffer/-/typed-array-buffer-1.0.0.tgz#18de3e7ed7974b0a729d3feecb94338d1472cd60" + integrity sha512-Y8KTSIglk9OZEr8zywiIHG/kmQ7KWyjseXs1CbSo8vC42w7hg2HgYTxSWwP0+is7bWDc1H+Fo026CpHFwm8tkw== + dependencies: + call-bind "^1.0.2" + get-intrinsic "^1.2.1" + is-typed-array "^1.1.10" + +typed-array-byte-length@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/typed-array-byte-length/-/typed-array-byte-length-1.0.0.tgz#d787a24a995711611fb2b87a4052799517b230d0" + integrity sha512-Or/+kvLxNpeQ9DtSydonMxCx+9ZXOswtwJn17SNLvhptaXYDJvkFFP5zbfU/uLmvnBJlI4yrnXRxpdWH/M5tNA== + dependencies: + call-bind "^1.0.2" + for-each "^0.3.3" + has-proto "^1.0.1" + is-typed-array "^1.1.10" + +typed-array-byte-offset@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/typed-array-byte-offset/-/typed-array-byte-offset-1.0.0.tgz#cbbe89b51fdef9cd6aaf07ad4707340abbc4ea0b" + integrity sha512-RD97prjEt9EL8YgAgpOkf3O4IF9lhJFr9g0htQkm0rchFp/Vx7LW5Q8fSXXub7BXAODyUQohRMyOc3faCPd0hg== + dependencies: + available-typed-arrays "^1.0.5" + call-bind "^1.0.2" + for-each "^0.3.3" + has-proto "^1.0.1" + is-typed-array "^1.1.10" + +typed-array-length@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/typed-array-length/-/typed-array-length-1.0.4.tgz#89d83785e5c4098bec72e08b319651f0eac9c1bb" + integrity sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng== + dependencies: + call-bind "^1.0.2" + for-each "^0.3.3" + is-typed-array "^1.1.9" + typedarray-to-buffer@^3.1.5: version "3.1.5" resolved "https://registry.yarnpkg.com/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz#a97ee7a9ff42691b9f783ff1bc5112fe3fca9080" @@ -10319,10 +11073,10 @@ typedarray-to-buffer@^3.1.5: dependencies: is-typedarray "^1.0.0" -typescript@^4.9.4: - version "4.9.4" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.9.4.tgz#a2a3d2756c079abda241d75f149df9d561091e78" - integrity sha512-Uz+dTXYzxXXbsFpM86Wh3dKCxrQqUcVMxwU54orwlJjOpO3ao8L7j5lH+dWfTwgCwIuM9GQ2kvVotzYJMXTBZg== +typescript@*: + version "5.2.2" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.2.2.tgz#5ebb5e5a5b75f085f22bc3f8460fba308310fa78" + integrity sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w== unbox-primitive@^1.0.2: version "1.0.2" @@ -10465,15 +11219,20 @@ unquote@~1.1.1: resolved "https://registry.yarnpkg.com/unquote/-/unquote-1.1.1.tgz#8fded7324ec6e88a0ff8b905e7c098cdc086d544" integrity sha512-vRCqFv6UhXpWxZPyGDh/F3ZpNv8/qo7w6iufLpQg9aKnQ71qM4B5KiI7Mia9COcjEhrO9LueHpMYjYzsWH3OIg== +untildify@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/untildify/-/untildify-4.0.0.tgz#2bc947b953652487e4600949fb091e3ae8cd919b" + integrity sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw== + upath@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/upath/-/upath-1.2.0.tgz#8f66dbcd55a883acdae4408af8b035a5044c1894" integrity sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg== -update-browserslist-db@^1.0.9: - version "1.0.10" - resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz#0f54b876545726f17d00cd9a2561e6dade943ff3" - integrity sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ== +update-browserslist-db@^1.0.11: + version "1.0.11" + resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.0.11.tgz#9a2a641ad2907ae7b3616506f4b977851db5b940" + integrity sha512-dCwEFf0/oT85M1fHBg4F0jtLwJrutGoHSQXCh7u4o2t1drG+c0a9Flnqww6XUKSfQMPpJBRjU8d4RXB09qtvaA== dependencies: escalade "^3.1.1" picocolors "^1.0.0" @@ -10672,9 +11431,9 @@ webpack-dev-middleware@^5.3.1: schema-utils "^4.0.0" webpack-dev-server@^4.6.0: - version "4.11.1" - resolved "https://registry.yarnpkg.com/webpack-dev-server/-/webpack-dev-server-4.11.1.tgz#ae07f0d71ca0438cf88446f09029b92ce81380b5" - integrity sha512-lILVz9tAUy1zGFwieuaQtYiadImb5M3d+H+L1zDYalYoDl0cksAB1UNyuE5MMWJrG6zR1tXkCP2fitl7yoUJiw== + version "4.15.1" + resolved "https://registry.yarnpkg.com/webpack-dev-server/-/webpack-dev-server-4.15.1.tgz#8944b29c12760b3a45bdaa70799b17cb91b03df7" + integrity sha512-5hbAst3h3C3L8w6W4P96L5vaV0PxSmJhxZvWKYIdgxOQm8pNZ5dEOmmSLBVpP85ReeyRt6AS1QJNyo/oFFPeVA== dependencies: "@types/bonjour" "^3.5.9" "@types/connect-history-api-fallback" "^1.3.5" @@ -10682,7 +11441,7 @@ webpack-dev-server@^4.6.0: "@types/serve-index" "^1.9.1" "@types/serve-static" "^1.13.10" "@types/sockjs" "^0.3.33" - "@types/ws" "^8.5.1" + "@types/ws" "^8.5.5" ansi-html-community "^0.0.8" bonjour-service "^1.0.11" chokidar "^3.5.3" @@ -10695,6 +11454,7 @@ webpack-dev-server@^4.6.0: html-entities "^2.3.2" http-proxy-middleware "^2.0.3" ipaddr.js "^2.0.1" + launch-editor "^2.6.0" open "^8.0.9" p-retry "^4.5.0" rimraf "^3.0.2" @@ -10704,7 +11464,7 @@ webpack-dev-server@^4.6.0: sockjs "^0.3.24" spdy "^4.0.2" webpack-dev-middleware "^5.3.1" - ws "^8.4.2" + ws "^8.13.0" webpack-manifest-plugin@^4.0.2: version "4.1.1" @@ -10736,21 +11496,21 @@ webpack-sources@^3.2.3: integrity sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w== webpack@^5.64.4: - version "5.76.1" - resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.76.1.tgz#7773de017e988bccb0f13c7d75ec245f377d295c" - integrity sha512-4+YIK4Abzv8172/SGqObnUjaIHjLEuUasz9EwQj/9xmPPkYJy2Mh03Q/lJfSD3YLzbxy5FeTq5Uw0323Oh6SJQ== + version "5.88.2" + resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.88.2.tgz#f62b4b842f1c6ff580f3fcb2ed4f0b579f4c210e" + integrity sha512-JmcgNZ1iKj+aiR0OvTYtWQqJwq37Pf683dY9bVORwVbUrDhLhdn/PlO2sHsFHPkj7sHNQF3JwaAkp49V+Sq1tQ== dependencies: "@types/eslint-scope" "^3.7.3" - "@types/estree" "^0.0.51" - "@webassemblyjs/ast" "1.11.1" - "@webassemblyjs/wasm-edit" "1.11.1" - "@webassemblyjs/wasm-parser" "1.11.1" + "@types/estree" "^1.0.0" + "@webassemblyjs/ast" "^1.11.5" + "@webassemblyjs/wasm-edit" "^1.11.5" + "@webassemblyjs/wasm-parser" "^1.11.5" acorn "^8.7.1" - acorn-import-assertions "^1.7.6" + acorn-import-assertions "^1.9.0" browserslist "^4.14.5" chrome-trace-event "^1.0.2" - enhanced-resolve "^5.10.0" - es-module-lexer "^0.9.0" + enhanced-resolve "^5.15.0" + es-module-lexer "^1.2.1" eslint-scope "5.1.1" events "^3.2.0" glob-to-regexp "^0.4.1" @@ -10759,9 +11519,9 @@ webpack@^5.64.4: loader-runner "^4.2.0" mime-types "^2.1.27" neo-async "^2.6.2" - schema-utils "^3.1.0" + schema-utils "^3.2.0" tapable "^2.1.1" - terser-webpack-plugin "^5.1.3" + terser-webpack-plugin "^5.3.7" watchpack "^2.4.0" webpack-sources "^3.2.3" @@ -10787,9 +11547,9 @@ whatwg-encoding@^1.0.5: iconv-lite "0.4.24" whatwg-fetch@^3.6.2: - version "3.6.2" - resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-3.6.2.tgz#dced24f37f2624ed0281725d51d0e2e3fe677f8c" - integrity sha512-bJlen0FcuU/0EMLrdbJ7zOnW6ITZLrZMIarMUVmdKtsGvZna8vxKYaexICWPfZ8qwf9fzNq+UEIZrnSaApt6RA== + version "3.6.18" + resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-3.6.18.tgz#2f640cdee315abced7daeaed2309abd1e44e62d4" + integrity sha512-ltN7j66EneWn5TFDO4L9inYC1D+Czsxlrw2SalgjMmEMkLfA5SIZxEFdE6QtHFiiM6Q7WL32c7AkI3w6yxM84Q== whatwg-mimetype@^2.3.0: version "2.3.0" @@ -10833,6 +11593,45 @@ which-boxed-primitive@^1.0.2: is-string "^1.0.5" is-symbol "^1.0.3" +which-builtin-type@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/which-builtin-type/-/which-builtin-type-1.1.3.tgz#b1b8443707cc58b6e9bf98d32110ff0c2cbd029b" + integrity sha512-YmjsSMDBYsM1CaFiayOVT06+KJeXf0o5M/CAd4o1lTadFAtacTUM49zoYxr/oroopFDfhvN6iEcBxUyc3gvKmw== + dependencies: + function.prototype.name "^1.1.5" + has-tostringtag "^1.0.0" + is-async-function "^2.0.0" + is-date-object "^1.0.5" + is-finalizationregistry "^1.0.2" + is-generator-function "^1.0.10" + is-regex "^1.1.4" + is-weakref "^1.0.2" + isarray "^2.0.5" + which-boxed-primitive "^1.0.2" + which-collection "^1.0.1" + which-typed-array "^1.1.9" + +which-collection@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/which-collection/-/which-collection-1.0.1.tgz#70eab71ebbbd2aefaf32f917082fc62cdcb70906" + integrity sha512-W8xeTUwaln8i3K/cY1nGXzdnVZlidBcagyNFtBdD5kxnb4TvGKR7FfSIS3mYpwWS1QUCutfKz8IY8RjftB0+1A== + dependencies: + is-map "^2.0.1" + is-set "^2.0.1" + is-weakmap "^2.0.1" + is-weakset "^2.0.1" + +which-typed-array@^1.1.10, which-typed-array@^1.1.11, which-typed-array@^1.1.9: + version "1.1.11" + resolved "https://registry.yarnpkg.com/which-typed-array/-/which-typed-array-1.1.11.tgz#99d691f23c72aab6768680805a271b69761ed61a" + integrity sha512-qe9UWWpkeG5yzZ0tNYxDmd7vo58HDBc39mZ0xWWpolAGADdFOzkfamWLDxkOWcvHQKVmdTyQdLD4NOfjLWTKew== + dependencies: + available-typed-arrays "^1.0.5" + call-bind "^1.0.2" + for-each "^0.3.3" + gopd "^1.0.1" + has-tostringtag "^1.0.0" + which@^1.3.1: version "1.3.1" resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" @@ -10847,30 +11646,25 @@ which@^2.0.1: dependencies: isexe "^2.0.0" -word-wrap@^1.2.3, word-wrap@~1.2.3: - version "1.2.3" - resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c" - integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ== - -workbox-background-sync@6.5.4: - version "6.5.4" - resolved "https://registry.yarnpkg.com/workbox-background-sync/-/workbox-background-sync-6.5.4.tgz#3141afba3cc8aa2ae14c24d0f6811374ba8ff6a9" - integrity sha512-0r4INQZMyPky/lj4Ou98qxcThrETucOde+7mRGJl13MPJugQNKeZQOdIJe/1AchOP23cTqHcN/YVpD6r8E6I8g== +workbox-background-sync@6.6.1: + version "6.6.1" + resolved "https://registry.yarnpkg.com/workbox-background-sync/-/workbox-background-sync-6.6.1.tgz#08d603a33717ce663e718c30cc336f74909aff2f" + integrity sha512-trJd3ovpWCvzu4sW0E8rV3FUyIcC0W8G+AZ+VcqzzA890AsWZlUGOTSxIMmIHVusUw/FDq1HFWfy/kC/WTRqSg== dependencies: idb "^7.0.1" - workbox-core "6.5.4" + workbox-core "6.6.1" -workbox-broadcast-update@6.5.4: - version "6.5.4" - resolved "https://registry.yarnpkg.com/workbox-broadcast-update/-/workbox-broadcast-update-6.5.4.tgz#8441cff5417cd41f384ba7633ca960a7ffe40f66" - integrity sha512-I/lBERoH1u3zyBosnpPEtcAVe5lwykx9Yg1k6f8/BGEPGaMMgZrwVrqL1uA9QZ1NGGFoyE6t9i7lBjOlDhFEEw== +workbox-broadcast-update@6.6.1: + version "6.6.1" + resolved "https://registry.yarnpkg.com/workbox-broadcast-update/-/workbox-broadcast-update-6.6.1.tgz#0fad9454cf8e4ace0c293e5617c64c75d8a8c61e" + integrity sha512-fBhffRdaANdeQ1V8s692R9l/gzvjjRtydBOvR6WCSB0BNE2BacA29Z4r9/RHd9KaXCPl6JTdI9q0bR25YKP8TQ== dependencies: - workbox-core "6.5.4" + workbox-core "6.6.1" -workbox-build@6.5.4: - version "6.5.4" - resolved "https://registry.yarnpkg.com/workbox-build/-/workbox-build-6.5.4.tgz#7d06d31eb28a878817e1c991c05c5b93409f0389" - integrity sha512-kgRevLXEYvUW9WS4XoziYqZ8Q9j/2ziJYEtTrjdz5/L/cTUa2XfyMP2i7c3p34lgqJ03+mTiz13SdFef2POwbA== +workbox-build@6.6.1: + version "6.6.1" + resolved "https://registry.yarnpkg.com/workbox-build/-/workbox-build-6.6.1.tgz#6010e9ce550910156761448f2dbea8cfcf759cb0" + integrity sha512-INPgDx6aRycAugUixbKgiEQBWD0MPZqU5r0jyr24CehvNuLPSXp/wGOpdRJmts656lNiXwqV7dC2nzyrzWEDnw== dependencies: "@apideck/better-ajv-errors" "^0.3.1" "@babel/core" "^7.11.1" @@ -10894,132 +11688,132 @@ workbox-build@6.5.4: strip-comments "^2.0.1" tempy "^0.6.0" upath "^1.2.0" - workbox-background-sync "6.5.4" - workbox-broadcast-update "6.5.4" - workbox-cacheable-response "6.5.4" - workbox-core "6.5.4" - workbox-expiration "6.5.4" - workbox-google-analytics "6.5.4" - workbox-navigation-preload "6.5.4" - workbox-precaching "6.5.4" - workbox-range-requests "6.5.4" - workbox-recipes "6.5.4" - workbox-routing "6.5.4" - workbox-strategies "6.5.4" - workbox-streams "6.5.4" - workbox-sw "6.5.4" - workbox-window "6.5.4" - -workbox-cacheable-response@6.5.4: - version "6.5.4" - resolved "https://registry.yarnpkg.com/workbox-cacheable-response/-/workbox-cacheable-response-6.5.4.tgz#a5c6ec0c6e2b6f037379198d4ef07d098f7cf137" - integrity sha512-DCR9uD0Fqj8oB2TSWQEm1hbFs/85hXXoayVwFKLVuIuxwJaihBsLsp4y7J9bvZbqtPJ1KlCkmYVGQKrBU4KAug== - dependencies: - workbox-core "6.5.4" - -workbox-core@6.5.4: - version "6.5.4" - resolved "https://registry.yarnpkg.com/workbox-core/-/workbox-core-6.5.4.tgz#df48bf44cd58bb1d1726c49b883fb1dffa24c9ba" - integrity sha512-OXYb+m9wZm8GrORlV2vBbE5EC1FKu71GGp0H4rjmxmF4/HLbMCoTFws87M3dFwgpmg0v00K++PImpNQ6J5NQ6Q== - -workbox-expiration@6.5.4: - version "6.5.4" - resolved "https://registry.yarnpkg.com/workbox-expiration/-/workbox-expiration-6.5.4.tgz#501056f81e87e1d296c76570bb483ce5e29b4539" - integrity sha512-jUP5qPOpH1nXtjGGh1fRBa1wJL2QlIb5mGpct3NzepjGG2uFFBn4iiEBiI9GUmfAFR2ApuRhDydjcRmYXddiEQ== + workbox-background-sync "6.6.1" + workbox-broadcast-update "6.6.1" + workbox-cacheable-response "6.6.1" + workbox-core "6.6.1" + workbox-expiration "6.6.1" + workbox-google-analytics "6.6.1" + workbox-navigation-preload "6.6.1" + workbox-precaching "6.6.1" + workbox-range-requests "6.6.1" + workbox-recipes "6.6.1" + workbox-routing "6.6.1" + workbox-strategies "6.6.1" + workbox-streams "6.6.1" + workbox-sw "6.6.1" + workbox-window "6.6.1" + +workbox-cacheable-response@6.6.1: + version "6.6.1" + resolved "https://registry.yarnpkg.com/workbox-cacheable-response/-/workbox-cacheable-response-6.6.1.tgz#284c2b86be3f4fd191970ace8c8e99797bcf58e9" + integrity sha512-85LY4veT2CnTCDxaVG7ft3NKaFbH6i4urZXgLiU4AiwvKqS2ChL6/eILiGRYXfZ6gAwDnh5RkuDbr/GMS4KSag== + dependencies: + workbox-core "6.6.1" + +workbox-core@6.6.1: + version "6.6.1" + resolved "https://registry.yarnpkg.com/workbox-core/-/workbox-core-6.6.1.tgz#7184776d4134c5ed2f086878c882728fc9084265" + integrity sha512-ZrGBXjjaJLqzVothoE12qTbVnOAjFrHDXpZe7coCb6q65qI/59rDLwuFMO4PcZ7jcbxY+0+NhUVztzR/CbjEFw== + +workbox-expiration@6.6.1: + version "6.6.1" + resolved "https://registry.yarnpkg.com/workbox-expiration/-/workbox-expiration-6.6.1.tgz#a841fa36676104426dbfb9da1ef6a630b4f93739" + integrity sha512-qFiNeeINndiOxaCrd2DeL1Xh1RFug3JonzjxUHc5WkvkD2u5abY3gZL1xSUNt3vZKsFFGGORItSjVTVnWAZO4A== dependencies: idb "^7.0.1" - workbox-core "6.5.4" + workbox-core "6.6.1" -workbox-google-analytics@6.5.4: - version "6.5.4" - resolved "https://registry.yarnpkg.com/workbox-google-analytics/-/workbox-google-analytics-6.5.4.tgz#c74327f80dfa4c1954cbba93cd7ea640fe7ece7d" - integrity sha512-8AU1WuaXsD49249Wq0B2zn4a/vvFfHkpcFfqAFHNHwln3jK9QUYmzdkKXGIZl9wyKNP+RRX30vcgcyWMcZ9VAg== +workbox-google-analytics@6.6.1: + version "6.6.1" + resolved "https://registry.yarnpkg.com/workbox-google-analytics/-/workbox-google-analytics-6.6.1.tgz#a07a6655ab33d89d1b0b0a935ffa5dea88618c5d" + integrity sha512-1TjSvbFSLmkpqLcBsF7FuGqqeDsf+uAXO/pjiINQKg3b1GN0nBngnxLcXDYo1n/XxK4N7RaRrpRlkwjY/3ocuA== dependencies: - workbox-background-sync "6.5.4" - workbox-core "6.5.4" - workbox-routing "6.5.4" - workbox-strategies "6.5.4" + workbox-background-sync "6.6.1" + workbox-core "6.6.1" + workbox-routing "6.6.1" + workbox-strategies "6.6.1" -workbox-navigation-preload@6.5.4: - version "6.5.4" - resolved "https://registry.yarnpkg.com/workbox-navigation-preload/-/workbox-navigation-preload-6.5.4.tgz#ede56dd5f6fc9e860a7e45b2c1a8f87c1c793212" - integrity sha512-IIwf80eO3cr8h6XSQJF+Hxj26rg2RPFVUmJLUlM0+A2GzB4HFbQyKkrgD5y2d84g2IbJzP4B4j5dPBRzamHrng== +workbox-navigation-preload@6.6.1: + version "6.6.1" + resolved "https://registry.yarnpkg.com/workbox-navigation-preload/-/workbox-navigation-preload-6.6.1.tgz#61a34fe125558dd88cf09237f11bd966504ea059" + integrity sha512-DQCZowCecO+wRoIxJI2V6bXWK6/53ff+hEXLGlQL4Rp9ZaPDLrgV/32nxwWIP7QpWDkVEtllTAK5h6cnhxNxDA== dependencies: - workbox-core "6.5.4" + workbox-core "6.6.1" -workbox-precaching@6.5.4: - version "6.5.4" - resolved "https://registry.yarnpkg.com/workbox-precaching/-/workbox-precaching-6.5.4.tgz#740e3561df92c6726ab5f7471e6aac89582cab72" - integrity sha512-hSMezMsW6btKnxHB4bFy2Qfwey/8SYdGWvVIKFaUm8vJ4E53JAY+U2JwLTRD8wbLWoP6OVUdFlXsTdKu9yoLTg== +workbox-precaching@6.6.1: + version "6.6.1" + resolved "https://registry.yarnpkg.com/workbox-precaching/-/workbox-precaching-6.6.1.tgz#dedeeba10a2d163d990bf99f1c2066ac0d1a19e2" + integrity sha512-K4znSJ7IKxCnCYEdhNkMr7X1kNh8cz+mFgx9v5jFdz1MfI84pq8C2zG+oAoeE5kFrUf7YkT5x4uLWBNg0DVZ5A== dependencies: - workbox-core "6.5.4" - workbox-routing "6.5.4" - workbox-strategies "6.5.4" + workbox-core "6.6.1" + workbox-routing "6.6.1" + workbox-strategies "6.6.1" -workbox-range-requests@6.5.4: - version "6.5.4" - resolved "https://registry.yarnpkg.com/workbox-range-requests/-/workbox-range-requests-6.5.4.tgz#86b3d482e090433dab38d36ae031b2bb0bd74399" - integrity sha512-Je2qR1NXCFC8xVJ/Lux6saH6IrQGhMpDrPXWZWWS8n/RD+WZfKa6dSZwU+/QksfEadJEr/NfY+aP/CXFFK5JFg== +workbox-range-requests@6.6.1: + version "6.6.1" + resolved "https://registry.yarnpkg.com/workbox-range-requests/-/workbox-range-requests-6.6.1.tgz#ddaf7e73af11d362fbb2f136a9063a4c7f507a39" + integrity sha512-4BDzk28govqzg2ZpX0IFkthdRmCKgAKreontYRC5YsAPB2jDtPNxqx3WtTXgHw1NZalXpcH/E4LqUa9+2xbv1g== dependencies: - workbox-core "6.5.4" + workbox-core "6.6.1" -workbox-recipes@6.5.4: - version "6.5.4" - resolved "https://registry.yarnpkg.com/workbox-recipes/-/workbox-recipes-6.5.4.tgz#cca809ee63b98b158b2702dcfb741b5cc3e24acb" - integrity sha512-QZNO8Ez708NNwzLNEXTG4QYSKQ1ochzEtRLGaq+mr2PyoEIC1xFW7MrWxrONUxBFOByksds9Z4//lKAX8tHyUA== +workbox-recipes@6.6.1: + version "6.6.1" + resolved "https://registry.yarnpkg.com/workbox-recipes/-/workbox-recipes-6.6.1.tgz#ea70d2b2b0b0bce8de0a9d94f274d4a688e69fae" + integrity sha512-/oy8vCSzromXokDA+X+VgpeZJvtuf8SkQ8KL0xmRivMgJZrjwM3c2tpKTJn6PZA6TsbxGs3Sc7KwMoZVamcV2g== dependencies: - workbox-cacheable-response "6.5.4" - workbox-core "6.5.4" - workbox-expiration "6.5.4" - workbox-precaching "6.5.4" - workbox-routing "6.5.4" - workbox-strategies "6.5.4" + workbox-cacheable-response "6.6.1" + workbox-core "6.6.1" + workbox-expiration "6.6.1" + workbox-precaching "6.6.1" + workbox-routing "6.6.1" + workbox-strategies "6.6.1" -workbox-routing@6.5.4: - version "6.5.4" - resolved "https://registry.yarnpkg.com/workbox-routing/-/workbox-routing-6.5.4.tgz#6a7fbbd23f4ac801038d9a0298bc907ee26fe3da" - integrity sha512-apQswLsbrrOsBUWtr9Lf80F+P1sHnQdYodRo32SjiByYi36IDyL2r7BH1lJtFX8fwNHDa1QOVY74WKLLS6o5Pg== +workbox-routing@6.6.1: + version "6.6.1" + resolved "https://registry.yarnpkg.com/workbox-routing/-/workbox-routing-6.6.1.tgz#cba9a1c7e0d1ea11e24b6f8c518840efdc94f581" + integrity sha512-j4ohlQvfpVdoR8vDYxTY9rA9VvxTHogkIDwGdJ+rb2VRZQ5vt1CWwUUZBeD/WGFAni12jD1HlMXvJ8JS7aBWTg== dependencies: - workbox-core "6.5.4" + workbox-core "6.6.1" -workbox-strategies@6.5.4: - version "6.5.4" - resolved "https://registry.yarnpkg.com/workbox-strategies/-/workbox-strategies-6.5.4.tgz#4edda035b3c010fc7f6152918370699334cd204d" - integrity sha512-DEtsxhx0LIYWkJBTQolRxG4EI0setTJkqR4m7r4YpBdxtWJH1Mbg01Cj8ZjNOO8etqfA3IZaOPHUxCs8cBsKLw== +workbox-strategies@6.6.1: + version "6.6.1" + resolved "https://registry.yarnpkg.com/workbox-strategies/-/workbox-strategies-6.6.1.tgz#38d0f0fbdddba97bd92e0c6418d0b1a2ccd5b8bf" + integrity sha512-WQLXkRnsk4L81fVPkkgon1rZNxnpdO5LsO+ws7tYBC6QQQFJVI6v98klrJEjFtZwzw/mB/HT5yVp7CcX0O+mrw== dependencies: - workbox-core "6.5.4" + workbox-core "6.6.1" -workbox-streams@6.5.4: - version "6.5.4" - resolved "https://registry.yarnpkg.com/workbox-streams/-/workbox-streams-6.5.4.tgz#1cb3c168a6101df7b5269d0353c19e36668d7d69" - integrity sha512-FXKVh87d2RFXkliAIheBojBELIPnWbQdyDvsH3t74Cwhg0fDheL1T8BqSM86hZvC0ZESLsznSYWw+Va+KVbUzg== +workbox-streams@6.6.1: + version "6.6.1" + resolved "https://registry.yarnpkg.com/workbox-streams/-/workbox-streams-6.6.1.tgz#b2f7ba7b315c27a6e3a96a476593f99c5d227d26" + integrity sha512-maKG65FUq9e4BLotSKWSTzeF0sgctQdYyTMq529piEN24Dlu9b6WhrAfRpHdCncRS89Zi2QVpW5V33NX8PgH3Q== dependencies: - workbox-core "6.5.4" - workbox-routing "6.5.4" + workbox-core "6.6.1" + workbox-routing "6.6.1" -workbox-sw@6.5.4: - version "6.5.4" - resolved "https://registry.yarnpkg.com/workbox-sw/-/workbox-sw-6.5.4.tgz#d93e9c67924dd153a61367a4656ff4d2ae2ed736" - integrity sha512-vo2RQo7DILVRoH5LjGqw3nphavEjK4Qk+FenXeUsknKn14eCNedHOXWbmnvP4ipKhlE35pvJ4yl4YYf6YsJArA== +workbox-sw@6.6.1: + version "6.6.1" + resolved "https://registry.yarnpkg.com/workbox-sw/-/workbox-sw-6.6.1.tgz#d4c4ca3125088e8b9fd7a748ed537fa0247bd72c" + integrity sha512-R7whwjvU2abHH/lR6kQTTXLHDFU2izht9kJOvBRYK65FbwutT4VvnUAJIgHvfWZ/fokrOPhfoWYoPCMpSgUKHQ== workbox-webpack-plugin@^6.4.1: - version "6.5.4" - resolved "https://registry.yarnpkg.com/workbox-webpack-plugin/-/workbox-webpack-plugin-6.5.4.tgz#baf2d3f4b8f435f3469887cf4fba2b7fac3d0fd7" - integrity sha512-LmWm/zoaahe0EGmMTrSLUi+BjyR3cdGEfU3fS6PN1zKFYbqAKuQ+Oy/27e4VSXsyIwAw8+QDfk1XHNGtZu9nQg== + version "6.6.1" + resolved "https://registry.yarnpkg.com/workbox-webpack-plugin/-/workbox-webpack-plugin-6.6.1.tgz#4f81cc1ad4e5d2cd7477a86ba83c84ee2d187531" + integrity sha512-zpZ+ExFj9NmiI66cFEApyjk7hGsfJ1YMOaLXGXBoZf0v7Iu6hL0ZBe+83mnDq3YYWAfA3fnyFejritjOHkFcrA== dependencies: fast-json-stable-stringify "^2.1.0" pretty-bytes "^5.4.1" upath "^1.2.0" webpack-sources "^1.4.3" - workbox-build "6.5.4" + workbox-build "6.6.1" -workbox-window@6.5.4: - version "6.5.4" - resolved "https://registry.yarnpkg.com/workbox-window/-/workbox-window-6.5.4.tgz#d991bc0a94dff3c2dbb6b84558cff155ca878e91" - integrity sha512-HnLZJDwYBE+hpG25AQBO8RUWBJRaCsI9ksQJEp3aCOFCaG5kqaToAYXFRAHxzRluM2cQbGzdQF5rjKPWPA1fug== +workbox-window@6.6.1: + version "6.6.1" + resolved "https://registry.yarnpkg.com/workbox-window/-/workbox-window-6.6.1.tgz#f22a394cbac36240d0dadcbdebc35f711bb7b89e" + integrity sha512-wil4nwOY58nTdCvif/KEZjQ2NP8uk3gGeRNy2jPBbzypU4BT4D9L8xiwbmDBpZlSgJd2xsT9FvSNU0gsxV51JQ== dependencies: "@types/trusted-types" "^2.0.2" - workbox-core "6.5.4" + workbox-core "6.6.1" wrap-ansi@^7.0.0: version "7.0.0" @@ -11050,10 +11844,10 @@ ws@^7.4.6: resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.9.tgz#54fa7db29f4c7cec68b1ddd3a89de099942bb591" integrity sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q== -ws@^8.4.2: - version "8.11.0" - resolved "https://registry.yarnpkg.com/ws/-/ws-8.11.0.tgz#6a0d36b8edfd9f96d8b25683db2f8d7de6e8e143" - integrity sha512-HPG3wQd9sNQoT9xHyNCXoDUa+Xw/VevmY9FoHyQ+g+rrMn4j6FB4np7Z0OhdTgjx6MgQLK7jwSy1YecU1+4Asg== +ws@^8.13.0: + version "8.13.0" + resolved "https://registry.yarnpkg.com/ws/-/ws-8.13.0.tgz#9a9fb92f93cf41512a0735c8f4dd09b8a1211cd0" + integrity sha512-x9vcZYTrFPC7aSIbj7sRCYo7L/Xb8Iy+pW0ng0wt2vCJv7M9HOMy0UoN3rr+IFC7hb7vXoqS+P9ktyLLLhO+LA== xml-name-validator@^3.0.0: version "3.0.0" @@ -11065,16 +11859,16 @@ xmlchars@^2.2.0: resolved "https://registry.yarnpkg.com/xmlchars/-/xmlchars-2.2.0.tgz#060fe1bcb7f9c76fe2a17db86a9bc3ab894210cb" integrity sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw== -xtend@^4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54" - integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ== - y18n@^5.0.5: version "5.0.8" resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== +yallist@^3.0.2: + version "3.1.1" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd" + integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g== + yallist@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" @@ -11085,6 +11879,11 @@ yaml@^1.10.0, yaml@^1.10.2, yaml@^1.7.2: resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.10.2.tgz#2301c5ffbf12b467de8da2333a459e29e7920e4b" integrity sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg== +yaml@^2.1.1: + version "2.3.2" + resolved "https://registry.yarnpkg.com/yaml/-/yaml-2.3.2.tgz#f522db4313c671a0ca963a75670f1c12ea909144" + integrity sha512-N/lyzTPaJasoDmfV7YTrYCI0G/3ivm/9wdG0aHuheKowWQwGTsK0Eoiw6utmzAnI6pkJa0DUVygvp3spqqEKXg== + yargs-parser@^20.2.2: version "20.2.9" resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.9.tgz#2eb7dc3b0289718fc295f362753845c41a0c94ee" @@ -11118,10 +11917,10 @@ yup@^1.2.0: toposort "^2.0.2" type-fest "^2.19.0" -zustand@^4.1.1: - version "4.1.5" - resolved "https://registry.yarnpkg.com/zustand/-/zustand-4.1.5.tgz#7402b511f5b23ccb0f9ba6d20ae01ec817e16eb6" - integrity sha512-PsdRT8Bvq22Yyh1tvpgdHNE7OAeFKqJXUxtJvj1Ixw2B9O2YZ1M34ImQ+xyZah4wZrR4lENMoDUutKPpyXCQ/Q== +zustand@^4.4.1: + version "4.4.1" + resolved "https://registry.yarnpkg.com/zustand/-/zustand-4.4.1.tgz#0cd3a3e4756f21811bd956418fdc686877e8b3b0" + integrity sha512-QCPfstAS4EBiTQzlaGP1gmorkh/UL1Leaj2tdj+zZCZ/9bm0WS7sI2wnfD5lpOszFqWJ1DcPnGoY8RDL61uokw== dependencies: use-sync-external-store "1.2.0" From d7fd0678283797e5ff2bd348326c1825faaba93f Mon Sep 17 00:00:00 2001 From: Nathan Vieira Marcelino Date: Mon, 4 Sep 2023 11:19:20 -0300 Subject: [PATCH 221/328] refactor: use camelCase --- ...th-context.hoc.tsx => withContext.hoc.tsx} | 0 ...ource.enum.ts => repositorySource.enum.ts} | 0 .../{checkbox-input.tsx => checkboxInput.tsx} | 0 ...deeditor-input.tsx => codeeditorInput.tsx} | 0 .../{datetime-input.tsx => datetimeInput.tsx} | 0 .../{number-input.tsx => numberInput.tsx} | 0 .../{select-input.tsx => selectInput.tsx} | 0 .../{text-input.tsx => textInput.tsx} | 0 ...ner-resources.ts => containerResources.ts} | 0 frontend/src/context/workflows/types/index.ts | 4 +- ...low-piece-data.ts => workflowPieceData.ts} | 2 +- .../index.tsx | 39 +++++++++++-------- .../pieces.context.tsx | 4 +- .../providerContextWrapper.tsx} | 10 ++--- .../workflowEdges.context.tsx} | 2 +- .../workflowNodes.context.tsx} | 2 +- .../workflowPieces.context.tsx} | 2 +- .../workflowPiecesData.context.tsx} | 2 +- .../workflowSettingsData.context.tsx} | 2 +- ...text.tsx => workspaceSettings.context.tsx} | 2 +- frontend/src/modules/app/app.component.tsx | 2 +- ...nt.tsx => applicationRoutes.component.tsx} | 8 ++-- ...mponent.tsx => privateRoute.component.tsx} | 0 ...omponent.tsx => publicRoute.component.tsx} | 0 frontend/src/modules/layout/index.ts | 4 +- .../header/drawerMenu.component.tsx} | 4 +- .../header/drawerMenu.style.ts} | 0 .../header/drawerMenuItem.component.tsx} | 0 .../header/header.component.tsx | 2 +- .../privateLayout.component.tsx} | 0 .../publicLayout.component.tsx} | 0 frontend/src/pages/private/workflows/index.ts | 6 +-- ....tsx => workflowTaskDetails.component.tsx} | 0 ...ent.tsx => workflowTaskLogs.component.tsx} | 0 ...t.tsx => workflowTaskResult.component.tsx} | 0 .../components/workflows.component.tsx | 11 +++--- ... workflowsRunTasksFlowchart.component.tsx} | 8 ++-- ...t.tsx => workflowsRunsTable.component.tsx} | 26 ++++++++----- ...onent.tsx => workflowsTable.component.tsx} | 0 ...ponent.tsx => workflowsPage.component.tsx} | 0 .../components/customNode.component.tsx} | 0 .../components/drawerMenuComponent.tsx} | 4 +- .../pieceDocsPopover.component.tsx} | 0 .../components/sidebarAddNode.component.tsx} | 4 +- .../containerResourceForm.component.tsx} | 4 +- .../sidebarForm.component}/index.tsx | 10 ++--- .../pieceForm.component}/index.tsx | 6 +-- .../pieceFormItem.component/arrayInput.tsx} | 18 ++++----- .../disableCheckboxOptions.ts | 0 .../pieceFormItem.component}/index.tsx | 18 ++++----- .../pieceFormItem.component/objectInput.tsx} | 10 ++--- .../selectUpstreamInput.tsx} | 2 +- .../pieceForm.component/upstreamOptions.ts} | 0 .../pieceForm.component}/validation.ts | 0 .../storageForm.component.tsx} | 0 .../components/sidebarNode.component.tsx} | 2 +- .../sidebarSettingsForm.component.tsx} | 8 ++-- .../workflowEditorPanel.component.tsx} | 8 ++-- .../components/workflowsEditor.component.tsx} | 14 +++---- .../workflowsEditorPage.component.tsx} | 6 +-- .../src/pages/private/workspaces/index.ts | 4 +- .../repositoriesCard.component.tsx} | 4 +- .../repositorySecretsCard.component.tsx} | 0 .../storageSecretsCard.component.tsx} | 2 +- .../components/usersCard.component.tsx} | 2 +- .../workspaceSecretsCard.component.tsx} | 2 +- .../workspaceUsersCard.component.tsx} | 0 .../workspaceSettingsPage.component.tsx} | 16 ++++---- ...mponent.tsx => addWorkspace.component.tsx} | 0 ...omponent.tsx => pendingItem.component.tsx} | 0 ...onent.tsx => workspacesPage.component.tsx} | 4 +- .../signInPage.component.tsx} | 2 +- .../signUpPage.component.tsx} | 2 +- ...forage.config.ts => localForage.config.ts} | 0 .../services/requests/authentication/index.ts | 4 +- ...in.request.ts => postAuthLogin.request.ts} | 0 ...request.ts => postAuthRegister.request.ts} | 0 ....ts => getOperatorRepositories.request.ts} | 0 ...tOperatorsRepositoriesReleases.request.ts} | 0 ...ts => getPieceRepositoryPieces.request.ts} | 0 frontend/src/services/requests/piece/index.ts | 2 +- .../requests/piece/operator.interface.ts | 2 +- ...ts => deleteOperatorRepository.request.ts} | 0 ...> getOperatorRepositorySecrets.request.ts} | 2 +- .../src/services/requests/repository/index.ts | 6 +-- ...ace.ts => operatorRepository.interface.ts} | 0 ... patchOperatorRepositorySecret.request.ts} | 0 ...t.ts => getWorkflowRunTaskLogs.request.ts} | 0 ...ts => getWorkflowRunTaskResult.request.ts} | 0 ...uest.ts => getWorkflowRunTasks.request.ts} | 0 ....request.ts => getWorkflowRuns.request.ts} | 0 frontend/src/services/requests/runs/index.ts | 8 ++-- ...request.ts => deleteWorkflowId.request.ts} | 0 ...flow.request.ts => getWorkflow.request.ts} | 0 ...id.request.ts => getWorkflowId.request.ts} | 0 .../src/services/requests/workflow/index.ts | 10 ++--- ...low.request.ts => postWorkflow.request.ts} | 0 ...equest.ts => postWorkflowRunId.request.ts} | 0 ...st.ts => acceptWorkspaceInvite.request.ts} | 0 ...uest.ts => deleteUserWorkspace.request.ts} | 0 ....request.ts => deleteWorkspace.request.ts} | 0 ...d.request.ts => getWorkspaceId.request.ts} | 0 ...uest.ts => getWorkspaceMembers.request.ts} | 0 ...es.request.ts => getWorkspaces.request.ts} | 0 .../src/services/requests/workspaces/index.ts | 22 +++++------ ....request.ts => inviteWorkspace.request.ts} | 0 ...ace.reques.ts => patchWorkspace.reques.ts} | 0 ...s => postOperatorsRepositories.request.ts} | 0 ...s.request.ts => postWorkspaces.request.ts} | 0 ...st.ts => rejectWorkspaceInvite.request.ts} | 0 .../workspaces/workspaces.interface.ts | 2 +- ...ion.ts => createCustomContext.function.ts} | 0 frontend/src/utils/index.ts | 2 +- 113 files changed, 184 insertions(+), 170 deletions(-) rename frontend/src/common/hocs/{with-context.hoc.tsx => withContext.hoc.tsx} (100%) rename frontend/src/common/interfaces/{repository-source.enum.ts => repositorySource.enum.ts} (100%) rename frontend/src/components/{checkbox-input.tsx => checkboxInput.tsx} (100%) rename frontend/src/components/{codeeditor-input.tsx => codeeditorInput.tsx} (100%) rename frontend/src/components/{datetime-input.tsx => datetimeInput.tsx} (100%) rename frontend/src/components/{number-input.tsx => numberInput.tsx} (100%) rename frontend/src/components/{select-input.tsx => selectInput.tsx} (100%) rename frontend/src/components/{text-input.tsx => textInput.tsx} (100%) rename frontend/src/context/workflows/types/{container-resources.ts => containerResources.ts} (100%) rename frontend/src/context/workflows/types/{workflow-piece-data.ts => workflowPieceData.ts} (95%) rename frontend/src/context/workflows/{workflows-editor.context => workflowsEditor.context}/index.tsx (92%) rename frontend/src/context/workflows/{workflows-editor.context => workflowsEditor.context}/pieces.context.tsx (96%) rename frontend/src/context/workflows/{workflows-editor.context/provider-context-wrapper.tsx => workflowsEditor.context/providerContextWrapper.tsx} (65%) rename frontend/src/context/workflows/{workflows-editor.context/workflow-edges.context.tsx => workflowsEditor.context/workflowEdges.context.tsx} (96%) rename frontend/src/context/workflows/{workflows-editor.context/workflow-nodes.context.tsx => workflowsEditor.context/workflowNodes.context.tsx} (97%) rename frontend/src/context/workflows/{workflows-editor.context/workflow-pieces.context.tsx => workflowsEditor.context/workflowPieces.context.tsx} (97%) rename frontend/src/context/workflows/{workflows-editor.context/workflow-pieces-data.context.tsx => workflowsEditor.context/workflowPiecesData.context.tsx} (98%) rename frontend/src/context/workflows/{workflows-editor.context/workflow-settings-data.context.tsx => workflowsEditor.context/workflowSettingsData.context.tsx} (95%) rename frontend/src/context/workspaces/{workspace-settings.context.tsx => workspaceSettings.context.tsx} (98%) rename frontend/src/modules/app/router/{application-routes.component.tsx => applicationRoutes.component.tsx} (87%) rename frontend/src/modules/app/router/{private-route.component.tsx => privateRoute.component.tsx} (100%) rename frontend/src/modules/app/router/{public-route.component.tsx => publicRoute.component.tsx} (100%) rename frontend/src/modules/layout/{private-layout/header/drawer-menu.component.tsx => privateLayout/header/drawerMenu.component.tsx} (97%) rename frontend/src/modules/layout/{private-layout/header/drawer-menu.style.ts => privateLayout/header/drawerMenu.style.ts} (100%) rename frontend/src/modules/layout/{private-layout/header/drawer-menu-item.component.tsx => privateLayout/header/drawerMenuItem.component.tsx} (100%) rename frontend/src/modules/layout/{private-layout => privateLayout}/header/header.component.tsx (89%) rename frontend/src/modules/layout/{private-layout/private-layout.component.tsx => privateLayout/privateLayout.component.tsx} (100%) rename frontend/src/modules/layout/{public-layout/public-layout.component.tsx => publicLayout/publicLayout.component.tsx} (100%) rename frontend/src/pages/private/workflows/workflows/components/{workflow-task-details.component.tsx => workflowTaskDetails.component.tsx} (100%) rename frontend/src/pages/private/workflows/workflows/components/{workflow-task-logs.component.tsx => workflowTaskLogs.component.tsx} (100%) rename frontend/src/pages/private/workflows/workflows/components/{workflow-task-result.component.tsx => workflowTaskResult.component.tsx} (100%) rename frontend/src/pages/private/workflows/workflows/components/{workflows-run-tasks-flowchart.component.tsx => workflowsRunTasksFlowchart.component.tsx} (97%) rename frontend/src/pages/private/workflows/workflows/components/{workflows-runs-table.component.tsx => workflowsRunsTable.component.tsx} (92%) rename frontend/src/pages/private/workflows/workflows/components/{workflows-table.component.tsx => workflowsTable.component.tsx} (100%) rename frontend/src/pages/private/workflows/workflows/{workflows-page.component.tsx => workflowsPage.component.tsx} (100%) rename frontend/src/pages/private/workflows/{workflows-editor/components/custom-node.component.tsx => workflowsEditor/components/customNode.component.tsx} (100%) rename frontend/src/pages/private/workflows/{workflows-editor/components/drawer-menu-component.tsx => workflowsEditor/components/drawerMenuComponent.tsx} (93%) rename frontend/src/pages/private/workflows/{workflows-editor/components/piece-docs-popover.component.tsx => workflowsEditor/components/pieceDocsPopover.component.tsx} (100%) rename frontend/src/pages/private/workflows/{workflows-editor/components/sidebar-add-node.component.tsx => workflowsEditor/components/sidebarAddNode.component.tsx} (97%) rename frontend/src/pages/private/workflows/{workflows-editor/components/sidebar-form.component/container-resource-form.component.tsx => workflowsEditor/components/sidebarForm.component/containerResourceForm.component.tsx} (96%) rename frontend/src/pages/private/workflows/{workflows-editor/components/sidebar-form.component => workflowsEditor/components/sidebarForm.component}/index.tsx (95%) rename frontend/src/pages/private/workflows/{workflows-editor/components/sidebar-form.component/piece-form.component => workflowsEditor/components/sidebarForm.component/pieceForm.component}/index.tsx (92%) rename frontend/src/pages/private/workflows/{workflows-editor/components/sidebar-form.component/piece-form.component/piece-form-item.component/array-input.tsx => workflowsEditor/components/sidebarForm.component/pieceForm.component/pieceFormItem.component/arrayInput.tsx} (95%) rename frontend/src/pages/private/workflows/{workflows-editor/components/sidebar-form.component/piece-form.component/piece-form-item.component => workflowsEditor/components/sidebarForm.component/pieceForm.component/pieceFormItem.component}/disableCheckboxOptions.ts (100%) rename frontend/src/pages/private/workflows/{workflows-editor/components/sidebar-form.component/piece-form.component/piece-form-item.component => workflowsEditor/components/sidebarForm.component/pieceForm.component/pieceFormItem.component}/index.tsx (91%) rename frontend/src/pages/private/workflows/{workflows-editor/components/sidebar-form.component/piece-form.component/piece-form-item.component/object-input.tsx => workflowsEditor/components/sidebarForm.component/pieceForm.component/pieceFormItem.component/objectInput.tsx} (92%) rename frontend/src/pages/private/workflows/{workflows-editor/components/sidebar-form.component/piece-form.component/piece-form-item.component/select-upstream-input.tsx => workflowsEditor/components/sidebarForm.component/pieceForm.component/pieceFormItem.component/selectUpstreamInput.tsx} (97%) rename frontend/src/pages/private/workflows/{workflows-editor/components/sidebar-form.component/piece-form.component/upstream-options.ts => workflowsEditor/components/sidebarForm.component/pieceForm.component/upstreamOptions.ts} (100%) rename frontend/src/pages/private/workflows/{workflows-editor/components/sidebar-form.component/piece-form.component => workflowsEditor/components/sidebarForm.component/pieceForm.component}/validation.ts (100%) rename frontend/src/pages/private/workflows/{workflows-editor/components/sidebar-form.component/storage-form.component.tsx => workflowsEditor/components/sidebarForm.component/storageForm.component.tsx} (100%) rename frontend/src/pages/private/workflows/{workflows-editor/components/sidebar-node.component.tsx => workflowsEditor/components/sidebarNode.component.tsx} (96%) rename frontend/src/pages/private/workflows/{workflows-editor/components/sidebar-settings-form.component.tsx => workflowsEditor/components/sidebarSettingsForm.component.tsx} (97%) rename frontend/src/pages/private/workflows/{workflows-editor/components/workflow-editor-panel.component.tsx => workflowsEditor/components/workflowEditorPanel.component.tsx} (97%) rename frontend/src/pages/private/workflows/{workflows-editor/components/workflows-editor.component.tsx => workflowsEditor/components/workflowsEditor.component.tsx} (92%) rename frontend/src/pages/private/workflows/{workflows-editor/workflows-editor-page.component.tsx => workflowsEditor/workflowsEditorPage.component.tsx} (81%) rename frontend/src/pages/private/workspaces/{workspace-settings/components/repositories-card.component.tsx => workspaceSettings/components/repositoriesCard.component.tsx} (98%) rename frontend/src/pages/private/workspaces/{workspace-settings/components/repository-secrets-card.component.tsx => workspaceSettings/components/repositorySecretsCard.component.tsx} (100%) rename frontend/src/pages/private/workspaces/{workspace-settings/components/storage-secrets-card.component.tsx => workspaceSettings/components/storageSecretsCard.component.tsx} (99%) rename frontend/src/pages/private/workspaces/{workspace-settings/components/users-card.component.tsx => workspaceSettings/components/usersCard.component.tsx} (99%) rename frontend/src/pages/private/workspaces/{workspace-settings/components/workspace-secrets-card.component.tsx => workspaceSettings/components/workspaceSecretsCard.component.tsx} (99%) rename frontend/src/pages/private/workspaces/{workspace-settings/components/workspace-users-card.component.tsx => workspaceSettings/components/workspaceUsersCard.component.tsx} (100%) rename frontend/src/pages/private/workspaces/{workspace-settings/workspace-settings-page.component.tsx => workspaceSettings/workspaceSettingsPage.component.tsx} (83%) rename frontend/src/pages/private/workspaces/workspaces/components/{add-workspace.component.tsx => addWorkspace.component.tsx} (100%) rename frontend/src/pages/private/workspaces/workspaces/components/{pending-item.component.tsx => pendingItem.component.tsx} (100%) rename frontend/src/pages/private/workspaces/workspaces/{workspaces-page.component.tsx => workspacesPage.component.tsx} (97%) rename frontend/src/pages/public/{sign-in/sign-in-page.component.tsx => signIn/signInPage.component.tsx} (98%) rename frontend/src/pages/public/{sign-up/sign-up-page.component.tsx => signUp/signUpPage.component.tsx} (98%) rename frontend/src/services/config/{local-forage.config.ts => localForage.config.ts} (100%) rename frontend/src/services/requests/authentication/{post-auth-login.request.ts => postAuthLogin.request.ts} (100%) rename frontend/src/services/requests/authentication/{post-auth-register.request.ts => postAuthRegister.request.ts} (100%) rename frontend/src/services/requests/piece/{get-operator-repositories.request.ts => getOperatorRepositories.request.ts} (100%) rename frontend/src/services/requests/piece/{get-operators-repositories-releases.request.ts => getOperatorsRepositoriesReleases.request.ts} (100%) rename frontend/src/services/requests/piece/{get-piece-repository-pieces.request.ts => getPieceRepositoryPieces.request.ts} (100%) rename frontend/src/services/requests/repository/{delete-operator-repository.request.ts => deleteOperatorRepository.request.ts} (100%) rename frontend/src/services/requests/repository/{get-operator-repository-secrets.request.ts => getOperatorRepositorySecrets.request.ts} (94%) rename frontend/src/services/requests/repository/{operator-repository.interface.ts => operatorRepository.interface.ts} (100%) rename frontend/src/services/requests/repository/{patch-operator-repository-secret.request.ts => patchOperatorRepositorySecret.request.ts} (100%) rename frontend/src/services/requests/runs/{get-workflow-run-task-logs.request.ts => getWorkflowRunTaskLogs.request.ts} (100%) rename frontend/src/services/requests/runs/{get-workflow-run-task-result.request.ts => getWorkflowRunTaskResult.request.ts} (100%) rename frontend/src/services/requests/runs/{get-workflow-run-tasks.request.ts => getWorkflowRunTasks.request.ts} (100%) rename frontend/src/services/requests/runs/{get-workflow-runs.request.ts => getWorkflowRuns.request.ts} (100%) rename frontend/src/services/requests/workflow/{delete-workflow-id.request.ts => deleteWorkflowId.request.ts} (100%) rename frontend/src/services/requests/workflow/{get-workflow.request.ts => getWorkflow.request.ts} (100%) rename frontend/src/services/requests/workflow/{get-workflow-id.request.ts => getWorkflowId.request.ts} (100%) rename frontend/src/services/requests/workflow/{post-workflow.request.ts => postWorkflow.request.ts} (100%) rename frontend/src/services/requests/workflow/{post-workflow-run-id.request.ts => postWorkflowRunId.request.ts} (100%) rename frontend/src/services/requests/workspaces/{accept-workspace-invite.request.ts => acceptWorkspaceInvite.request.ts} (100%) rename frontend/src/services/requests/workspaces/{delete-user-workspace.request.ts => deleteUserWorkspace.request.ts} (100%) rename frontend/src/services/requests/workspaces/{delete-workspace.request.ts => deleteWorkspace.request.ts} (100%) rename frontend/src/services/requests/workspaces/{get-workspace-id.request.ts => getWorkspaceId.request.ts} (100%) rename frontend/src/services/requests/workspaces/{get-workspace-members.request.ts => getWorkspaceMembers.request.ts} (100%) rename frontend/src/services/requests/workspaces/{get-workspaces.request.ts => getWorkspaces.request.ts} (100%) rename frontend/src/services/requests/workspaces/{invite-workspace.request.ts => inviteWorkspace.request.ts} (100%) rename frontend/src/services/requests/workspaces/{patch-workspace.reques.ts => patchWorkspace.reques.ts} (100%) rename frontend/src/services/requests/workspaces/{post-operators-repositories.request.ts => postOperatorsRepositories.request.ts} (100%) rename frontend/src/services/requests/workspaces/{post-workspaces.request.ts => postWorkspaces.request.ts} (100%) rename frontend/src/services/requests/workspaces/{reject-workspace-invite.request.ts => rejectWorkspaceInvite.request.ts} (100%) rename frontend/src/utils/{create-custom-context.function.ts => createCustomContext.function.ts} (100%) diff --git a/frontend/src/common/hocs/with-context.hoc.tsx b/frontend/src/common/hocs/withContext.hoc.tsx similarity index 100% rename from frontend/src/common/hocs/with-context.hoc.tsx rename to frontend/src/common/hocs/withContext.hoc.tsx diff --git a/frontend/src/common/interfaces/repository-source.enum.ts b/frontend/src/common/interfaces/repositorySource.enum.ts similarity index 100% rename from frontend/src/common/interfaces/repository-source.enum.ts rename to frontend/src/common/interfaces/repositorySource.enum.ts diff --git a/frontend/src/components/checkbox-input.tsx b/frontend/src/components/checkboxInput.tsx similarity index 100% rename from frontend/src/components/checkbox-input.tsx rename to frontend/src/components/checkboxInput.tsx diff --git a/frontend/src/components/codeeditor-input.tsx b/frontend/src/components/codeeditorInput.tsx similarity index 100% rename from frontend/src/components/codeeditor-input.tsx rename to frontend/src/components/codeeditorInput.tsx diff --git a/frontend/src/components/datetime-input.tsx b/frontend/src/components/datetimeInput.tsx similarity index 100% rename from frontend/src/components/datetime-input.tsx rename to frontend/src/components/datetimeInput.tsx diff --git a/frontend/src/components/number-input.tsx b/frontend/src/components/numberInput.tsx similarity index 100% rename from frontend/src/components/number-input.tsx rename to frontend/src/components/numberInput.tsx diff --git a/frontend/src/components/select-input.tsx b/frontend/src/components/selectInput.tsx similarity index 100% rename from frontend/src/components/select-input.tsx rename to frontend/src/components/selectInput.tsx diff --git a/frontend/src/components/text-input.tsx b/frontend/src/components/textInput.tsx similarity index 100% rename from frontend/src/components/text-input.tsx rename to frontend/src/components/textInput.tsx diff --git a/frontend/src/context/workflows/types/container-resources.ts b/frontend/src/context/workflows/types/containerResources.ts similarity index 100% rename from frontend/src/context/workflows/types/container-resources.ts rename to frontend/src/context/workflows/types/containerResources.ts diff --git a/frontend/src/context/workflows/types/index.ts b/frontend/src/context/workflows/types/index.ts index 6ddb5a38..087062d5 100644 --- a/frontend/src/context/workflows/types/index.ts +++ b/frontend/src/context/workflows/types/index.ts @@ -1,4 +1,4 @@ -export * from "./container-resources"; +export * from "./containerResources"; export * from "./storage"; -export * from "./workflow-piece-data"; +export * from "./workflowPieceData"; export * from "./input"; diff --git a/frontend/src/context/workflows/types/workflow-piece-data.ts b/frontend/src/context/workflows/types/workflowPieceData.ts similarity index 95% rename from frontend/src/context/workflows/types/workflow-piece-data.ts rename to frontend/src/context/workflows/types/workflowPieceData.ts index 56136bc5..72b02b85 100644 --- a/frontend/src/context/workflows/types/workflow-piece-data.ts +++ b/frontend/src/context/workflows/types/workflowPieceData.ts @@ -1,7 +1,7 @@ import { type Edge } from "reactflow"; import { type IWorkflowElement } from "services/requests/workflow"; -import { type IContainerResourceFormData } from "./container-resources"; +import { type IContainerResourceFormData } from "./containerResources"; import { type InputArray, type Input } from "./input"; import { type EndDateTypes, diff --git a/frontend/src/context/workflows/workflows-editor.context/index.tsx b/frontend/src/context/workflows/workflowsEditor.context/index.tsx similarity index 92% rename from frontend/src/context/workflows/workflows-editor.context/index.tsx rename to frontend/src/context/workflows/workflowsEditor.context/index.tsx index 79103df5..78de53ff 100644 --- a/frontend/src/context/workflows/workflows-editor.context/index.tsx +++ b/frontend/src/context/workflows/workflowsEditor.context/index.tsx @@ -13,23 +13,23 @@ import { usesPieces, type IPiecesContext } from "./pieces.context"; import { useWorkflowsEdges, type IWorkflowsEdgesContext, -} from "./workflow-edges.context"; +} from "./workflowEdges.context"; import { useWorkflowsNodes, type IWorkflowsNodesContext, -} from "./workflow-nodes.context"; -import { - useWorkflowPiecesData, - type IWorkflowPiecesDataContext, -} from "./workflow-pieces-data.context"; +} from "./workflowNodes.context"; import { useWorkflowPiece, type IWorkflowPieceContext, -} from "./workflow-pieces.context"; +} from "./workflowPieces.context"; +import { + useWorkflowPiecesData, + type IWorkflowPiecesDataContext, +} from "./workflowPiecesData.context"; import { type IWorkflowSettingsContext, useWorkflowSettings, -} from "./workflow-settings-data.context"; +} from "./workflowSettingsData.context"; interface IWorkflowsEditorContext extends IPiecesContext, @@ -155,17 +155,22 @@ export const WorkflowsEditorProvider: FC<{ children?: React.ReactNode }> = ({ ui_schema.nodes[taskName] = element; - const dependencies = workflowEdges.reduce((acc, edge) => { - if (edge.target === element.id) { - const task = workflowNodes.find((n) => n.id === edge.source); - if (task) { - const upTaskName = generateTaskName(task.data.name, task.id); - acc.push(upTaskName); + const dependencies = workflowEdges.reduce( + (acc: string[], edge: { target: any; source: any }) => { + if (edge.target === element.id) { + const task = workflowNodes.find( + (n: { id: any }) => n.id === edge.source, + ); + if (task) { + const upTaskName = generateTaskName(task.data.name, task.id); + acc.push(upTaskName); + } } - } - return acc; - }, []); + return acc; + }, + [], + ); const { storageSource, baseFolder, ...providerOptions } = workflowSettingsData.storage || {}; diff --git a/frontend/src/context/workflows/workflows-editor.context/pieces.context.tsx b/frontend/src/context/workflows/workflowsEditor.context/pieces.context.tsx similarity index 96% rename from frontend/src/context/workflows/workflows-editor.context/pieces.context.tsx rename to frontend/src/context/workflows/workflowsEditor.context/pieces.context.tsx index 2b8e9253..0396562f 100644 --- a/frontend/src/context/workflows/workflows-editor.context/pieces.context.tsx +++ b/frontend/src/context/workflows/workflowsEditor.context/pieces.context.tsx @@ -1,6 +1,6 @@ import React, { useCallback, useEffect, useMemo, useState } from "react"; import { toast } from "react-toastify"; -import localForage from "services/config/local-forage.config"; +import localForage from "services/config/localForage.config"; import { type IGetRepoOperatorsResponseInterface, type IOperator, @@ -9,7 +9,7 @@ import { type IRepositoryOperators, useAuthenticatedGetOperatorRepositories, } from "services/requests/piece"; -import { useFetchAuthenticatedGetRepoIdOperators } from "services/requests/piece/get-piece-repository-pieces.request"; +import { useFetchAuthenticatedGetRepoIdOperators } from "services/requests/piece/getPieceRepositoryPieces.request"; import { createCustomContext } from "utils"; export interface IPiecesContext { diff --git a/frontend/src/context/workflows/workflows-editor.context/provider-context-wrapper.tsx b/frontend/src/context/workflows/workflowsEditor.context/providerContextWrapper.tsx similarity index 65% rename from frontend/src/context/workflows/workflows-editor.context/provider-context-wrapper.tsx rename to frontend/src/context/workflows/workflowsEditor.context/providerContextWrapper.tsx index 1e866f94..671a65f1 100644 --- a/frontend/src/context/workflows/workflows-editor.context/provider-context-wrapper.tsx +++ b/frontend/src/context/workflows/workflowsEditor.context/providerContextWrapper.tsx @@ -1,9 +1,9 @@ import PiecesProvider from "./pieces.context"; -import WorkflowsEdgesProvider from "./workflow-edges.context"; -import WorkflowsNodesProvider from "./workflow-nodes.context"; -import WorkflowPiecesDataProvider from "./workflow-pieces-data.context"; -import WorkflowPiecesProvider from "./workflow-pieces.context"; -import WorkflowSettingsDataProvider from "./workflow-settings-data.context"; +import WorkflowsEdgesProvider from "./workflowEdges.context"; +import WorkflowsNodesProvider from "./workflowNodes.context"; +import WorkflowPiecesProvider from "./workflowPieces.context"; +import WorkflowPiecesDataProvider from "./workflowPiecesData.context"; +import WorkflowSettingsDataProvider from "./workflowSettingsData.context"; const ProviderContextWrapper: React.FC<{ children: React.ReactNode }> = ({ children, diff --git a/frontend/src/context/workflows/workflows-editor.context/workflow-edges.context.tsx b/frontend/src/context/workflows/workflowsEditor.context/workflowEdges.context.tsx similarity index 96% rename from frontend/src/context/workflows/workflows-editor.context/workflow-edges.context.tsx rename to frontend/src/context/workflows/workflowsEditor.context/workflowEdges.context.tsx index 49640d68..19ea543d 100644 --- a/frontend/src/context/workflows/workflows-editor.context/workflow-edges.context.tsx +++ b/frontend/src/context/workflows/workflowsEditor.context/workflowEdges.context.tsx @@ -1,6 +1,6 @@ import React, { useCallback, useEffect, useState } from "react"; import { type Edge } from "reactflow"; -import localForage from "services/config/local-forage.config"; +import localForage from "services/config/localForage.config"; import { createCustomContext } from "utils"; export interface IWorkflowsEdgesContext { diff --git a/frontend/src/context/workflows/workflows-editor.context/workflow-nodes.context.tsx b/frontend/src/context/workflows/workflowsEditor.context/workflowNodes.context.tsx similarity index 97% rename from frontend/src/context/workflows/workflows-editor.context/workflow-nodes.context.tsx rename to frontend/src/context/workflows/workflowsEditor.context/workflowNodes.context.tsx index be6603ef..e7e6e7d3 100644 --- a/frontend/src/context/workflows/workflows-editor.context/workflow-nodes.context.tsx +++ b/frontend/src/context/workflows/workflowsEditor.context/workflowNodes.context.tsx @@ -1,6 +1,6 @@ import React, { useCallback, useEffect, useState } from "react"; import { type Node } from "reactflow"; -import localForage from "services/config/local-forage.config"; +import localForage from "services/config/localForage.config"; import { type IWorkflowElement } from "services/requests/workflow"; import { createCustomContext } from "utils"; diff --git a/frontend/src/context/workflows/workflows-editor.context/workflow-pieces.context.tsx b/frontend/src/context/workflows/workflowsEditor.context/workflowPieces.context.tsx similarity index 97% rename from frontend/src/context/workflows/workflows-editor.context/workflow-pieces.context.tsx rename to frontend/src/context/workflows/workflowsEditor.context/workflowPieces.context.tsx index 3600b2b9..20cca559 100644 --- a/frontend/src/context/workflows/workflows-editor.context/workflow-pieces.context.tsx +++ b/frontend/src/context/workflows/workflowsEditor.context/workflowPieces.context.tsx @@ -1,5 +1,5 @@ import React, { useCallback } from "react"; -import localForage from "services/config/local-forage.config"; +import localForage from "services/config/localForage.config"; import { type IOperator } from "services/requests/piece"; import { createCustomContext } from "utils"; diff --git a/frontend/src/context/workflows/workflows-editor.context/workflow-pieces-data.context.tsx b/frontend/src/context/workflows/workflowsEditor.context/workflowPiecesData.context.tsx similarity index 98% rename from frontend/src/context/workflows/workflows-editor.context/workflow-pieces-data.context.tsx rename to frontend/src/context/workflows/workflowsEditor.context/workflowPiecesData.context.tsx index c3c8f258..76125912 100644 --- a/frontend/src/context/workflows/workflows-editor.context/workflow-pieces-data.context.tsx +++ b/frontend/src/context/workflows/workflowsEditor.context/workflowPiecesData.context.tsx @@ -1,5 +1,5 @@ import React, { useCallback } from "react"; -import localForage from "services/config/local-forage.config"; +import localForage from "services/config/localForage.config"; import { createCustomContext, getUuid } from "utils"; import { type IWorkflowPieceData } from "../types"; diff --git a/frontend/src/context/workflows/workflows-editor.context/workflow-settings-data.context.tsx b/frontend/src/context/workflows/workflowsEditor.context/workflowSettingsData.context.tsx similarity index 95% rename from frontend/src/context/workflows/workflows-editor.context/workflow-settings-data.context.tsx rename to frontend/src/context/workflows/workflowsEditor.context/workflowSettingsData.context.tsx index 9d6a4f00..5e2e40b4 100644 --- a/frontend/src/context/workflows/workflows-editor.context/workflow-settings-data.context.tsx +++ b/frontend/src/context/workflows/workflowsEditor.context/workflowSettingsData.context.tsx @@ -1,5 +1,5 @@ import React, { useCallback } from "react"; -import localForage from "services/config/local-forage.config"; +import localForage from "services/config/localForage.config"; import { createCustomContext } from "utils"; import { type IWorkflowSettings } from "../types/settings"; diff --git a/frontend/src/context/workspaces/workspace-settings.context.tsx b/frontend/src/context/workspaces/workspaceSettings.context.tsx similarity index 98% rename from frontend/src/context/workspaces/workspace-settings.context.tsx rename to frontend/src/context/workspaces/workspaceSettings.context.tsx index 85c6e341..83e03871 100644 --- a/frontend/src/context/workspaces/workspace-settings.context.tsx +++ b/frontend/src/context/workspaces/workspaceSettings.context.tsx @@ -6,7 +6,7 @@ import { type IOperatorRepository, useAuthenticatedGetOperatorRepositories, } from "services/requests/piece"; -import { useAuthenticatedGetOperatorRepositoriesReleases } from "services/requests/piece/get-operators-repositories-releases.request"; +import { useAuthenticatedGetOperatorRepositoriesReleases } from "services/requests/piece/getOperatorsRepositoriesReleases.request"; import { useAuthenticatedDeleteRepository } from "services/requests/repository"; import { type IPostWorkspaceRepositoryPayload, diff --git a/frontend/src/modules/app/app.component.tsx b/frontend/src/modules/app/app.component.tsx index 65845cf9..8bf63708 100644 --- a/frontend/src/modules/app/app.component.tsx +++ b/frontend/src/modules/app/app.component.tsx @@ -9,7 +9,7 @@ import { ToastContainer } from "react-toastify"; import "react-toastify/dist/ReactToastify.css"; import { SWRConfig } from "swr"; -import ApplicationRoutes from "./router/application-routes.component"; +import ApplicationRoutes from "./router/applicationRoutes.component"; import { theme } from "./theme.config"; import "ag-grid-community/dist/styles/ag-grid.css"; diff --git a/frontend/src/modules/app/router/application-routes.component.tsx b/frontend/src/modules/app/router/applicationRoutes.component.tsx similarity index 87% rename from frontend/src/modules/app/router/application-routes.component.tsx rename to frontend/src/modules/app/router/applicationRoutes.component.tsx index 694d0a29..4bbf1954 100644 --- a/frontend/src/modules/app/router/application-routes.component.tsx +++ b/frontend/src/modules/app/router/applicationRoutes.component.tsx @@ -3,13 +3,13 @@ import { WorkspacesPage, WorkspaceSettingsPage, } from "pages/private/workspaces"; -import SignInPage from "pages/public/sign-in/sign-in-page.component"; -import SignUpPage from "pages/public/sign-up/sign-up-page.component"; +import SignInPage from "pages/public/signIn/signInPage.component"; +import SignUpPage from "pages/public/signUp/signUpPage.component"; import { type FC } from "react"; import { Navigate, Route, Routes } from "react-router-dom"; -import { PrivateRoute } from "./private-route.component"; -import { PublicRoute } from "./public-route.component"; +import { PrivateRoute } from "./privateRoute.component"; +import { PublicRoute } from "./publicRoute.component"; /** * Application router diff --git a/frontend/src/modules/app/router/private-route.component.tsx b/frontend/src/modules/app/router/privateRoute.component.tsx similarity index 100% rename from frontend/src/modules/app/router/private-route.component.tsx rename to frontend/src/modules/app/router/privateRoute.component.tsx diff --git a/frontend/src/modules/app/router/public-route.component.tsx b/frontend/src/modules/app/router/publicRoute.component.tsx similarity index 100% rename from frontend/src/modules/app/router/public-route.component.tsx rename to frontend/src/modules/app/router/publicRoute.component.tsx diff --git a/frontend/src/modules/layout/index.ts b/frontend/src/modules/layout/index.ts index 7045f5cd..7c12987f 100644 --- a/frontend/src/modules/layout/index.ts +++ b/frontend/src/modules/layout/index.ts @@ -1,2 +1,2 @@ -export * from "./private-layout/private-layout.component"; -export * from "./public-layout/public-layout.component"; +export * from "./privateLayout/privateLayout.component"; +export * from "./publicLayout/publicLayout.component"; diff --git a/frontend/src/modules/layout/private-layout/header/drawer-menu.component.tsx b/frontend/src/modules/layout/privateLayout/header/drawerMenu.component.tsx similarity index 97% rename from frontend/src/modules/layout/private-layout/header/drawer-menu.component.tsx rename to frontend/src/modules/layout/privateLayout/header/drawerMenu.component.tsx index bab41a98..64cf625d 100644 --- a/frontend/src/modules/layout/private-layout/header/drawer-menu.component.tsx +++ b/frontend/src/modules/layout/privateLayout/header/drawerMenu.component.tsx @@ -22,8 +22,8 @@ import { useWorkspaces } from "context/workspaces/workspaces.context"; import { type FC } from "react"; import { useLocation, useNavigate } from "react-router-dom"; -import { DrawerMenuItem } from "./drawer-menu-item.component"; -import { AppBar, Drawer, DrawerHeader } from "./drawer-menu.style"; +import { AppBar, Drawer, DrawerHeader } from "./drawerMenu.style"; +import { DrawerMenuItem } from "./drawerMenuItem.component"; interface IDrawerMenuProps { isOpen: boolean; diff --git a/frontend/src/modules/layout/private-layout/header/drawer-menu.style.ts b/frontend/src/modules/layout/privateLayout/header/drawerMenu.style.ts similarity index 100% rename from frontend/src/modules/layout/private-layout/header/drawer-menu.style.ts rename to frontend/src/modules/layout/privateLayout/header/drawerMenu.style.ts diff --git a/frontend/src/modules/layout/private-layout/header/drawer-menu-item.component.tsx b/frontend/src/modules/layout/privateLayout/header/drawerMenuItem.component.tsx similarity index 100% rename from frontend/src/modules/layout/private-layout/header/drawer-menu-item.component.tsx rename to frontend/src/modules/layout/privateLayout/header/drawerMenuItem.component.tsx diff --git a/frontend/src/modules/layout/private-layout/header/header.component.tsx b/frontend/src/modules/layout/privateLayout/header/header.component.tsx similarity index 89% rename from frontend/src/modules/layout/private-layout/header/header.component.tsx rename to frontend/src/modules/layout/privateLayout/header/header.component.tsx index 125072cc..481255a7 100644 --- a/frontend/src/modules/layout/private-layout/header/header.component.tsx +++ b/frontend/src/modules/layout/privateLayout/header/header.component.tsx @@ -1,7 +1,7 @@ import { Box } from "@mui/material"; import { type FC, useRef, useState } from "react"; -import { DrawerMenu } from "./drawer-menu.component"; +import { DrawerMenu } from "./drawerMenu.component"; export const Header: FC = () => { const [menuOpen, setMenuOpen] = useState(false); diff --git a/frontend/src/modules/layout/private-layout/private-layout.component.tsx b/frontend/src/modules/layout/privateLayout/privateLayout.component.tsx similarity index 100% rename from frontend/src/modules/layout/private-layout/private-layout.component.tsx rename to frontend/src/modules/layout/privateLayout/privateLayout.component.tsx diff --git a/frontend/src/modules/layout/public-layout/public-layout.component.tsx b/frontend/src/modules/layout/publicLayout/publicLayout.component.tsx similarity index 100% rename from frontend/src/modules/layout/public-layout/public-layout.component.tsx rename to frontend/src/modules/layout/publicLayout/publicLayout.component.tsx diff --git a/frontend/src/pages/private/workflows/index.ts b/frontend/src/pages/private/workflows/index.ts index 04a264b8..1e553c83 100644 --- a/frontend/src/pages/private/workflows/index.ts +++ b/frontend/src/pages/private/workflows/index.ts @@ -1,4 +1,4 @@ -export * from "./workflows/workflows-page.component"; -export * from "./workflows-editor/workflows-editor-page.component"; +export * from "./workflows/workflowsPage.component"; +export * from "./workflowsEditor/workflowsEditorPage.component"; export * from "./workflows/components/workflows.component"; -export * from "./workflows-editor/components/workflows-editor.component"; +export * from "./workflowsEditor/components/workflowsEditor.component"; diff --git a/frontend/src/pages/private/workflows/workflows/components/workflow-task-details.component.tsx b/frontend/src/pages/private/workflows/workflows/components/workflowTaskDetails.component.tsx similarity index 100% rename from frontend/src/pages/private/workflows/workflows/components/workflow-task-details.component.tsx rename to frontend/src/pages/private/workflows/workflows/components/workflowTaskDetails.component.tsx diff --git a/frontend/src/pages/private/workflows/workflows/components/workflow-task-logs.component.tsx b/frontend/src/pages/private/workflows/workflows/components/workflowTaskLogs.component.tsx similarity index 100% rename from frontend/src/pages/private/workflows/workflows/components/workflow-task-logs.component.tsx rename to frontend/src/pages/private/workflows/workflows/components/workflowTaskLogs.component.tsx diff --git a/frontend/src/pages/private/workflows/workflows/components/workflow-task-result.component.tsx b/frontend/src/pages/private/workflows/workflows/components/workflowTaskResult.component.tsx similarity index 100% rename from frontend/src/pages/private/workflows/workflows/components/workflow-task-result.component.tsx rename to frontend/src/pages/private/workflows/workflows/components/workflowTaskResult.component.tsx diff --git a/frontend/src/pages/private/workflows/workflows/components/workflows.component.tsx b/frontend/src/pages/private/workflows/workflows/components/workflows.component.tsx index b8ccf2f8..708f07ca 100644 --- a/frontend/src/pages/private/workflows/workflows/components/workflows.component.tsx +++ b/frontend/src/pages/private/workflows/workflows/components/workflows.component.tsx @@ -2,16 +2,16 @@ import LoopIcon from "@mui/icons-material/Loop"; import NavigateNextIcon from "@mui/icons-material/NavigateNext"; import TabContext from "@mui/lab/TabContext"; import { Button, Grid, Typography, Breadcrumbs, Link } from "@mui/material"; -import { withContext } from "common/hocs/with-context.hoc"; +import { withContext } from "common/hocs/withContext.hoc"; import { useWorkflows, WorkflowsProvider, } from "context/workflows/workflows.context"; import { useState, useMemo } from "react"; -import { WorflowRunTaskFlowchart } from "./workflows-run-tasks-flowchart.component"; -import { WorkflowsRunsTable } from "./workflows-runs-table.component"; -import { WorkflowsTable } from "./workflows-table.component"; +import { WorkflowsRunsTable } from "./workflowsRunsTable.component"; +import { WorflowRunTaskFlowchart } from "./workflowsRunTasksFlowchart.component"; +import { WorkflowsTable } from "./workflowsTable.component"; // Icons /** @@ -31,7 +31,8 @@ export const WorkflowsComponent = withContext(WorkflowsProvider, () => { let executionDate = null; if (workflowRuns.data && selectedWorkflowRunId) { executionDate = workflowRuns?.data?.find( - (run) => run.workflow_run_id === selectedWorkflowRunId, + (run: { workflow_run_id: any }) => + run.workflow_run_id === selectedWorkflowRunId, )?.execution_date; executionDate = executionDate ? new Date(executionDate).toLocaleString() diff --git a/frontend/src/pages/private/workflows/workflows/components/workflows-run-tasks-flowchart.component.tsx b/frontend/src/pages/private/workflows/workflows/components/workflowsRunTasksFlowchart.component.tsx similarity index 97% rename from frontend/src/pages/private/workflows/workflows/components/workflows-run-tasks-flowchart.component.tsx rename to frontend/src/pages/private/workflows/workflows/components/workflowsRunTasksFlowchart.component.tsx index 6236057f..413bbc87 100644 --- a/frontend/src/pages/private/workflows/workflows/components/workflows-run-tasks-flowchart.component.tsx +++ b/frontend/src/pages/private/workflows/workflows/components/workflowsRunTasksFlowchart.component.tsx @@ -7,11 +7,11 @@ import ReactFlow, { Background, Controls, ReactFlowProvider } from "reactflow"; import "reactflow/dist/style.css"; import { taskStatesColorMap } from "../../../../../constants"; -import CustomNode from "../../workflows-editor/components/custom-node.component"; // todo move to shared +import CustomNode from "../../workflowsEditor/components/customNode.component"; // todo move to shared -import { TaskDetails } from "./workflow-task-details.component"; -import { TaskLogs } from "./workflow-task-logs.component"; -import { TaskResult } from "./workflow-task-result.component"; +import { TaskDetails } from "./workflowTaskDetails.component"; +import { TaskLogs } from "./workflowTaskLogs.component"; +import { TaskResult } from "./workflowTaskResult.component"; const nodeTypes = { CustomNode, diff --git a/frontend/src/pages/private/workflows/workflows/components/workflows-runs-table.component.tsx b/frontend/src/pages/private/workflows/workflows/components/workflowsRunsTable.component.tsx similarity index 92% rename from frontend/src/pages/private/workflows/workflows/components/workflows-runs-table.component.tsx rename to frontend/src/pages/private/workflows/workflows/components/workflowsRunsTable.component.tsx index 4300d790..b04dc6b1 100644 --- a/frontend/src/pages/private/workflows/workflows/components/workflows-runs-table.component.tsx +++ b/frontend/src/pages/private/workflows/workflows/components/workflowsRunsTable.component.tsx @@ -147,15 +147,23 @@ export const WorkflowsRunsTable = () => { const { rowsData, totalRows } = useMemo(() => { const rowsData = Array.isArray(workflowRuns.data) - ? workflowRuns.data.map((run) => { - return { - id: run.workflow_run_id, - startDate: run.start_date, - endDate: run.end_date, - executionDate: run.execution_date, - state: run.state, - }; - }) + ? workflowRuns.data.map( + (run: { + workflow_run_id: any; + start_date: any; + end_date: any; + execution_date: any; + state: any; + }) => { + return { + id: run.workflow_run_id, + startDate: run.start_date, + endDate: run.end_date, + executionDate: run.execution_date, + state: run.state, + }; + }, + ) : []; const totalRows = workflowRuns.metadata?.total ?? 0; return { rowsData, totalRows }; diff --git a/frontend/src/pages/private/workflows/workflows/components/workflows-table.component.tsx b/frontend/src/pages/private/workflows/workflows/components/workflowsTable.component.tsx similarity index 100% rename from frontend/src/pages/private/workflows/workflows/components/workflows-table.component.tsx rename to frontend/src/pages/private/workflows/workflows/components/workflowsTable.component.tsx diff --git a/frontend/src/pages/private/workflows/workflows/workflows-page.component.tsx b/frontend/src/pages/private/workflows/workflows/workflowsPage.component.tsx similarity index 100% rename from frontend/src/pages/private/workflows/workflows/workflows-page.component.tsx rename to frontend/src/pages/private/workflows/workflows/workflowsPage.component.tsx diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/custom-node.component.tsx b/frontend/src/pages/private/workflows/workflowsEditor/components/customNode.component.tsx similarity index 100% rename from frontend/src/pages/private/workflows/workflows-editor/components/custom-node.component.tsx rename to frontend/src/pages/private/workflows/workflowsEditor/components/customNode.component.tsx diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/drawer-menu-component.tsx b/frontend/src/pages/private/workflows/workflowsEditor/components/drawerMenuComponent.tsx similarity index 93% rename from frontend/src/pages/private/workflows/workflows-editor/components/drawer-menu-component.tsx rename to frontend/src/pages/private/workflows/workflowsEditor/components/drawerMenuComponent.tsx index fcf3bc2f..52658a0e 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/components/drawer-menu-component.tsx +++ b/frontend/src/pages/private/workflows/workflowsEditor/components/drawerMenuComponent.tsx @@ -14,10 +14,10 @@ import { import { Drawer, DrawerHeader, -} from "modules/layout/private-layout/header/drawer-menu.style"; +} from "modules/layout/privateLayout/header/drawerMenu.style"; import { type FC, type ReactNode, useState } from "react"; -import SidebarAddNode from "./sidebar-add-node.component"; +import SidebarAddNode from "./sidebarAddNode.component"; interface PermanentDrawerRightWorkflowsProps { isOpen?: boolean; diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/piece-docs-popover.component.tsx b/frontend/src/pages/private/workflows/workflowsEditor/components/pieceDocsPopover.component.tsx similarity index 100% rename from frontend/src/pages/private/workflows/workflows-editor/components/piece-docs-popover.component.tsx rename to frontend/src/pages/private/workflows/workflowsEditor/components/pieceDocsPopover.component.tsx diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-add-node.component.tsx b/frontend/src/pages/private/workflows/workflowsEditor/components/sidebarAddNode.component.tsx similarity index 97% rename from frontend/src/pages/private/workflows/workflows-editor/components/sidebar-add-node.component.tsx rename to frontend/src/pages/private/workflows/workflowsEditor/components/sidebarAddNode.component.tsx index 1e268b76..ec3972dd 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-add-node.component.tsx +++ b/frontend/src/pages/private/workflows/workflowsEditor/components/sidebarAddNode.component.tsx @@ -9,11 +9,11 @@ import { ToggleButtonGroup, Typography, } from "@mui/material"; -import { useWorkflowsEditor } from "context/workflows/workflows-editor.context"; +import { useWorkflowsEditor } from "context/workflows/workflowsEditor.context"; import { type FC, type SyntheticEvent, useState } from "react"; import { type IOperator } from "services/requests/piece"; -import PiecesSidebarNode from "./sidebar-node.component"; +import PiecesSidebarNode from "./sidebarNode.component"; /** * @todo cleanup comments when no longer needed diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component/container-resource-form.component.tsx b/frontend/src/pages/private/workflows/workflowsEditor/components/sidebarForm.component/containerResourceForm.component.tsx similarity index 96% rename from frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component/container-resource-form.component.tsx rename to frontend/src/pages/private/workflows/workflowsEditor/components/sidebarForm.component/containerResourceForm.component.tsx index d0c4d6e9..7ab7f33b 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component/container-resource-form.component.tsx +++ b/frontend/src/pages/private/workflows/workflowsEditor/components/sidebarForm.component/containerResourceForm.component.tsx @@ -1,6 +1,6 @@ import { Grid, Typography } from "@mui/material"; -import CheckboxInput from "components/checkbox-input"; -import NumberInput from "components/number-input"; +import CheckboxInput from "components/checkboxInput"; +import NumberInput from "components/numberInput"; import { type IContainerResourceFormData } from "context/workflows/types"; import React from "react"; import * as yup from "yup"; diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component/index.tsx b/frontend/src/pages/private/workflows/workflowsEditor/components/sidebarForm.component/index.tsx similarity index 95% rename from frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component/index.tsx rename to frontend/src/pages/private/workflows/workflowsEditor/components/sidebarForm.component/index.tsx index 755c7263..b32fb221 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component/index.tsx +++ b/frontend/src/pages/private/workflows/workflowsEditor/components/sidebarForm.component/index.tsx @@ -8,7 +8,7 @@ import { AccordionDetails, } from "@mui/material"; import { type IWorkflowPieceData } from "context/workflows/types"; -import { useWorkflowsEditor } from "context/workflows/workflows-editor.context"; +import { useWorkflowsEditor } from "context/workflows/workflowsEditor.context"; import React, { useCallback, useEffect, useMemo, useState } from "react"; import { FormProvider, useForm } from "react-hook-form"; import { yupResolver } from "utils"; @@ -16,10 +16,10 @@ import * as yup from "yup"; import ContainerResourceForm, { ContainerResourceFormSchema, -} from "./container-resource-form.component"; -import PieceForm from "./piece-form.component"; -import { createInputsSchemaValidation } from "./piece-form.component/validation"; -import StorageForm, { storageFormSchema } from "./storage-form.component"; +} from "./containerResourceForm.component"; +import PieceForm from "./pieceForm.component"; +import { createInputsSchemaValidation } from "./pieceForm.component/validation"; +import StorageForm, { storageFormSchema } from "./storageForm.component"; interface ISidebarPieceFormProps { formId: string; diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component/piece-form.component/index.tsx b/frontend/src/pages/private/workflows/workflowsEditor/components/sidebarForm.component/pieceForm.component/index.tsx similarity index 92% rename from frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component/piece-form.component/index.tsx rename to frontend/src/pages/private/workflows/workflowsEditor/components/sidebarForm.component/pieceForm.component/index.tsx index 1020598d..deae3677 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component/piece-form.component/index.tsx +++ b/frontend/src/pages/private/workflows/workflowsEditor/components/sidebarForm.component/pieceForm.component/index.tsx @@ -1,10 +1,10 @@ import { type IWorkflowPieceData } from "context/workflows/types"; -import { useWorkflowsEditor } from "context/workflows/workflows-editor.context"; +import { useWorkflowsEditor } from "context/workflows/workflowsEditor.context"; import React, { useCallback, useEffect, useMemo, useState } from "react"; import { useFormContext } from "react-hook-form"; -import PieceFormItem from "./piece-form-item.component"; -import { type UpstreamOptions, getUpstreamOptions } from "./upstream-options"; +import PieceFormItem from "./pieceFormItem.component"; +import { type UpstreamOptions, getUpstreamOptions } from "./upstreamOptions"; interface PieceFormProps { formId: string; diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component/piece-form.component/piece-form-item.component/array-input.tsx b/frontend/src/pages/private/workflows/workflowsEditor/components/sidebarForm.component/pieceForm.component/pieceFormItem.component/arrayInput.tsx similarity index 95% rename from frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component/piece-form.component/piece-form-item.component/array-input.tsx rename to frontend/src/pages/private/workflows/workflowsEditor/components/sidebarForm.component/pieceForm.component/pieceFormItem.component/arrayInput.tsx index 333995ff..0f30b442 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component/piece-form.component/piece-form-item.component/array-input.tsx +++ b/frontend/src/pages/private/workflows/workflowsEditor/components/sidebarForm.component/pieceForm.component/pieceFormItem.component/arrayInput.tsx @@ -1,12 +1,12 @@ import AddIcon from "@mui/icons-material/Add"; import DeleteIcon from "@mui/icons-material/Delete"; import { Card, CardContent, IconButton, Grid } from "@mui/material"; -import CheckboxInput from "components/checkbox-input"; -import CodeEditorInput from "components/codeeditor-input"; -import DatetimeInput from "components/datetime-input"; -import NumberInput from "components/number-input"; -import SelectInput from "components/select-input"; -import TextInput from "components/text-input"; +import CheckboxInput from "components/checkboxInput"; +import CodeEditorInput from "components/codeeditorInput"; +import DatetimeInput from "components/datetimeInput"; +import NumberInput from "components/numberInput"; +import SelectInput from "components/selectInput"; +import TextInput from "components/textInput"; import { type IWorkflowPieceData, type InputArray, @@ -20,11 +20,11 @@ import { } from "react-hook-form"; import { getFromUpstream } from "utils"; -import { type ArrayOption } from "../../piece-form.component/upstream-options"; +import { type ArrayOption } from "../../pieceForm.component/upstreamOptions"; import { disableCheckboxOptions } from "./disableCheckboxOptions"; -import ObjectInputComponent from "./object-input"; -import SelectUpstreamInput from "./select-upstream-input"; +import ObjectInputComponent from "./objectInput"; +import SelectUpstreamInput from "./selectUpstreamInput"; interface ArrayInputItemProps { formId: string; diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component/piece-form.component/piece-form-item.component/disableCheckboxOptions.ts b/frontend/src/pages/private/workflows/workflowsEditor/components/sidebarForm.component/pieceForm.component/pieceFormItem.component/disableCheckboxOptions.ts similarity index 100% rename from frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component/piece-form.component/piece-form-item.component/disableCheckboxOptions.ts rename to frontend/src/pages/private/workflows/workflowsEditor/components/sidebarForm.component/pieceForm.component/pieceFormItem.component/disableCheckboxOptions.ts diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component/piece-form.component/piece-form-item.component/index.tsx b/frontend/src/pages/private/workflows/workflowsEditor/components/sidebarForm.component/pieceForm.component/pieceFormItem.component/index.tsx similarity index 91% rename from frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component/piece-form.component/piece-form-item.component/index.tsx rename to frontend/src/pages/private/workflows/workflowsEditor/components/sidebarForm.component/pieceForm.component/pieceFormItem.component/index.tsx index 2e3fa493..1a0f2bc2 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component/piece-form.component/piece-form-item.component/index.tsx +++ b/frontend/src/pages/private/workflows/workflowsEditor/components/sidebarForm.component/pieceForm.component/pieceFormItem.component/index.tsx @@ -1,10 +1,10 @@ import { Box, Grid } from "@mui/material"; -import CheckboxInput from "components/checkbox-input"; -import CodeEditorInput from "components/codeeditor-input"; -import DatetimeInput from "components/datetime-input"; -import NumberInput from "components/number-input"; -import SelectInput from "components/select-input"; -import TextInput from "components/text-input"; +import CheckboxInput from "components/checkboxInput"; +import CodeEditorInput from "components/codeeditorInput"; +import DatetimeInput from "components/datetimeInput"; +import NumberInput from "components/numberInput"; +import SelectInput from "components/selectInput"; +import TextInput from "components/textInput"; import { type IWorkflowPieceData } from "context/workflows/types"; import React, { useMemo } from "react"; import { type Control, useWatch } from "react-hook-form"; @@ -12,11 +12,11 @@ import { type Control, useWatch } from "react-hook-form"; import { type ArrayOption, type Option, -} from "../../piece-form.component/upstream-options"; +} from "../../pieceForm.component/upstreamOptions"; -import ArrayInput from "./array-input"; +import ArrayInput from "./arrayInput"; import { disableCheckboxOptions } from "./disableCheckboxOptions"; -import SelectUpstreamInput from "./select-upstream-input"; +import SelectUpstreamInput from "./selectUpstreamInput"; interface PieceFormItemProps { formId: string; diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component/piece-form.component/piece-form-item.component/object-input.tsx b/frontend/src/pages/private/workflows/workflowsEditor/components/sidebarForm.component/pieceForm.component/pieceFormItem.component/objectInput.tsx similarity index 92% rename from frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component/piece-form.component/piece-form-item.component/object-input.tsx rename to frontend/src/pages/private/workflows/workflowsEditor/components/sidebarForm.component/pieceForm.component/pieceFormItem.component/objectInput.tsx index 8a9f3e17..766d723c 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component/piece-form.component/piece-form-item.component/object-input.tsx +++ b/frontend/src/pages/private/workflows/workflowsEditor/components/sidebarForm.component/pieceForm.component/pieceFormItem.component/objectInput.tsx @@ -1,15 +1,15 @@ import { Grid } from "@mui/material"; -import CheckboxInput from "components/checkbox-input"; -import SelectInput from "components/select-input"; -import TextInput from "components/text-input"; +import CheckboxInput from "components/checkboxInput"; +import SelectInput from "components/selectInput"; +import TextInput from "components/textInput"; import React, { useCallback, useMemo, useState } from "react"; import { useWatch } from "react-hook-form"; import { getDefinition } from "utils"; -import { type Option } from "../../piece-form.component/upstream-options"; +import { type Option } from "../../pieceForm.component/upstreamOptions"; import { disableCheckboxOptions } from "./disableCheckboxOptions"; -import SelectUpstreamInput from "./select-upstream-input"; +import SelectUpstreamInput from "./selectUpstreamInput"; interface Prop { name: `inputs.${string}.value.${number}`; diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component/piece-form.component/piece-form-item.component/select-upstream-input.tsx b/frontend/src/pages/private/workflows/workflowsEditor/components/sidebarForm.component/pieceForm.component/pieceFormItem.component/selectUpstreamInput.tsx similarity index 97% rename from frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component/piece-form.component/piece-form-item.component/select-upstream-input.tsx rename to frontend/src/pages/private/workflows/workflowsEditor/components/sidebarForm.component/pieceForm.component/pieceFormItem.component/selectUpstreamInput.tsx index e1a62bb3..8eae5049 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component/piece-form.component/piece-form-item.component/select-upstream-input.tsx +++ b/frontend/src/pages/private/workflows/workflowsEditor/components/sidebarForm.component/pieceForm.component/pieceFormItem.component/selectUpstreamInput.tsx @@ -11,7 +11,7 @@ import React, { useCallback } from "react"; import { Controller, useFormContext } from "react-hook-form"; import { fetchFromObject } from "utils"; -import { type Option } from "../../piece-form.component/upstream-options"; +import { type Option } from "../../pieceForm.component/upstreamOptions"; type ObjectName = `inputs.${string}.value.${number}.upstreamValue.${string}`; type Name = `inputs.${string}`; diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component/piece-form.component/upstream-options.ts b/frontend/src/pages/private/workflows/workflowsEditor/components/sidebarForm.component/pieceForm.component/upstreamOptions.ts similarity index 100% rename from frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component/piece-form.component/upstream-options.ts rename to frontend/src/pages/private/workflows/workflowsEditor/components/sidebarForm.component/pieceForm.component/upstreamOptions.ts diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component/piece-form.component/validation.ts b/frontend/src/pages/private/workflows/workflowsEditor/components/sidebarForm.component/pieceForm.component/validation.ts similarity index 100% rename from frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component/piece-form.component/validation.ts rename to frontend/src/pages/private/workflows/workflowsEditor/components/sidebarForm.component/pieceForm.component/validation.ts diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component/storage-form.component.tsx b/frontend/src/pages/private/workflows/workflowsEditor/components/sidebarForm.component/storageForm.component.tsx similarity index 100% rename from frontend/src/pages/private/workflows/workflows-editor/components/sidebar-form.component/storage-form.component.tsx rename to frontend/src/pages/private/workflows/workflowsEditor/components/sidebarForm.component/storageForm.component.tsx diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-node.component.tsx b/frontend/src/pages/private/workflows/workflowsEditor/components/sidebarNode.component.tsx similarity index 96% rename from frontend/src/pages/private/workflows/workflows-editor/components/sidebar-node.component.tsx rename to frontend/src/pages/private/workflows/workflowsEditor/components/sidebarNode.component.tsx index d9ac327d..fa3fbd61 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-node.component.tsx +++ b/frontend/src/pages/private/workflows/workflowsEditor/components/sidebarNode.component.tsx @@ -3,7 +3,7 @@ import { Box, Typography, IconButton } from "@mui/material"; import React, { type FC, useState } from "react"; import { type IOperator } from "services/requests/piece"; -import PieceDocsPopover from "./piece-docs-popover.component"; +import PieceDocsPopover from "./pieceDocsPopover.component"; const PiecesSidebarNode: FC<{ operator: IOperator }> = ({ operator }) => { const [popoverOpen, setPopoverOpen] = useState(false); diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-settings-form.component.tsx b/frontend/src/pages/private/workflows/workflowsEditor/components/sidebarSettingsForm.component.tsx similarity index 97% rename from frontend/src/pages/private/workflows/workflows-editor/components/sidebar-settings-form.component.tsx rename to frontend/src/pages/private/workflows/workflowsEditor/components/sidebarSettingsForm.component.tsx index 77d052b8..c8098f26 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/components/sidebar-settings-form.component.tsx +++ b/frontend/src/pages/private/workflows/workflowsEditor/components/sidebarSettingsForm.component.tsx @@ -1,7 +1,7 @@ import { Drawer, Grid, Typography, TextField } from "@mui/material"; -import DatetimeInput from "components/datetime-input"; -import SelectInput from "components/select-input"; -import TextInput from "components/text-input"; +import DatetimeInput from "components/datetimeInput"; +import SelectInput from "components/selectInput"; +import TextInput from "components/textInput"; import { type EndDateTypes, type IWorkflowSettings, @@ -13,7 +13,7 @@ import { storageSourcesAWS, storageSourcesLocal, } from "context/workflows/types/settings"; -import { useWorkflowsEditor } from "context/workflows/workflows-editor.context"; +import { useWorkflowsEditor } from "context/workflows/workflowsEditor.context"; import dayjs from "dayjs"; import { useCallback, useEffect, useState } from "react"; import { FormProvider, useForm } from "react-hook-form"; diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/workflow-editor-panel.component.tsx b/frontend/src/pages/private/workflows/workflowsEditor/components/workflowEditorPanel.component.tsx similarity index 97% rename from frontend/src/pages/private/workflows/workflows-editor/components/workflow-editor-panel.component.tsx rename to frontend/src/pages/private/workflows/workflowsEditor/components/workflowEditorPanel.component.tsx index 1fad42ab..d35a5d62 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/components/workflow-editor-panel.component.tsx +++ b/frontend/src/pages/private/workflows/workflowsEditor/components/workflowEditorPanel.component.tsx @@ -3,7 +3,7 @@ import { type IWorkflowPieceData, storageAccessModes, } from "context/workflows/types"; -import { useWorkflowsEditor } from "context/workflows/workflows-editor.context"; +import { useWorkflowsEditor } from "context/workflows/workflowsEditor.context"; import React, { useCallback, useEffect, useRef, useState } from "react"; import ReactFlow, { addEdge, @@ -23,9 +23,9 @@ import ReactFlow, { import { extractDefaultValues, extractDefaultInputValues } from "utils"; import { v4 as uuidv4 } from "uuid"; -import CustomNode from "./custom-node.component"; -import { type INodeData } from "./custom-node.component"; -import SidebarForm from "./sidebar-form.component"; +import CustomNode from "./customNode.component"; +import { type INodeData } from "./customNode.component"; +import SidebarForm from "./sidebarForm.component"; /** * @todo When change the workspace should we clear the forage ? * @todo Solve any types diff --git a/frontend/src/pages/private/workflows/workflows-editor/components/workflows-editor.component.tsx b/frontend/src/pages/private/workflows/workflowsEditor/components/workflowsEditor.component.tsx similarity index 92% rename from frontend/src/pages/private/workflows/workflows-editor/components/workflows-editor.component.tsx rename to frontend/src/pages/private/workflows/workflowsEditor/components/workflowsEditor.component.tsx index 6e8bad01..04127939 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/components/workflows-editor.component.tsx +++ b/frontend/src/pages/private/workflows/workflowsEditor/components/workflowsEditor.component.tsx @@ -4,21 +4,21 @@ import DownloadIcon from "@mui/icons-material/Download"; import SaveIcon from "@mui/icons-material/Save"; import { Button, Grid, Paper, Backdrop, CircularProgress } from "@mui/material"; import { AxiosError } from "axios"; -import { useWorkflowsEditor } from "context/workflows/workflows-editor.context"; +import { useWorkflowsEditor } from "context/workflows/workflowsEditor.context"; import { useWorkspaces } from "context/workspaces/workspaces.context"; import { useCallback, useState } from "react"; import { toast } from "react-toastify"; import { yupResolver } from "utils"; import * as yup from "yup"; -import { PermanentDrawerRightWorkflows } from "./drawer-menu-component"; -import { ContainerResourceFormSchema } from "./sidebar-form.component/container-resource-form.component"; -import { createInputsSchemaValidation } from "./sidebar-form.component/piece-form.component/validation"; -import { storageFormSchema } from "./sidebar-form.component/storage-form.component"; +import { PermanentDrawerRightWorkflows } from "./drawerMenuComponent"; +import { ContainerResourceFormSchema } from "./sidebarForm.component/containerResourceForm.component"; +import { createInputsSchemaValidation } from "./sidebarForm.component/pieceForm.component/validation"; +import { storageFormSchema } from "./sidebarForm.component/storageForm.component"; import SidebarSettingsForm, { WorkflowSettingsFormSchema, -} from "./sidebar-settings-form.component"; -import WorkflowEditorPanelComponent from "./workflow-editor-panel.component"; +} from "./sidebarSettingsForm.component"; +import WorkflowEditorPanelComponent from "./workflowEditorPanel.component"; /** * Create workflow tab // TODO refactor/simplify inner files diff --git a/frontend/src/pages/private/workflows/workflows-editor/workflows-editor-page.component.tsx b/frontend/src/pages/private/workflows/workflowsEditor/workflowsEditorPage.component.tsx similarity index 81% rename from frontend/src/pages/private/workflows/workflows-editor/workflows-editor-page.component.tsx rename to frontend/src/pages/private/workflows/workflowsEditor/workflowsEditorPage.component.tsx index 9bd9b0be..9f52754f 100644 --- a/frontend/src/pages/private/workflows/workflows-editor/workflows-editor-page.component.tsx +++ b/frontend/src/pages/private/workflows/workflowsEditor/workflowsEditorPage.component.tsx @@ -1,9 +1,9 @@ import { Grid } from "@mui/material"; -import { WorkflowsEditorProvider } from "context/workflows/workflows-editor.context"; -import ProviderContextWrapper from "context/workflows/workflows-editor.context/provider-context-wrapper"; +import { WorkflowsEditorProvider } from "context/workflows/workflowsEditor.context"; +import ProviderContextWrapper from "context/workflows/workflowsEditor.context/providerContextWrapper"; import { PrivateLayout } from "modules/layout"; -import { WorkflowsEditorComponent } from "./components/workflows-editor.component"; +import { WorkflowsEditorComponent } from "./components/workflowsEditor.component"; /** * Workflows editor page */ diff --git a/frontend/src/pages/private/workspaces/index.ts b/frontend/src/pages/private/workspaces/index.ts index c362d824..603f7892 100644 --- a/frontend/src/pages/private/workspaces/index.ts +++ b/frontend/src/pages/private/workspaces/index.ts @@ -1,2 +1,2 @@ -export * from "./workspaces/workspaces-page.component"; -export * from "./workspace-settings/workspace-settings-page.component"; +export * from "./workspaces/workspacesPage.component"; +export * from "./workspaceSettings/workspaceSettingsPage.component"; diff --git a/frontend/src/pages/private/workspaces/workspace-settings/components/repositories-card.component.tsx b/frontend/src/pages/private/workspaces/workspaceSettings/components/repositoriesCard.component.tsx similarity index 98% rename from frontend/src/pages/private/workspaces/workspace-settings/components/repositories-card.component.tsx rename to frontend/src/pages/private/workspaces/workspaceSettings/components/repositoriesCard.component.tsx index 2d218866..fb16e806 100644 --- a/frontend/src/pages/private/workspaces/workspace-settings/components/repositories-card.component.tsx +++ b/frontend/src/pages/private/workspaces/workspaceSettings/components/repositoriesCard.component.tsx @@ -28,8 +28,8 @@ import { Tooltip, } from "@mui/material"; import TextField from "@mui/material/TextField"; -import { ERepositorySource } from "common/interfaces/repository-source.enum"; -import { useWorkspaceSettings } from "context/workspaces/workspace-settings.context"; +import { ERepositorySource } from "common/interfaces/repositorySource.enum"; +import { useWorkspaceSettings } from "context/workspaces/workspaceSettings.context"; import { type FC, type ReactNode, useCallback, useMemo, useState } from "react"; import { toast } from "react-toastify"; import { type IOperatorRepositoryMetadata } from "services/requests/piece"; diff --git a/frontend/src/pages/private/workspaces/workspace-settings/components/repository-secrets-card.component.tsx b/frontend/src/pages/private/workspaces/workspaceSettings/components/repositorySecretsCard.component.tsx similarity index 100% rename from frontend/src/pages/private/workspaces/workspace-settings/components/repository-secrets-card.component.tsx rename to frontend/src/pages/private/workspaces/workspaceSettings/components/repositorySecretsCard.component.tsx diff --git a/frontend/src/pages/private/workspaces/workspace-settings/components/storage-secrets-card.component.tsx b/frontend/src/pages/private/workspaces/workspaceSettings/components/storageSecretsCard.component.tsx similarity index 99% rename from frontend/src/pages/private/workspaces/workspace-settings/components/storage-secrets-card.component.tsx rename to frontend/src/pages/private/workspaces/workspaceSettings/components/storageSecretsCard.component.tsx index 75dcf947..9542fcc2 100644 --- a/frontend/src/pages/private/workspaces/workspace-settings/components/storage-secrets-card.component.tsx +++ b/frontend/src/pages/private/workspaces/workspaceSettings/components/storageSecretsCard.component.tsx @@ -15,7 +15,7 @@ import { IconButton, Alert, } from "@mui/material"; -import { useWorkspaceSettings } from "context/workspaces/workspace-settings.context"; +import { useWorkspaceSettings } from "context/workspaces/workspaceSettings.context"; import { useState, useCallback, useMemo, useEffect } from "react"; import { useForm } from "react-hook-form"; import { toast } from "react-toastify"; diff --git a/frontend/src/pages/private/workspaces/workspace-settings/components/users-card.component.tsx b/frontend/src/pages/private/workspaces/workspaceSettings/components/usersCard.component.tsx similarity index 99% rename from frontend/src/pages/private/workspaces/workspace-settings/components/users-card.component.tsx rename to frontend/src/pages/private/workspaces/workspaceSettings/components/usersCard.component.tsx index 7178fada..056036dd 100644 --- a/frontend/src/pages/private/workspaces/workspace-settings/components/users-card.component.tsx +++ b/frontend/src/pages/private/workspaces/workspaceSettings/components/usersCard.component.tsx @@ -13,8 +13,8 @@ import { FormControl, } from "@mui/material"; import TextField from "@mui/material/TextField"; -import { useWorkspaceSettings } from "context/workspaces/workspace-settings.context"; import { useWorkspaces } from "context/workspaces/workspaces.context"; +import { useWorkspaceSettings } from "context/workspaces/workspaceSettings.context"; import { type FC, useCallback, useState } from "react"; import { toast } from "react-toastify"; diff --git a/frontend/src/pages/private/workspaces/workspace-settings/components/workspace-secrets-card.component.tsx b/frontend/src/pages/private/workspaces/workspaceSettings/components/workspaceSecretsCard.component.tsx similarity index 99% rename from frontend/src/pages/private/workspaces/workspace-settings/components/workspace-secrets-card.component.tsx rename to frontend/src/pages/private/workspaces/workspaceSettings/components/workspaceSecretsCard.component.tsx index ae1902b4..f4048309 100644 --- a/frontend/src/pages/private/workspaces/workspace-settings/components/workspace-secrets-card.component.tsx +++ b/frontend/src/pages/private/workspaces/workspaceSettings/components/workspaceSecretsCard.component.tsx @@ -14,8 +14,8 @@ import { Tooltip, IconButton, } from "@mui/material"; -import { useWorkspaceSettings } from "context/workspaces/workspace-settings.context"; import { useWorkspaces } from "context/workspaces/workspaces.context"; +import { useWorkspaceSettings } from "context/workspaces/workspaceSettings.context"; import { useState, useCallback, useEffect } from "react"; import { useForm } from "react-hook-form"; import { toast } from "react-toastify"; diff --git a/frontend/src/pages/private/workspaces/workspace-settings/components/workspace-users-card.component.tsx b/frontend/src/pages/private/workspaces/workspaceSettings/components/workspaceUsersCard.component.tsx similarity index 100% rename from frontend/src/pages/private/workspaces/workspace-settings/components/workspace-users-card.component.tsx rename to frontend/src/pages/private/workspaces/workspaceSettings/components/workspaceUsersCard.component.tsx diff --git a/frontend/src/pages/private/workspaces/workspace-settings/workspace-settings-page.component.tsx b/frontend/src/pages/private/workspaces/workspaceSettings/workspaceSettingsPage.component.tsx similarity index 83% rename from frontend/src/pages/private/workspaces/workspace-settings/workspace-settings-page.component.tsx rename to frontend/src/pages/private/workspaces/workspaceSettings/workspaceSettingsPage.component.tsx index 1a7cad60..84153838 100644 --- a/frontend/src/pages/private/workspaces/workspace-settings/workspace-settings-page.component.tsx +++ b/frontend/src/pages/private/workspaces/workspaceSettings/workspaceSettingsPage.component.tsx @@ -3,20 +3,20 @@ import TabList from "@mui/lab/TabList"; import TabPanel from "@mui/lab/TabPanel"; import { Box, Grid, Typography } from "@mui/material"; import Tab from "@mui/material/Tab"; -import { withContext } from "common/hocs/with-context.hoc"; +import { withContext } from "common/hocs/withContext.hoc"; import { WorkspaceSettingsProvider, useWorkspaceSettings, -} from "context/workspaces/workspace-settings.context"; +} from "context/workspaces/workspaceSettings.context"; import { PrivateLayout } from "modules/layout"; import { useState } from "react"; -import { RepositoriesCard } from "./components/repositories-card.component"; -import SecretsCard from "./components/repository-secrets-card.component"; -import StorageSecretsCard from "./components/storage-secrets-card.component"; -import { UsersCard } from "./components/users-card.component"; -import WorkspaceSecretsCard from "./components/workspace-secrets-card.component"; -import WorkspaceMembersCard from "./components/workspace-users-card.component"; +import { RepositoriesCard } from "./components/repositoriesCard.component"; +import SecretsCard from "./components/repositorySecretsCard.component"; +import StorageSecretsCard from "./components/storageSecretsCard.component"; +import { UsersCard } from "./components/usersCard.component"; +import WorkspaceSecretsCard from "./components/workspaceSecretsCard.component"; +import WorkspaceMembersCard from "./components/workspaceUsersCard.component"; export const WorkspaceSettingsPage = withContext( WorkspaceSettingsProvider, diff --git a/frontend/src/pages/private/workspaces/workspaces/components/add-workspace.component.tsx b/frontend/src/pages/private/workspaces/workspaces/components/addWorkspace.component.tsx similarity index 100% rename from frontend/src/pages/private/workspaces/workspaces/components/add-workspace.component.tsx rename to frontend/src/pages/private/workspaces/workspaces/components/addWorkspace.component.tsx diff --git a/frontend/src/pages/private/workspaces/workspaces/components/pending-item.component.tsx b/frontend/src/pages/private/workspaces/workspaces/components/pendingItem.component.tsx similarity index 100% rename from frontend/src/pages/private/workspaces/workspaces/components/pending-item.component.tsx rename to frontend/src/pages/private/workspaces/workspaces/components/pendingItem.component.tsx diff --git a/frontend/src/pages/private/workspaces/workspaces/workspaces-page.component.tsx b/frontend/src/pages/private/workspaces/workspaces/workspacesPage.component.tsx similarity index 97% rename from frontend/src/pages/private/workspaces/workspaces/workspaces-page.component.tsx rename to frontend/src/pages/private/workspaces/workspaces/workspacesPage.component.tsx index 8b1a2b9d..584d851b 100644 --- a/frontend/src/pages/private/workspaces/workspaces/workspaces-page.component.tsx +++ b/frontend/src/pages/private/workspaces/workspaces/workspacesPage.component.tsx @@ -14,9 +14,9 @@ import { useWorkspaces } from "context/workspaces/workspaces.context"; import { PrivateLayout } from "modules/layout"; import { type FC, useCallback, useState } from "react"; -import { AddWorkspace } from "./components/add-workspace.component"; +import { AddWorkspace } from "./components/addWorkspace.component"; import { WorkspaceListItem } from "./components/item.component"; -import { WorkspacePendingListItem } from "./components/pending-item.component"; +import { WorkspacePendingListItem } from "./components/pendingItem.component"; /** * Workspace list page diff --git a/frontend/src/pages/public/sign-in/sign-in-page.component.tsx b/frontend/src/pages/public/signIn/signInPage.component.tsx similarity index 98% rename from frontend/src/pages/public/sign-in/sign-in-page.component.tsx rename to frontend/src/pages/public/signIn/signInPage.component.tsx index a3a0eb63..2e30e1f3 100644 --- a/frontend/src/pages/public/sign-in/sign-in-page.component.tsx +++ b/frontend/src/pages/public/signIn/signInPage.component.tsx @@ -1,5 +1,5 @@ import { Box, Button, Grid, Typography, Link as LinkMui } from "@mui/material"; -import TextInput from "components/text-input"; +import TextInput from "components/textInput"; import { useAuthentication } from "context/authentication"; import { PublicLayout } from "modules/layout"; import { type FC, useCallback } from "react"; diff --git a/frontend/src/pages/public/sign-up/sign-up-page.component.tsx b/frontend/src/pages/public/signUp/signUpPage.component.tsx similarity index 98% rename from frontend/src/pages/public/sign-up/sign-up-page.component.tsx rename to frontend/src/pages/public/signUp/signUpPage.component.tsx index 88537526..f1e85ca3 100644 --- a/frontend/src/pages/public/sign-up/sign-up-page.component.tsx +++ b/frontend/src/pages/public/signUp/signUpPage.component.tsx @@ -6,7 +6,7 @@ import { CircularProgress, Link as LinkMui, } from "@mui/material"; -import TextInput from "components/text-input"; +import TextInput from "components/textInput"; import { useAuthentication } from "context/authentication"; import { PublicLayout } from "modules/layout"; import { type FC, useCallback } from "react"; diff --git a/frontend/src/services/config/local-forage.config.ts b/frontend/src/services/config/localForage.config.ts similarity index 100% rename from frontend/src/services/config/local-forage.config.ts rename to frontend/src/services/config/localForage.config.ts diff --git a/frontend/src/services/requests/authentication/index.ts b/frontend/src/services/requests/authentication/index.ts index 7b7e7ec5..747c6f43 100644 --- a/frontend/src/services/requests/authentication/index.ts +++ b/frontend/src/services/requests/authentication/index.ts @@ -1,2 +1,2 @@ -export * from "./post-auth-login.request"; -export * from "./post-auth-register.request"; +export * from "./postAuthLogin.request"; +export * from "./postAuthRegister.request"; diff --git a/frontend/src/services/requests/authentication/post-auth-login.request.ts b/frontend/src/services/requests/authentication/postAuthLogin.request.ts similarity index 100% rename from frontend/src/services/requests/authentication/post-auth-login.request.ts rename to frontend/src/services/requests/authentication/postAuthLogin.request.ts diff --git a/frontend/src/services/requests/authentication/post-auth-register.request.ts b/frontend/src/services/requests/authentication/postAuthRegister.request.ts similarity index 100% rename from frontend/src/services/requests/authentication/post-auth-register.request.ts rename to frontend/src/services/requests/authentication/postAuthRegister.request.ts diff --git a/frontend/src/services/requests/piece/get-operator-repositories.request.ts b/frontend/src/services/requests/piece/getOperatorRepositories.request.ts similarity index 100% rename from frontend/src/services/requests/piece/get-operator-repositories.request.ts rename to frontend/src/services/requests/piece/getOperatorRepositories.request.ts diff --git a/frontend/src/services/requests/piece/get-operators-repositories-releases.request.ts b/frontend/src/services/requests/piece/getOperatorsRepositoriesReleases.request.ts similarity index 100% rename from frontend/src/services/requests/piece/get-operators-repositories-releases.request.ts rename to frontend/src/services/requests/piece/getOperatorsRepositoriesReleases.request.ts diff --git a/frontend/src/services/requests/piece/get-piece-repository-pieces.request.ts b/frontend/src/services/requests/piece/getPieceRepositoryPieces.request.ts similarity index 100% rename from frontend/src/services/requests/piece/get-piece-repository-pieces.request.ts rename to frontend/src/services/requests/piece/getPieceRepositoryPieces.request.ts diff --git a/frontend/src/services/requests/piece/index.ts b/frontend/src/services/requests/piece/index.ts index 10592dcf..d6e920ef 100644 --- a/frontend/src/services/requests/piece/index.ts +++ b/frontend/src/services/requests/piece/index.ts @@ -1,2 +1,2 @@ -export * from "./get-operator-repositories.request"; +export * from "./getOperatorRepositories.request"; export * from "./operator.interface"; diff --git a/frontend/src/services/requests/piece/operator.interface.ts b/frontend/src/services/requests/piece/operator.interface.ts index 4a05e1b0..e2ca4e59 100644 --- a/frontend/src/services/requests/piece/operator.interface.ts +++ b/frontend/src/services/requests/piece/operator.interface.ts @@ -1,4 +1,4 @@ -import { type ERepositorySource } from "common/interfaces/repository-source.enum"; +import { type ERepositorySource } from "common/interfaces/repositorySource.enum"; /** * Operator object diff --git a/frontend/src/services/requests/repository/delete-operator-repository.request.ts b/frontend/src/services/requests/repository/deleteOperatorRepository.request.ts similarity index 100% rename from frontend/src/services/requests/repository/delete-operator-repository.request.ts rename to frontend/src/services/requests/repository/deleteOperatorRepository.request.ts diff --git a/frontend/src/services/requests/repository/get-operator-repository-secrets.request.ts b/frontend/src/services/requests/repository/getOperatorRepositorySecrets.request.ts similarity index 94% rename from frontend/src/services/requests/repository/get-operator-repository-secrets.request.ts rename to frontend/src/services/requests/repository/getOperatorRepositorySecrets.request.ts index 9530517a..3afab78f 100644 --- a/frontend/src/services/requests/repository/get-operator-repository-secrets.request.ts +++ b/frontend/src/services/requests/repository/getOperatorRepositorySecrets.request.ts @@ -4,7 +4,7 @@ import useSWR from "swr"; import { dominoApiClient } from "../../clients/domino.client"; -import { type IOperatorRepositorySecretsData } from "./operator-repository.interface"; +import { type IOperatorRepositorySecretsData } from "./operatorRepository.interface"; interface IGetRepositorySecretsParams { repositoryId: string; diff --git a/frontend/src/services/requests/repository/index.ts b/frontend/src/services/requests/repository/index.ts index a18bda2f..295fe0a7 100644 --- a/frontend/src/services/requests/repository/index.ts +++ b/frontend/src/services/requests/repository/index.ts @@ -1,3 +1,3 @@ -export * from "./get-operator-repository-secrets.request"; -export * from "./patch-operator-repository-secret.request"; -export * from "./delete-operator-repository.request"; +export * from "./getOperatorRepositorySecrets.request"; +export * from "./patchOperatorRepositorySecret.request"; +export * from "./deleteOperatorRepository.request"; diff --git a/frontend/src/services/requests/repository/operator-repository.interface.ts b/frontend/src/services/requests/repository/operatorRepository.interface.ts similarity index 100% rename from frontend/src/services/requests/repository/operator-repository.interface.ts rename to frontend/src/services/requests/repository/operatorRepository.interface.ts diff --git a/frontend/src/services/requests/repository/patch-operator-repository-secret.request.ts b/frontend/src/services/requests/repository/patchOperatorRepositorySecret.request.ts similarity index 100% rename from frontend/src/services/requests/repository/patch-operator-repository-secret.request.ts rename to frontend/src/services/requests/repository/patchOperatorRepositorySecret.request.ts diff --git a/frontend/src/services/requests/runs/get-workflow-run-task-logs.request.ts b/frontend/src/services/requests/runs/getWorkflowRunTaskLogs.request.ts similarity index 100% rename from frontend/src/services/requests/runs/get-workflow-run-task-logs.request.ts rename to frontend/src/services/requests/runs/getWorkflowRunTaskLogs.request.ts diff --git a/frontend/src/services/requests/runs/get-workflow-run-task-result.request.ts b/frontend/src/services/requests/runs/getWorkflowRunTaskResult.request.ts similarity index 100% rename from frontend/src/services/requests/runs/get-workflow-run-task-result.request.ts rename to frontend/src/services/requests/runs/getWorkflowRunTaskResult.request.ts diff --git a/frontend/src/services/requests/runs/get-workflow-run-tasks.request.ts b/frontend/src/services/requests/runs/getWorkflowRunTasks.request.ts similarity index 100% rename from frontend/src/services/requests/runs/get-workflow-run-tasks.request.ts rename to frontend/src/services/requests/runs/getWorkflowRunTasks.request.ts diff --git a/frontend/src/services/requests/runs/get-workflow-runs.request.ts b/frontend/src/services/requests/runs/getWorkflowRuns.request.ts similarity index 100% rename from frontend/src/services/requests/runs/get-workflow-runs.request.ts rename to frontend/src/services/requests/runs/getWorkflowRuns.request.ts diff --git a/frontend/src/services/requests/runs/index.ts b/frontend/src/services/requests/runs/index.ts index e8803f5c..1c75263c 100644 --- a/frontend/src/services/requests/runs/index.ts +++ b/frontend/src/services/requests/runs/index.ts @@ -1,5 +1,5 @@ -export * from "./get-workflow-runs.request"; -export * from "./get-workflow-run-tasks.request"; -export * from "./get-workflow-run-task-logs.request"; -export * from "./get-workflow-run-task-result.request"; +export * from "./getWorkflowRuns.request"; +export * from "./getWorkflowRunTasks.request"; +export * from "./getWorkflowRunTaskLogs.request"; +export * from "./getWorkflowRunTaskResult.request"; export * from "./runs.interface"; diff --git a/frontend/src/services/requests/workflow/delete-workflow-id.request.ts b/frontend/src/services/requests/workflow/deleteWorkflowId.request.ts similarity index 100% rename from frontend/src/services/requests/workflow/delete-workflow-id.request.ts rename to frontend/src/services/requests/workflow/deleteWorkflowId.request.ts diff --git a/frontend/src/services/requests/workflow/get-workflow.request.ts b/frontend/src/services/requests/workflow/getWorkflow.request.ts similarity index 100% rename from frontend/src/services/requests/workflow/get-workflow.request.ts rename to frontend/src/services/requests/workflow/getWorkflow.request.ts diff --git a/frontend/src/services/requests/workflow/get-workflow-id.request.ts b/frontend/src/services/requests/workflow/getWorkflowId.request.ts similarity index 100% rename from frontend/src/services/requests/workflow/get-workflow-id.request.ts rename to frontend/src/services/requests/workflow/getWorkflowId.request.ts diff --git a/frontend/src/services/requests/workflow/index.ts b/frontend/src/services/requests/workflow/index.ts index 3195869d..8668023f 100644 --- a/frontend/src/services/requests/workflow/index.ts +++ b/frontend/src/services/requests/workflow/index.ts @@ -1,6 +1,6 @@ -export * from "./delete-workflow-id.request"; -export * from "./get-workflow-id.request"; -export * from "./get-workflow.request"; -export * from "./post-workflow-run-id.request"; -export * from "./post-workflow.request"; +export * from "./deleteWorkflowId.request"; +export * from "./getWorkflowId.request"; +export * from "./getWorkflow.request"; +export * from "./postWorkflowRunId.request"; +export * from "./postWorkflow.request"; export * from "./workflow.interface"; diff --git a/frontend/src/services/requests/workflow/post-workflow.request.ts b/frontend/src/services/requests/workflow/postWorkflow.request.ts similarity index 100% rename from frontend/src/services/requests/workflow/post-workflow.request.ts rename to frontend/src/services/requests/workflow/postWorkflow.request.ts diff --git a/frontend/src/services/requests/workflow/post-workflow-run-id.request.ts b/frontend/src/services/requests/workflow/postWorkflowRunId.request.ts similarity index 100% rename from frontend/src/services/requests/workflow/post-workflow-run-id.request.ts rename to frontend/src/services/requests/workflow/postWorkflowRunId.request.ts diff --git a/frontend/src/services/requests/workspaces/accept-workspace-invite.request.ts b/frontend/src/services/requests/workspaces/acceptWorkspaceInvite.request.ts similarity index 100% rename from frontend/src/services/requests/workspaces/accept-workspace-invite.request.ts rename to frontend/src/services/requests/workspaces/acceptWorkspaceInvite.request.ts diff --git a/frontend/src/services/requests/workspaces/delete-user-workspace.request.ts b/frontend/src/services/requests/workspaces/deleteUserWorkspace.request.ts similarity index 100% rename from frontend/src/services/requests/workspaces/delete-user-workspace.request.ts rename to frontend/src/services/requests/workspaces/deleteUserWorkspace.request.ts diff --git a/frontend/src/services/requests/workspaces/delete-workspace.request.ts b/frontend/src/services/requests/workspaces/deleteWorkspace.request.ts similarity index 100% rename from frontend/src/services/requests/workspaces/delete-workspace.request.ts rename to frontend/src/services/requests/workspaces/deleteWorkspace.request.ts diff --git a/frontend/src/services/requests/workspaces/get-workspace-id.request.ts b/frontend/src/services/requests/workspaces/getWorkspaceId.request.ts similarity index 100% rename from frontend/src/services/requests/workspaces/get-workspace-id.request.ts rename to frontend/src/services/requests/workspaces/getWorkspaceId.request.ts diff --git a/frontend/src/services/requests/workspaces/get-workspace-members.request.ts b/frontend/src/services/requests/workspaces/getWorkspaceMembers.request.ts similarity index 100% rename from frontend/src/services/requests/workspaces/get-workspace-members.request.ts rename to frontend/src/services/requests/workspaces/getWorkspaceMembers.request.ts diff --git a/frontend/src/services/requests/workspaces/get-workspaces.request.ts b/frontend/src/services/requests/workspaces/getWorkspaces.request.ts similarity index 100% rename from frontend/src/services/requests/workspaces/get-workspaces.request.ts rename to frontend/src/services/requests/workspaces/getWorkspaces.request.ts diff --git a/frontend/src/services/requests/workspaces/index.ts b/frontend/src/services/requests/workspaces/index.ts index 265adafc..66816196 100644 --- a/frontend/src/services/requests/workspaces/index.ts +++ b/frontend/src/services/requests/workspaces/index.ts @@ -1,12 +1,12 @@ -export * from "./get-workspace-id.request"; -export * from "./get-workspaces.request"; -export * from "./post-operators-repositories.request"; -export * from "./post-workspaces.request"; -export * from "./delete-workspace.request"; +export * from "./getWorkspaceId.request"; +export * from "./getWorkspaces.request"; +export * from "./postOperatorsRepositories.request"; +export * from "./postWorkspaces.request"; +export * from "./deleteWorkspace.request"; export * from "./workspaces.interface"; -export * from "./patch-workspace.reques"; -export * from "./accept-workspace-invite.request"; -export * from "./reject-workspace-invite.request"; -export * from "./invite-workspace.request"; -export * from "./delete-user-workspace.request"; -export * from "./get-workspace-members.request"; +export * from "./patchWorkspace.reques"; +export * from "./acceptWorkspaceInvite.request"; +export * from "./rejectWorkspaceInvite.request"; +export * from "./inviteWorkspace.request"; +export * from "./deleteUserWorkspace.request"; +export * from "./getWorkspaceMembers.request"; diff --git a/frontend/src/services/requests/workspaces/invite-workspace.request.ts b/frontend/src/services/requests/workspaces/inviteWorkspace.request.ts similarity index 100% rename from frontend/src/services/requests/workspaces/invite-workspace.request.ts rename to frontend/src/services/requests/workspaces/inviteWorkspace.request.ts diff --git a/frontend/src/services/requests/workspaces/patch-workspace.reques.ts b/frontend/src/services/requests/workspaces/patchWorkspace.reques.ts similarity index 100% rename from frontend/src/services/requests/workspaces/patch-workspace.reques.ts rename to frontend/src/services/requests/workspaces/patchWorkspace.reques.ts diff --git a/frontend/src/services/requests/workspaces/post-operators-repositories.request.ts b/frontend/src/services/requests/workspaces/postOperatorsRepositories.request.ts similarity index 100% rename from frontend/src/services/requests/workspaces/post-operators-repositories.request.ts rename to frontend/src/services/requests/workspaces/postOperatorsRepositories.request.ts diff --git a/frontend/src/services/requests/workspaces/post-workspaces.request.ts b/frontend/src/services/requests/workspaces/postWorkspaces.request.ts similarity index 100% rename from frontend/src/services/requests/workspaces/post-workspaces.request.ts rename to frontend/src/services/requests/workspaces/postWorkspaces.request.ts diff --git a/frontend/src/services/requests/workspaces/reject-workspace-invite.request.ts b/frontend/src/services/requests/workspaces/rejectWorkspaceInvite.request.ts similarity index 100% rename from frontend/src/services/requests/workspaces/reject-workspace-invite.request.ts rename to frontend/src/services/requests/workspaces/rejectWorkspaceInvite.request.ts diff --git a/frontend/src/services/requests/workspaces/workspaces.interface.ts b/frontend/src/services/requests/workspaces/workspaces.interface.ts index 8fb390db..31f059d9 100644 --- a/frontend/src/services/requests/workspaces/workspaces.interface.ts +++ b/frontend/src/services/requests/workspaces/workspaces.interface.ts @@ -1,4 +1,4 @@ -import { type ERepositorySource } from "common/interfaces/repository-source.enum"; +import { type ERepositorySource } from "common/interfaces/repositorySource.enum"; // Workspace status enum with values (pending, accepted and rejected) export enum EWorkspaceStatus { diff --git a/frontend/src/utils/create-custom-context.function.ts b/frontend/src/utils/createCustomContext.function.ts similarity index 100% rename from frontend/src/utils/create-custom-context.function.ts rename to frontend/src/utils/createCustomContext.function.ts diff --git a/frontend/src/utils/index.ts b/frontend/src/utils/index.ts index 626dc245..d4ff9fab 100644 --- a/frontend/src/utils/index.ts +++ b/frontend/src/utils/index.ts @@ -1,5 +1,5 @@ export { extractDefaultValues, extractDefaultInputValues } from "./jsonSchema"; -export { createCustomContext } from "./create-custom-context.function"; +export { createCustomContext } from "./createCustomContext.function"; export { fetchFromObject } from "./fetchFromObject"; export { yupResolver } from "./validationResolver"; export { getIdSlice, getUuidSlice, getUuid } from "./getUuidSlice"; From 0afb533ad2d972ec2ba7669befd3da5f93145dd5 Mon Sep 17 00:00:00 2001 From: Vinicius Vaz Date: Tue, 5 Sep 2023 07:17:18 -0300 Subject: [PATCH 222/328] fix filter path --- rest/schemas/requests/piece_repository.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rest/schemas/requests/piece_repository.py b/rest/schemas/requests/piece_repository.py index 8ef4a612..9da934a6 100644 --- a/rest/schemas/requests/piece_repository.py +++ b/rest/schemas/requests/piece_repository.py @@ -11,7 +11,7 @@ class Config: class ListRepositoryFilters(BaseModel): name__like: Optional[str] - path_like: Optional[str] + path__like: Optional[str] version: Optional[str] url: Optional[str] workspace_id: Optional[int] From 0c3f21b78296d4d75ea23054de30c7f4b382335f Mon Sep 17 00:00:00 2001 From: Vinicius Vaz Date: Tue, 5 Sep 2023 07:36:01 -0300 Subject: [PATCH 223/328] Add url to create piece repository --- .../components/repositories-card.component.tsx | 5 +++-- .../src/services/requests/workspaces/workspaces.interface.ts | 3 ++- rest/core/settings.py | 1 + rest/schemas/requests/piece_repository.py | 3 ++- rest/services/piece_repository_service.py | 5 +++-- rest/services/workspace_service.py | 3 ++- 6 files changed, 13 insertions(+), 7 deletions(-) diff --git a/frontend/src/pages/private/workspaces/workspace-settings/components/repositories-card.component.tsx b/frontend/src/pages/private/workspaces/workspace-settings/components/repositories-card.component.tsx index f64f8c77..e912289c 100644 --- a/frontend/src/pages/private/workspaces/workspace-settings/components/repositories-card.component.tsx +++ b/frontend/src/pages/private/workspaces/workspace-settings/components/repositories-card.component.tsx @@ -95,7 +95,8 @@ export const RepositoriesCard: FC = () => { handleAddRepository({ path, source, - version + version, + url }).finally(() => { setStep('FETCH_METADATA') setAvailableVersions([]) @@ -103,7 +104,7 @@ export const RepositoriesCard: FC = () => { setUrl('') setIsStepLoading(false) }) - }, [handleAddRepository, handleRefreshRepositories, path, source, version]) + }, [handleAddRepository, handleRefreshRepositories, path, source, version, url]) const handleNextStep = useCallback(() => { switch (step) { diff --git a/frontend/src/services/requests/workspaces/workspaces.interface.ts b/frontend/src/services/requests/workspaces/workspaces.interface.ts index bec28320..1c296494 100644 --- a/frontend/src/services/requests/workspaces/workspaces.interface.ts +++ b/frontend/src/services/requests/workspaces/workspaces.interface.ts @@ -55,7 +55,8 @@ export interface IPostWorkspaceRepositoryPayload { workspace_id: string source: ERepositorySource | string path: string - version: string + version: string, + url: string } export interface IPostWorkspaceRepositoryParams { id: string diff --git a/rest/core/settings.py b/rest/core/settings.py index ce05db8e..fcead635 100644 --- a/rest/core/settings.py +++ b/rest/core/settings.py @@ -51,6 +51,7 @@ class Settings(BaseSettings): DOMINO_DEFAULT_PIECES_REPOSITORY_VERSION = os.environ.get('DOMINO_DEFAULT_PIECES_REPOSITORY_VERSION', "0.3.11") DOMINO_DEFAULT_PIECES_REPOSITORY_SOURCE = os.environ.get('DOMINO_DEFAULT_PIECES_REPOSITORY_SOURCE', "github") DOMINO_DEFAULT_PIECES_REPOSITORY_TOKEN: EmptyStrToNone = os.environ.get('DOMINO_DEFAULT_PIECES_REPOSITORY_TOKEN', "") + DOMINO_DEFAULT_PIECES_REPOSITORY_URL: str = os.environ.get('DOMINO_DEFAULT_PIECES_REPOSITORY_URL', 'https://github.com/Tauffer-Consulting/default_domino_pieces') # Default DB mock data RUN_CREATE_MOCK_DATA = False diff --git a/rest/schemas/requests/piece_repository.py b/rest/schemas/requests/piece_repository.py index 9da934a6..86e133a3 100644 --- a/rest/schemas/requests/piece_repository.py +++ b/rest/schemas/requests/piece_repository.py @@ -20,8 +20,9 @@ class ListRepositoryFilters(BaseModel): class CreateRepositoryRequest(BaseModel): workspace_id: int = Field(description='Workspace id to create repository') source: RepositorySourceRequestEnum = Field(description="Source of the repository", default=RepositorySource.github.value) - path: str = Field(..., description="Path to the repository. If local source, this is the absolute path to the repository folder. If github source, this is the repository name.") + path: str = Field(..., description="Path to the repository.") version: str = Field(regex=r'((^\d+\.\d+\.\d+$))', description="Version of the repository.") + url: str = Field(..., description="Url of the repository.") class PatchRepositoryRequest(BaseModel): version: str = Field(regex=r'((^\d+\.\d+\.\d+$))', description="Version of the repository.") \ No newline at end of file diff --git a/rest/services/piece_repository_service.py b/rest/services/piece_repository_service.py index 9efdf139..f8d606a9 100644 --- a/rest/services/piece_repository_service.py +++ b/rest/services/piece_repository_service.py @@ -213,7 +213,7 @@ def create_piece_repository( token = auth_context.workspace.github_access_token if auth_context.workspace.github_access_token else settings.DOMINO_DEFAULT_PIECES_REPOSITORY_TOKEN repository_files_metadata = self._read_repository_data( - source=piece_repository_data.source, + source=piece_repository_data.source, path=piece_repository_data.path, version=piece_repository_data.version, github_access_token=token @@ -227,7 +227,8 @@ def create_piece_repository( version=piece_repository_data.version, dependencies_map=repository_files_metadata['dependencies_map'], compiled_metadata=repository_files_metadata['compiled_metadata'], - workspace_id=piece_repository_data.workspace_id + workspace_id=piece_repository_data.workspace_id, + url=piece_repository_data.url ) repository = self.piece_repository_repository.create(piece_repository=new_repo) try: diff --git a/rest/services/workspace_service.py b/rest/services/workspace_service.py index 76090773..188379b7 100644 --- a/rest/services/workspace_service.py +++ b/rest/services/workspace_service.py @@ -79,7 +79,8 @@ def create_workspace( workspace_id=workspace.id, source=settings.DOMINO_DEFAULT_PIECES_REPOSITORY_SOURCE, path=settings.DOMINO_DEFAULT_PIECES_REPOSITORY, - version=settings.DOMINO_DEFAULT_PIECES_REPOSITORY_VERSION + version=settings.DOMINO_DEFAULT_PIECES_REPOSITORY_VERSION, + url=settings.DOMINO_DEFAULT_PIECES_REPOSITORY_URL ), auth_context=auth_context ) From aa8aa87ac58c7de7ac66ed952ba21546219722c4 Mon Sep 17 00:00:00 2001 From: Vinicius Vaz Date: Tue, 5 Sep 2023 08:00:02 -0300 Subject: [PATCH 224/328] dag with version and url for default storage repository --- rest/core/settings.py | 10 +++++++++- rest/services/piece_repository_service.py | 9 ++++++--- rest/services/workflow_service.py | 11 ++++------- 3 files changed, 19 insertions(+), 11 deletions(-) diff --git a/rest/core/settings.py b/rest/core/settings.py index fcead635..62858146 100644 --- a/rest/core/settings.py +++ b/rest/core/settings.py @@ -1,6 +1,8 @@ from pydantic import BaseSettings, validators from typing import Optional import os +from database.models.enums import RepositorySource + def empty_to_none(v: str) -> Optional[str]: @@ -66,7 +68,13 @@ class Settings(BaseSettings): AIRFLOW_WEBSERVER_HOST = os.environ.get('AIRFLOW_WEBSERVER_HOST', "http://airflow-webserver:8080/") # Default repositories - DEFAULT_STORAGE_REPOSITORY_NAME = 'default_storage_repository' + DEFAULT_STORAGE_REPOSITORY = dict( + name="default_storage_repository", + path="default_storage_repository", + source=getattr(RepositorySource, 'default').value, + version="0.0.1", + url="domino-default/default_storage_repository" + ) DEPLOY_MODE = os.environ.get('DOMINO_DEPLOY_MODE', 'local-k8s') diff --git a/rest/services/piece_repository_service.py b/rest/services/piece_repository_service.py index f8d606a9..45e66b58 100644 --- a/rest/services/piece_repository_service.py +++ b/rest/services/piece_repository_service.py @@ -180,12 +180,15 @@ def create_default_storage_repository(self, workspace_id: int): self.logger.info(f"Creating default storage repository") new_repo = PieceRepository( - name=settings.DEFAULT_STORAGE_REPOSITORY_NAME, + name=settings.DEFAULT_STORAGE_REPOSITORY['name'], created_at=datetime.utcnow(), workspace_id=workspace_id, - path=None, - source=getattr(RepositorySource, 'default').value + path=settings.DEFAULT_STORAGE_REPOSITORY['path'], + source=settings.DEFAULT_STORAGE_REPOSITORY['source'], + version=settings.DEFAULT_STORAGE_REPOSITORY['version'], + url=settings.DEFAULT_STORAGE_REPOSITORY['url'] ) + default_storage_repository = self.piece_repository_repository.create(piece_repository=new_repo) pieces = self.piece_service.create_default_storage_pieces( piece_repository_id=default_storage_repository.id, diff --git a/rest/services/workflow_service.py b/rest/services/workflow_service.py index 6a6f8f86..30330c5d 100644 --- a/rest/services/workflow_service.py +++ b/rest/services/workflow_service.py @@ -414,11 +414,6 @@ def _create_dag_code_from_raw_json(self, data: dict, workspace_id: int): if key in workflow_kwargs: workflow_kwargs.pop(key) - workspace_storage_repository = self._get_storage_repository_from_tasks(tasks=tasks, workspace_id=workspace_id) - workspace_storage_repository_id = None - if workspace_storage_repository: - workspace_storage_repository_id = workspace_storage_repository.id - pieces_repositories_ids = set() stream_tasks_dict = dict() for task_key, task_value in tasks.items(): @@ -472,9 +467,11 @@ def _create_dag_code_from_raw_json(self, data: dict, workspace_id: int): input_kwargs[input_key] = array_input_kwargs else: input_kwargs[input_key] = input_value['value'] - + + workspace_storage_repository = self._get_storage_repository_from_tasks(tasks=tasks, workspace_id=workspace_id) if workflow_shared_storage: - workflow_shared_storage['storage_repository_id'] = workspace_storage_repository_id + workflow_shared_storage['storage_repository_url'] = workspace_storage_repository.url if workspace_storage_repository else None + workflow_shared_storage['storage_repository_version'] = workspace_storage_repository.version if workspace_storage_repository else None piece_db = self.piece_repository.find_by_id(piece_request.get('id')) piece_repository_db = self.piece_repository_repository.find_by_id(piece_db.repository_id) From d46eac40f6f74728ea535ae3f17471f2ac669617 Mon Sep 17 00:00:00 2001 From: Nathan Vieira Marcelino Date: Tue, 5 Sep 2023 21:00:51 -0300 Subject: [PATCH 225/328] refactor: use react bulletproof architecture --- frontend/src/common/hocs/withContext.hoc.tsx | 17 --- .../interfaces/environment.interface.ts | 11 -- frontend/src/common/schemas/storageSchemas.ts | 11 -- .../src/common/schemas/workflowFormSchema.ts | 137 ------------------ .../index.tsx} | 0 .../index.tsx} | 0 .../CustomNode/index.tsx} | 0 .../index.tsx} | 0 .../index.tsx} | 0 .../PrivateLayout}/header/drawerMenu.style.ts | 0 .../PrivateLayout/header/drawerMenu.tsx} | 4 +- .../PrivateLayout/header/drawerMenuItem.tsx} | 0 .../PrivateLayout/header/header.tsx} | 2 +- .../PrivateLayout/index.tsx} | 2 +- .../PublicLayout/index.tsx} | 0 .../index.tsx} | 0 .../{textInput.tsx => TextInput/index.tsx} | 0 .../{common => }/config/environment.config.ts | 16 +- .../providerContextWrapper.tsx | 28 ---- .../{workspaces.context.tsx => index.tsx} | 0 .../auth/pages/signIn/signInPage.tsx} | 4 +- .../auth/pages/signUp/signUpPage.tsx} | 4 +- .../components/DrawerMenu/index.tsx} | 4 +- .../DrawerMenu/pieceDocsPopover.tsx} | 0 .../components/DrawerMenu/sidebarAddNode.tsx} | 4 +- .../components/DrawerMenu/sidebarNode.tsx} | 2 +- .../components/SidebarSettingsForm/index.tsx} | 12 +- .../components/WorkflowEditorPanel/index.tsx} | 11 +- .../sidebarForm/containerResourceForm.tsx} | 6 +- .../sidebarForm}/index.tsx | 12 +- .../sidebarForm/pieceForm}/index.tsx | 6 +- .../pieceForm/pieceFormItem}/arrayInput.tsx | 18 +-- .../pieceFormItem}/disableCheckboxOptions.ts | 0 .../pieceForm/pieceFormItem}/index.tsx | 19 +-- .../pieceForm/pieceFormItem}/objectInput.tsx | 8 +- .../pieceFormItem}/selectUpstreamInput.tsx | 4 +- .../sidebarForm/pieceForm}/upstreamOptions.ts | 0 .../sidebarForm/pieceForm}/validation.ts | 0 .../sidebarForm/storageForm.tsx} | 2 +- .../components/WorkflowsEditor.tsx} | 17 ++- .../context/types/containerResources.ts | 11 ++ .../workflowEditor/context/types/index.ts | 4 + .../workflowEditor/context/types/input.ts | 24 +++ .../workflowEditor/context/types/settings.ts | 50 +++++++ .../workflowEditor/context/types/storage.ts | 11 ++ .../context/types/workflowPieceData.ts | 72 +++++++++ .../context/workflowsEditor/index.tsx | 35 +++++ .../context/workflowsEditor/pieces.tsx} | 0 .../workflowsEditor/workflowEdges.tsx} | 0 .../workflowsEditor/workflowNodes.tsx} | 0 .../workflowsEditor/workflowPieces.tsx} | 0 .../workflowsEditor/workflowPiecesData.tsx} | 0 .../workflowsEditor/workflowSettingsData.tsx} | 0 .../workflowsEditor/workflowsEditor.tsx} | 21 ++- .../features/workflowEditor/pages/index.ts | 1 + .../pages/workflowEditorPage.tsx | 22 +++ .../schemas/containerResourcesSchemas.ts | 0 .../workflows/components/Workflows.tsx} | 21 +-- .../WorkflowTaskDetails.tsx} | 2 +- .../WorkflowTaskLogs.tsx} | 0 .../WorkflowTaskResult.tsx} | 0 .../WorkflowsRunTasksFlowchart/index.tsx} | 15 +- .../components/WorkflowsRunsTable/index.tsx} | 3 +- .../components/WorkflowsTable/index.tsx} | 3 +- .../workflows}/constants/index.ts | 11 -- .../workflows/context/workflows/index.tsx} | 0 .../src/features/workflows/pages/index.ts | 1 + .../workflows/pages/workflowsPage.tsx | 18 +++ .../workspaceSettings/RepositoriesCard.tsx} | 5 +- .../workspaceSettings/SecretsCard.tsx} | 0 .../workspaceSettings/StorageSecretsCard.tsx} | 3 +- .../workspaceSettings/UsersCard.tsx} | 5 +- .../WorkspaceMembersCard.tsx} | 2 +- .../WorkspaceSecretsCard.tsx} | 5 +- .../components/workspaceSettings/index.tsx | 89 ++++++++++++ .../components/workspaces/AddWorkspace.tsx} | 2 +- .../workspaces/WorkspaceListItem.tsx} | 0 .../workspaces/WorkspacePendingListItem.tsx} | 2 +- .../components/workspaces/index.tsx} | 14 +- .../workspaces/context/workspaceSettings.tsx} | 3 +- .../src/features/workspaces/pages/index.ts | 2 + .../pages/workspaceSettingsPage.tsx | 12 ++ .../workspaces/pages/workspacesPage.tsx | 7 + frontend/src/index.tsx | 2 +- .../interfaces/repositorySource.enum.ts | 0 frontend/src/modules/layout/index.ts | 2 - frontend/src/pages/private/workflows/index.ts | 4 - .../workflows/workflowsPage.component.tsx | 17 --- .../workflowsEditorPage.component.tsx | 27 ---- .../src/pages/private/workspaces/index.ts | 2 - .../workspaceSettingsPage.component.tsx | 93 ------------ .../app.component.tsx => providers/app.tsx} | 5 +- .../app => providers}/theme.config.ts | 0 .../index.tsx} | 15 +- .../privateRoute.tsx} | 2 +- .../publicRoute.tsx} | 0 .../src/services/clients/domino.client.ts | 2 +- .../src/services/config/endpoints.config.ts | 3 +- .../piece/getOperatorRepositories.request.ts | 2 +- ...etOperatorsRepositoriesReleases.request.ts | 2 +- .../requests/piece/operator.interface.ts | 2 +- .../deleteOperatorRepository.request.ts | 2 +- .../getOperatorRepositorySecrets.request.ts | 2 +- .../patchOperatorRepositorySecret.request.ts | 2 +- .../runs/getWorkflowRunTaskLogs.request.ts | 2 +- .../runs/getWorkflowRunTaskResult.request.ts | 2 +- .../runs/getWorkflowRunTasks.request.ts | 2 +- .../requests/runs/getWorkflowRuns.request.ts | 2 +- .../workflow/deleteWorkflowId.request.ts | 2 +- .../requests/workflow/getWorkflow.request.ts | 2 +- .../workflow/getWorkflowId.request.ts | 2 +- .../workflow/postWorkflowRunId.request.ts | 2 +- .../workspaces/patchWorkspace.reques.ts | 2 +- .../workspaces/workspaces.interface.ts | 2 +- frontend/src/utils/index.ts | 1 + frontend/src/utils/lazyImports.ts | 17 +++ 116 files changed, 541 insertions(+), 520 deletions(-) delete mode 100644 frontend/src/common/hocs/withContext.hoc.tsx delete mode 100644 frontend/src/common/interfaces/environment.interface.ts delete mode 100644 frontend/src/common/schemas/storageSchemas.ts delete mode 100644 frontend/src/common/schemas/workflowFormSchema.ts rename frontend/src/components/{checkboxInput.tsx => CheckboxInput/index.tsx} (100%) rename frontend/src/components/{codeeditorInput.tsx => CodeEditorInput/index.tsx} (100%) rename frontend/src/{pages/private/workflows/workflowsEditor/components/customNode.component.tsx => components/CustomNode/index.tsx} (100%) rename frontend/src/components/{datetimeInput.tsx => DatetimeInput/index.tsx} (100%) rename frontend/src/components/{numberInput.tsx => NumberInput/index.tsx} (100%) rename frontend/src/{modules/layout/privateLayout => components/PrivateLayout}/header/drawerMenu.style.ts (100%) rename frontend/src/{modules/layout/privateLayout/header/drawerMenu.component.tsx => components/PrivateLayout/header/drawerMenu.tsx} (96%) rename frontend/src/{modules/layout/privateLayout/header/drawerMenuItem.component.tsx => components/PrivateLayout/header/drawerMenuItem.tsx} (100%) rename frontend/src/{modules/layout/privateLayout/header/header.component.tsx => components/PrivateLayout/header/header.tsx} (90%) rename frontend/src/{modules/layout/privateLayout/privateLayout.component.tsx => components/PrivateLayout/index.tsx} (91%) rename frontend/src/{modules/layout/publicLayout/publicLayout.component.tsx => components/PublicLayout/index.tsx} (100%) rename frontend/src/components/{selectInput.tsx => SelectInput/index.tsx} (100%) rename frontend/src/components/{textInput.tsx => TextInput/index.tsx} (100%) rename frontend/src/{common => }/config/environment.config.ts (52%) delete mode 100644 frontend/src/context/workflows/workflowsEditor.context/providerContextWrapper.tsx rename frontend/src/context/workspaces/{workspaces.context.tsx => index.tsx} (100%) rename frontend/src/{pages/public/signIn/signInPage.component.tsx => features/auth/pages/signIn/signInPage.tsx} (97%) rename frontend/src/{pages/public/signUp/signUpPage.component.tsx => features/auth/pages/signUp/signUpPage.tsx} (97%) rename frontend/src/{pages/private/workflows/workflowsEditor/components/drawerMenuComponent.tsx => features/workflowEditor/components/DrawerMenu/index.tsx} (93%) rename frontend/src/{pages/private/workflows/workflowsEditor/components/pieceDocsPopover.component.tsx => features/workflowEditor/components/DrawerMenu/pieceDocsPopover.tsx} (100%) rename frontend/src/{pages/private/workflows/workflowsEditor/components/sidebarAddNode.component.tsx => features/workflowEditor/components/DrawerMenu/sidebarAddNode.tsx} (97%) rename frontend/src/{pages/private/workflows/workflowsEditor/components/sidebarNode.component.tsx => features/workflowEditor/components/DrawerMenu/sidebarNode.tsx} (96%) rename frontend/src/{pages/private/workflows/workflowsEditor/components/sidebarSettingsForm.component.tsx => features/workflowEditor/components/SidebarSettingsForm/index.tsx} (96%) rename frontend/src/{pages/private/workflows/workflowsEditor/components/workflowEditorPanel.component.tsx => features/workflowEditor/components/WorkflowEditorPanel/index.tsx} (95%) rename frontend/src/{pages/private/workflows/workflowsEditor/components/sidebarForm.component/containerResourceForm.component.tsx => features/workflowEditor/components/WorkflowEditorPanel/sidebarForm/containerResourceForm.tsx} (94%) rename frontend/src/{pages/private/workflows/workflowsEditor/components/sidebarForm.component => features/workflowEditor/components/WorkflowEditorPanel/sidebarForm}/index.tsx (95%) rename frontend/src/{pages/private/workflows/workflowsEditor/components/sidebarForm.component/pieceForm.component => features/workflowEditor/components/WorkflowEditorPanel/sidebarForm/pieceForm}/index.tsx (89%) rename frontend/src/{pages/private/workflows/workflowsEditor/components/sidebarForm.component/pieceForm.component/pieceFormItem.component => features/workflowEditor/components/WorkflowEditorPanel/sidebarForm/pieceForm/pieceFormItem}/arrayInput.tsx (95%) rename frontend/src/{pages/private/workflows/workflowsEditor/components/sidebarForm.component/pieceForm.component/pieceFormItem.component => features/workflowEditor/components/WorkflowEditorPanel/sidebarForm/pieceForm/pieceFormItem}/disableCheckboxOptions.ts (100%) rename frontend/src/{pages/private/workflows/workflowsEditor/components/sidebarForm.component/pieceForm.component/pieceFormItem.component => features/workflowEditor/components/WorkflowEditorPanel/sidebarForm/pieceForm/pieceFormItem}/index.tsx (91%) rename frontend/src/{pages/private/workflows/workflowsEditor/components/sidebarForm.component/pieceForm.component/pieceFormItem.component => features/workflowEditor/components/WorkflowEditorPanel/sidebarForm/pieceForm/pieceFormItem}/objectInput.tsx (94%) rename frontend/src/{pages/private/workflows/workflowsEditor/components/sidebarForm.component/pieceForm.component/pieceFormItem.component => features/workflowEditor/components/WorkflowEditorPanel/sidebarForm/pieceForm/pieceFormItem}/selectUpstreamInput.tsx (94%) rename frontend/src/{pages/private/workflows/workflowsEditor/components/sidebarForm.component/pieceForm.component => features/workflowEditor/components/WorkflowEditorPanel/sidebarForm/pieceForm}/upstreamOptions.ts (100%) rename frontend/src/{pages/private/workflows/workflowsEditor/components/sidebarForm.component/pieceForm.component => features/workflowEditor/components/WorkflowEditorPanel/sidebarForm/pieceForm}/validation.ts (100%) rename frontend/src/{pages/private/workflows/workflowsEditor/components/sidebarForm.component/storageForm.component.tsx => features/workflowEditor/components/WorkflowEditorPanel/sidebarForm/storageForm.tsx} (97%) rename frontend/src/{pages/private/workflows/workflowsEditor/components/workflowsEditor.component.tsx => features/workflowEditor/components/WorkflowsEditor.tsx} (91%) create mode 100644 frontend/src/features/workflowEditor/context/types/containerResources.ts create mode 100644 frontend/src/features/workflowEditor/context/types/index.ts create mode 100644 frontend/src/features/workflowEditor/context/types/input.ts create mode 100644 frontend/src/features/workflowEditor/context/types/settings.ts create mode 100644 frontend/src/features/workflowEditor/context/types/storage.ts create mode 100644 frontend/src/features/workflowEditor/context/types/workflowPieceData.ts create mode 100644 frontend/src/features/workflowEditor/context/workflowsEditor/index.tsx rename frontend/src/{context/workflows/workflowsEditor.context/pieces.context.tsx => features/workflowEditor/context/workflowsEditor/pieces.tsx} (100%) rename frontend/src/{context/workflows/workflowsEditor.context/workflowEdges.context.tsx => features/workflowEditor/context/workflowsEditor/workflowEdges.tsx} (100%) rename frontend/src/{context/workflows/workflowsEditor.context/workflowNodes.context.tsx => features/workflowEditor/context/workflowsEditor/workflowNodes.tsx} (100%) rename frontend/src/{context/workflows/workflowsEditor.context/workflowPieces.context.tsx => features/workflowEditor/context/workflowsEditor/workflowPieces.tsx} (100%) rename frontend/src/{context/workflows/workflowsEditor.context/workflowPiecesData.context.tsx => features/workflowEditor/context/workflowsEditor/workflowPiecesData.tsx} (100%) rename frontend/src/{context/workflows/workflowsEditor.context/workflowSettingsData.context.tsx => features/workflowEditor/context/workflowsEditor/workflowSettingsData.tsx} (100%) rename frontend/src/{context/workflows/workflowsEditor.context/index.tsx => features/workflowEditor/context/workflowsEditor/workflowsEditor.tsx} (94%) create mode 100644 frontend/src/features/workflowEditor/pages/index.ts create mode 100644 frontend/src/features/workflowEditor/pages/workflowEditorPage.tsx rename frontend/src/{common => features/workflowEditor}/schemas/containerResourcesSchemas.ts (100%) rename frontend/src/{pages/private/workflows/workflows/components/workflows.component.tsx => features/workflows/components/Workflows.tsx} (87%) rename frontend/src/{pages/private/workflows/workflows/components/workflowTaskDetails.component.tsx => features/workflows/components/WorkflowsRunTasksFlowchart/WorkflowTaskDetails.tsx} (98%) rename frontend/src/{pages/private/workflows/workflows/components/workflowTaskLogs.component.tsx => features/workflows/components/WorkflowsRunTasksFlowchart/WorkflowTaskLogs.tsx} (100%) rename frontend/src/{pages/private/workflows/workflows/components/workflowTaskResult.component.tsx => features/workflows/components/WorkflowsRunTasksFlowchart/WorkflowTaskResult.tsx} (100%) rename frontend/src/{pages/private/workflows/workflows/components/workflowsRunTasksFlowchart.component.tsx => features/workflows/components/WorkflowsRunTasksFlowchart/index.tsx} (96%) rename frontend/src/{pages/private/workflows/workflows/components/workflowsRunsTable.component.tsx => features/workflows/components/WorkflowsRunsTable/index.tsx} (98%) rename frontend/src/{pages/private/workflows/workflows/components/workflowsTable.component.tsx => features/workflows/components/WorkflowsTable/index.tsx} (99%) rename frontend/src/{ => features/workflows}/constants/index.ts (72%) rename frontend/src/{context/workflows/workflows.context.tsx => features/workflows/context/workflows/index.tsx} (100%) create mode 100644 frontend/src/features/workflows/pages/index.ts create mode 100644 frontend/src/features/workflows/pages/workflowsPage.tsx rename frontend/src/{pages/private/workspaces/workspaceSettings/components/repositoriesCard.component.tsx => features/workspaces/components/workspaceSettings/RepositoriesCard.tsx} (98%) rename frontend/src/{pages/private/workspaces/workspaceSettings/components/repositorySecretsCard.component.tsx => features/workspaces/components/workspaceSettings/SecretsCard.tsx} (100%) rename frontend/src/{pages/private/workspaces/workspaceSettings/components/storageSecretsCard.component.tsx => features/workspaces/components/workspaceSettings/StorageSecretsCard.tsx} (98%) rename frontend/src/{pages/private/workspaces/workspaceSettings/components/usersCard.component.tsx => features/workspaces/components/workspaceSettings/UsersCard.tsx} (95%) rename frontend/src/{pages/private/workspaces/workspaceSettings/components/workspaceUsersCard.component.tsx => features/workspaces/components/workspaceSettings/WorkspaceMembersCard.tsx} (98%) rename frontend/src/{pages/private/workspaces/workspaceSettings/components/workspaceSecretsCard.component.tsx => features/workspaces/components/workspaceSettings/WorkspaceSecretsCard.tsx} (97%) create mode 100644 frontend/src/features/workspaces/components/workspaceSettings/index.tsx rename frontend/src/{pages/private/workspaces/workspaces/components/addWorkspace.component.tsx => features/workspaces/components/workspaces/AddWorkspace.tsx} (96%) rename frontend/src/{pages/private/workspaces/workspaces/components/item.component.tsx => features/workspaces/components/workspaces/WorkspaceListItem.tsx} (100%) rename frontend/src/{pages/private/workspaces/workspaces/components/pendingItem.component.tsx => features/workspaces/components/workspaces/WorkspacePendingListItem.tsx} (97%) rename frontend/src/{pages/private/workspaces/workspaces/workspacesPage.component.tsx => features/workspaces/components/workspaces/index.tsx} (93%) rename frontend/src/{context/workspaces/workspaceSettings.context.tsx => features/workspaces/context/workspaceSettings.tsx} (98%) create mode 100644 frontend/src/features/workspaces/pages/index.ts create mode 100644 frontend/src/features/workspaces/pages/workspaceSettingsPage.tsx create mode 100644 frontend/src/features/workspaces/pages/workspacesPage.tsx rename frontend/src/{common => }/interfaces/repositorySource.enum.ts (100%) delete mode 100644 frontend/src/modules/layout/index.ts delete mode 100644 frontend/src/pages/private/workflows/index.ts delete mode 100644 frontend/src/pages/private/workflows/workflows/workflowsPage.component.tsx delete mode 100644 frontend/src/pages/private/workflows/workflowsEditor/workflowsEditorPage.component.tsx delete mode 100644 frontend/src/pages/private/workspaces/index.ts delete mode 100644 frontend/src/pages/private/workspaces/workspaceSettings/workspaceSettingsPage.component.tsx rename frontend/src/{modules/app/app.component.tsx => providers/app.tsx} (88%) rename frontend/src/{modules/app => providers}/theme.config.ts (100%) rename frontend/src/{modules/app/router/applicationRoutes.component.tsx => routes/index.tsx} (81%) rename frontend/src/{modules/app/router/privateRoute.component.tsx => routes/privateRoute.tsx} (95%) rename frontend/src/{modules/app/router/publicRoute.component.tsx => routes/publicRoute.tsx} (100%) create mode 100644 frontend/src/utils/lazyImports.ts diff --git a/frontend/src/common/hocs/withContext.hoc.tsx b/frontend/src/common/hocs/withContext.hoc.tsx deleted file mode 100644 index 5e14f64e..00000000 --- a/frontend/src/common/hocs/withContext.hoc.tsx +++ /dev/null @@ -1,17 +0,0 @@ -import { type FC, memo } from "react"; - -export function withContext

(Provider: FC

, Component: FC

): FC

{ - const MemoizedComponent = memo(Component); - /** - * @todo solve as any type - */ - const WithContext: FC

= (props) => { - return ( - - - - ); - }; - - return WithContext; -} diff --git a/frontend/src/common/interfaces/environment.interface.ts b/frontend/src/common/interfaces/environment.interface.ts deleted file mode 100644 index 39ab48df..00000000 --- a/frontend/src/common/interfaces/environment.interface.ts +++ /dev/null @@ -1,11 +0,0 @@ -/** - * @todo add other envs when available - */ -export type INodeEnv = "development"; -export type IApiEnv = "local" | "dev" | "prod"; - -export interface IEnvironment { - NODE_ENV: INodeEnv; - API_ENV: IApiEnv; - USE_MOCK: boolean; -} diff --git a/frontend/src/common/schemas/storageSchemas.ts b/frontend/src/common/schemas/storageSchemas.ts deleted file mode 100644 index 0fc0c735..00000000 --- a/frontend/src/common/schemas/storageSchemas.ts +++ /dev/null @@ -1,11 +0,0 @@ -export const operatorStorageSchema = { - type: "object", - properties: { - storageAccessMode: { - title: "Access Mode", - type: "string", - enum: ["None", "Read", "Read/Write"], - default: "Read/Write", - }, - }, -}; diff --git a/frontend/src/common/schemas/workflowFormSchema.ts b/frontend/src/common/schemas/workflowFormSchema.ts deleted file mode 100644 index a179487f..00000000 --- a/frontend/src/common/schemas/workflowFormSchema.ts +++ /dev/null @@ -1,137 +0,0 @@ -export const workflowFormSchema = { - type: "object", - title: "workflowForm", - properties: { - config: { - type: "object", - title: "Config", - properties: { - name: { - title: "Name", - type: "string", - minLength: 3, - description: "Workflow Name", - }, - schedule_interval: { - title: "Schedule Interval", - type: "string", - enum: [ - "none", - "once", - "hourly", - "daily", - "weekly", - "monthly", - "yearly", - ], - default: "none", - }, - start_date: { - title: "Start Date", - type: "string", - format: "date", - }, - generate_report: { - title: "Generate Report", - type: "boolean", - default: false, - description: "[description]", - }, - }, - required: ["name", "start_date", "schedule_interval"], - }, - // Why object schemas is not separating the forms in two section as before? - storage: { - type: "object", - title: "Storage", - properties: { - source: { - title: "Storage Source", - type: "string", - enum: - process.env.REACT_APP_DOMINO_DEPLOY_MODE === "local-compose" - ? ["None", "Local"] - : ["None", "AWS S3"], - default: "None", - }, - baseFolder: { - title: "Base folder", - type: "string", - description: "Base folder from source storage.", - default: "", - }, - bucket: { - title: "Bucket name", - type: "string", - description: "Name for the S3 Bucket.", - }, - }, - required: ["source"], - }, - }, -}; - -export const workflowFormUISchema = { - type: "VerticalLayout", - elements: [ - { - type: "Group", - label: "Settings", - elements: [ - { - type: "Control", - scope: "#/properties/config/properties/name", - }, - { - type: "Control", - scope: "#/properties/config/properties/schedule_interval", - }, - { - type: "Control", - scope: "#/properties/config/properties/start_date", - }, - { - type: "Control", - scope: "#/properties/config/properties/generate_report", - }, - ], - }, - // TODO check why group label font size is small - { - type: "Group", - label: "Storage", - elements: [ - { - type: "Control", - scope: "#/properties/storage/properties/source", - }, - { - type: "Control", - scope: "#/properties/storage/properties/baseFolder", - rule: { - effect: "SHOW", - condition: { - scope: "#/properties/storage/properties/source", - schema: { - enum: ["AWS S3"], - }, - }, - }, - }, - { - type: "Control", - scope: "#/properties/storage/properties/bucket", - rule: { - effect: "SHOW", - condition: { - scope: "#/properties/storage/properties/source", - schema: { - enum: ["AWS S3"], - }, - }, - }, - }, - ], - }, - ], -}; diff --git a/frontend/src/components/checkboxInput.tsx b/frontend/src/components/CheckboxInput/index.tsx similarity index 100% rename from frontend/src/components/checkboxInput.tsx rename to frontend/src/components/CheckboxInput/index.tsx diff --git a/frontend/src/components/codeeditorInput.tsx b/frontend/src/components/CodeEditorInput/index.tsx similarity index 100% rename from frontend/src/components/codeeditorInput.tsx rename to frontend/src/components/CodeEditorInput/index.tsx diff --git a/frontend/src/pages/private/workflows/workflowsEditor/components/customNode.component.tsx b/frontend/src/components/CustomNode/index.tsx similarity index 100% rename from frontend/src/pages/private/workflows/workflowsEditor/components/customNode.component.tsx rename to frontend/src/components/CustomNode/index.tsx diff --git a/frontend/src/components/datetimeInput.tsx b/frontend/src/components/DatetimeInput/index.tsx similarity index 100% rename from frontend/src/components/datetimeInput.tsx rename to frontend/src/components/DatetimeInput/index.tsx diff --git a/frontend/src/components/numberInput.tsx b/frontend/src/components/NumberInput/index.tsx similarity index 100% rename from frontend/src/components/numberInput.tsx rename to frontend/src/components/NumberInput/index.tsx diff --git a/frontend/src/modules/layout/privateLayout/header/drawerMenu.style.ts b/frontend/src/components/PrivateLayout/header/drawerMenu.style.ts similarity index 100% rename from frontend/src/modules/layout/privateLayout/header/drawerMenu.style.ts rename to frontend/src/components/PrivateLayout/header/drawerMenu.style.ts diff --git a/frontend/src/modules/layout/privateLayout/header/drawerMenu.component.tsx b/frontend/src/components/PrivateLayout/header/drawerMenu.tsx similarity index 96% rename from frontend/src/modules/layout/privateLayout/header/drawerMenu.component.tsx rename to frontend/src/components/PrivateLayout/header/drawerMenu.tsx index 64cf625d..b9c6dfe1 100644 --- a/frontend/src/modules/layout/privateLayout/header/drawerMenu.component.tsx +++ b/frontend/src/components/PrivateLayout/header/drawerMenu.tsx @@ -18,12 +18,12 @@ import { useTheme, } from "@mui/material"; import { useAuthentication } from "context/authentication"; -import { useWorkspaces } from "context/workspaces/workspaces.context"; +import { useWorkspaces } from "context/workspaces"; import { type FC } from "react"; import { useLocation, useNavigate } from "react-router-dom"; import { AppBar, Drawer, DrawerHeader } from "./drawerMenu.style"; -import { DrawerMenuItem } from "./drawerMenuItem.component"; +import { DrawerMenuItem } from "./drawerMenuItem"; interface IDrawerMenuProps { isOpen: boolean; diff --git a/frontend/src/modules/layout/privateLayout/header/drawerMenuItem.component.tsx b/frontend/src/components/PrivateLayout/header/drawerMenuItem.tsx similarity index 100% rename from frontend/src/modules/layout/privateLayout/header/drawerMenuItem.component.tsx rename to frontend/src/components/PrivateLayout/header/drawerMenuItem.tsx diff --git a/frontend/src/modules/layout/privateLayout/header/header.component.tsx b/frontend/src/components/PrivateLayout/header/header.tsx similarity index 90% rename from frontend/src/modules/layout/privateLayout/header/header.component.tsx rename to frontend/src/components/PrivateLayout/header/header.tsx index 481255a7..d96bdf06 100644 --- a/frontend/src/modules/layout/privateLayout/header/header.component.tsx +++ b/frontend/src/components/PrivateLayout/header/header.tsx @@ -1,7 +1,7 @@ import { Box } from "@mui/material"; import { type FC, useRef, useState } from "react"; -import { DrawerMenu } from "./drawerMenu.component"; +import { DrawerMenu } from "./drawerMenu"; export const Header: FC = () => { const [menuOpen, setMenuOpen] = useState(false); diff --git a/frontend/src/modules/layout/privateLayout/privateLayout.component.tsx b/frontend/src/components/PrivateLayout/index.tsx similarity index 91% rename from frontend/src/modules/layout/privateLayout/privateLayout.component.tsx rename to frontend/src/components/PrivateLayout/index.tsx index 94928f59..6115dcc8 100644 --- a/frontend/src/modules/layout/privateLayout/privateLayout.component.tsx +++ b/frontend/src/components/PrivateLayout/index.tsx @@ -1,7 +1,7 @@ import { Box, Container } from "@mui/material"; import { type FC, type ReactNode } from "react"; -import { Header } from "./header/header.component"; +import { Header } from "./header/header"; interface IPrivateLayoutProps { children: ReactNode; diff --git a/frontend/src/modules/layout/publicLayout/publicLayout.component.tsx b/frontend/src/components/PublicLayout/index.tsx similarity index 100% rename from frontend/src/modules/layout/publicLayout/publicLayout.component.tsx rename to frontend/src/components/PublicLayout/index.tsx diff --git a/frontend/src/components/selectInput.tsx b/frontend/src/components/SelectInput/index.tsx similarity index 100% rename from frontend/src/components/selectInput.tsx rename to frontend/src/components/SelectInput/index.tsx diff --git a/frontend/src/components/textInput.tsx b/frontend/src/components/TextInput/index.tsx similarity index 100% rename from frontend/src/components/textInput.tsx rename to frontend/src/components/TextInput/index.tsx diff --git a/frontend/src/common/config/environment.config.ts b/frontend/src/config/environment.config.ts similarity index 52% rename from frontend/src/common/config/environment.config.ts rename to frontend/src/config/environment.config.ts index ccbcc867..34ddba98 100644 --- a/frontend/src/common/config/environment.config.ts +++ b/frontend/src/config/environment.config.ts @@ -1,8 +1,14 @@ -import { - type IEnvironment, - type INodeEnv, - type IApiEnv, -} from "common/interfaces/environment.interface"; +/** + * @todo add other envs when available + */ +export type INodeEnv = "development"; +export type IApiEnv = "local" | "dev" | "prod"; + +export interface IEnvironment { + NODE_ENV: INodeEnv; + API_ENV: IApiEnv; + USE_MOCK: boolean; +} /** * Stores all environment variables for easier access diff --git a/frontend/src/context/workflows/workflowsEditor.context/providerContextWrapper.tsx b/frontend/src/context/workflows/workflowsEditor.context/providerContextWrapper.tsx deleted file mode 100644 index 671a65f1..00000000 --- a/frontend/src/context/workflows/workflowsEditor.context/providerContextWrapper.tsx +++ /dev/null @@ -1,28 +0,0 @@ -import PiecesProvider from "./pieces.context"; -import WorkflowsEdgesProvider from "./workflowEdges.context"; -import WorkflowsNodesProvider from "./workflowNodes.context"; -import WorkflowPiecesProvider from "./workflowPieces.context"; -import WorkflowPiecesDataProvider from "./workflowPiecesData.context"; -import WorkflowSettingsDataProvider from "./workflowSettingsData.context"; - -const ProviderContextWrapper: React.FC<{ children: React.ReactNode }> = ({ - children, -}) => { - return ( - - - - - - - {children} - - - - - - - ); -}; - -export default ProviderContextWrapper; diff --git a/frontend/src/context/workspaces/workspaces.context.tsx b/frontend/src/context/workspaces/index.tsx similarity index 100% rename from frontend/src/context/workspaces/workspaces.context.tsx rename to frontend/src/context/workspaces/index.tsx diff --git a/frontend/src/pages/public/signIn/signInPage.component.tsx b/frontend/src/features/auth/pages/signIn/signInPage.tsx similarity index 97% rename from frontend/src/pages/public/signIn/signInPage.component.tsx rename to frontend/src/features/auth/pages/signIn/signInPage.tsx index 2e30e1f3..7bc479c6 100644 --- a/frontend/src/pages/public/signIn/signInPage.component.tsx +++ b/frontend/src/features/auth/pages/signIn/signInPage.tsx @@ -1,7 +1,7 @@ import { Box, Button, Grid, Typography, Link as LinkMui } from "@mui/material"; -import TextInput from "components/textInput"; +import PublicLayout from "components/PublicLayout"; +import TextInput from "components/TextInput"; import { useAuthentication } from "context/authentication"; -import { PublicLayout } from "modules/layout"; import { type FC, useCallback } from "react"; import { FormProvider, useForm } from "react-hook-form"; import { Link } from "react-router-dom"; diff --git a/frontend/src/pages/public/signUp/signUpPage.component.tsx b/frontend/src/features/auth/pages/signUp/signUpPage.tsx similarity index 97% rename from frontend/src/pages/public/signUp/signUpPage.component.tsx rename to frontend/src/features/auth/pages/signUp/signUpPage.tsx index f1e85ca3..6fe9dcba 100644 --- a/frontend/src/pages/public/signUp/signUpPage.component.tsx +++ b/frontend/src/features/auth/pages/signUp/signUpPage.tsx @@ -6,9 +6,9 @@ import { CircularProgress, Link as LinkMui, } from "@mui/material"; -import TextInput from "components/textInput"; +import PublicLayout from "components/PublicLayout"; +import TextInput from "components/TextInput"; import { useAuthentication } from "context/authentication"; -import { PublicLayout } from "modules/layout"; import { type FC, useCallback } from "react"; import { FormProvider, useForm } from "react-hook-form"; import { Link } from "react-router-dom"; diff --git a/frontend/src/pages/private/workflows/workflowsEditor/components/drawerMenuComponent.tsx b/frontend/src/features/workflowEditor/components/DrawerMenu/index.tsx similarity index 93% rename from frontend/src/pages/private/workflows/workflowsEditor/components/drawerMenuComponent.tsx rename to frontend/src/features/workflowEditor/components/DrawerMenu/index.tsx index 52658a0e..e1bc7979 100644 --- a/frontend/src/pages/private/workflows/workflowsEditor/components/drawerMenuComponent.tsx +++ b/frontend/src/features/workflowEditor/components/DrawerMenu/index.tsx @@ -14,10 +14,10 @@ import { import { Drawer, DrawerHeader, -} from "modules/layout/privateLayout/header/drawerMenu.style"; +} from "components/PrivateLayout/header/drawerMenu.style"; import { type FC, type ReactNode, useState } from "react"; -import SidebarAddNode from "./sidebarAddNode.component"; +import SidebarAddNode from "./sidebarAddNode"; interface PermanentDrawerRightWorkflowsProps { isOpen?: boolean; diff --git a/frontend/src/pages/private/workflows/workflowsEditor/components/pieceDocsPopover.component.tsx b/frontend/src/features/workflowEditor/components/DrawerMenu/pieceDocsPopover.tsx similarity index 100% rename from frontend/src/pages/private/workflows/workflowsEditor/components/pieceDocsPopover.component.tsx rename to frontend/src/features/workflowEditor/components/DrawerMenu/pieceDocsPopover.tsx diff --git a/frontend/src/pages/private/workflows/workflowsEditor/components/sidebarAddNode.component.tsx b/frontend/src/features/workflowEditor/components/DrawerMenu/sidebarAddNode.tsx similarity index 97% rename from frontend/src/pages/private/workflows/workflowsEditor/components/sidebarAddNode.component.tsx rename to frontend/src/features/workflowEditor/components/DrawerMenu/sidebarAddNode.tsx index ec3972dd..c3a329c7 100644 --- a/frontend/src/pages/private/workflows/workflowsEditor/components/sidebarAddNode.component.tsx +++ b/frontend/src/features/workflowEditor/components/DrawerMenu/sidebarAddNode.tsx @@ -9,11 +9,11 @@ import { ToggleButtonGroup, Typography, } from "@mui/material"; -import { useWorkflowsEditor } from "context/workflows/workflowsEditor.context"; +import { useWorkflowsEditor } from "features/workflowEditor/context/workflowsEditor"; import { type FC, type SyntheticEvent, useState } from "react"; import { type IOperator } from "services/requests/piece"; -import PiecesSidebarNode from "./sidebarNode.component"; +import PiecesSidebarNode from "./sidebarNode"; /** * @todo cleanup comments when no longer needed diff --git a/frontend/src/pages/private/workflows/workflowsEditor/components/sidebarNode.component.tsx b/frontend/src/features/workflowEditor/components/DrawerMenu/sidebarNode.tsx similarity index 96% rename from frontend/src/pages/private/workflows/workflowsEditor/components/sidebarNode.component.tsx rename to frontend/src/features/workflowEditor/components/DrawerMenu/sidebarNode.tsx index fa3fbd61..6aff2a7f 100644 --- a/frontend/src/pages/private/workflows/workflowsEditor/components/sidebarNode.component.tsx +++ b/frontend/src/features/workflowEditor/components/DrawerMenu/sidebarNode.tsx @@ -3,7 +3,7 @@ import { Box, Typography, IconButton } from "@mui/material"; import React, { type FC, useState } from "react"; import { type IOperator } from "services/requests/piece"; -import PieceDocsPopover from "./pieceDocsPopover.component"; +import PieceDocsPopover from "./pieceDocsPopover"; const PiecesSidebarNode: FC<{ operator: IOperator }> = ({ operator }) => { const [popoverOpen, setPopoverOpen] = useState(false); diff --git a/frontend/src/pages/private/workflows/workflowsEditor/components/sidebarSettingsForm.component.tsx b/frontend/src/features/workflowEditor/components/SidebarSettingsForm/index.tsx similarity index 96% rename from frontend/src/pages/private/workflows/workflowsEditor/components/sidebarSettingsForm.component.tsx rename to frontend/src/features/workflowEditor/components/SidebarSettingsForm/index.tsx index c8098f26..802bc22f 100644 --- a/frontend/src/pages/private/workflows/workflowsEditor/components/sidebarSettingsForm.component.tsx +++ b/frontend/src/features/workflowEditor/components/SidebarSettingsForm/index.tsx @@ -1,7 +1,8 @@ import { Drawer, Grid, Typography, TextField } from "@mui/material"; -import DatetimeInput from "components/datetimeInput"; -import SelectInput from "components/selectInput"; -import TextInput from "components/textInput"; +import DatetimeInput from "components/DatetimeInput"; +import SelectInput from "components/SelectInput"; +import TextInput from "components/TextInput"; +import dayjs from "dayjs"; import { type EndDateTypes, type IWorkflowSettings, @@ -12,9 +13,8 @@ import { scheduleIntervals, storageSourcesAWS, storageSourcesLocal, -} from "context/workflows/types/settings"; -import { useWorkflowsEditor } from "context/workflows/workflowsEditor.context"; -import dayjs from "dayjs"; +} from "features/workflowEditor/context/types/settings"; +import { useWorkflowsEditor } from "features/workflowEditor/context/workflowsEditor"; import { useCallback, useEffect, useState } from "react"; import { FormProvider, useForm } from "react-hook-form"; import { yupResolver } from "utils"; diff --git a/frontend/src/pages/private/workflows/workflowsEditor/components/workflowEditorPanel.component.tsx b/frontend/src/features/workflowEditor/components/WorkflowEditorPanel/index.tsx similarity index 95% rename from frontend/src/pages/private/workflows/workflowsEditor/components/workflowEditorPanel.component.tsx rename to frontend/src/features/workflowEditor/components/WorkflowEditorPanel/index.tsx index d35a5d62..6af78d6c 100644 --- a/frontend/src/pages/private/workflows/workflowsEditor/components/workflowEditorPanel.component.tsx +++ b/frontend/src/features/workflowEditor/components/WorkflowEditorPanel/index.tsx @@ -1,9 +1,10 @@ -import { containerResourcesSchema } from "common/schemas/containerResourcesSchemas"; +import CustomNode, { type INodeData } from "components/CustomNode"; import { type IWorkflowPieceData, storageAccessModes, -} from "context/workflows/types"; -import { useWorkflowsEditor } from "context/workflows/workflowsEditor.context"; +} from "features/workflowEditor/context/types"; +import { useWorkflowsEditor } from "features/workflowEditor/context/workflowsEditor"; +import { containerResourcesSchema } from "features/workflowEditor/schemas/containerResourcesSchemas"; import React, { useCallback, useEffect, useRef, useState } from "react"; import ReactFlow, { addEdge, @@ -23,9 +24,7 @@ import ReactFlow, { import { extractDefaultValues, extractDefaultInputValues } from "utils"; import { v4 as uuidv4 } from "uuid"; -import CustomNode from "./customNode.component"; -import { type INodeData } from "./customNode.component"; -import SidebarForm from "./sidebarForm.component"; +import SidebarForm from "./sidebarForm"; /** * @todo When change the workspace should we clear the forage ? * @todo Solve any types diff --git a/frontend/src/pages/private/workflows/workflowsEditor/components/sidebarForm.component/containerResourceForm.component.tsx b/frontend/src/features/workflowEditor/components/WorkflowEditorPanel/sidebarForm/containerResourceForm.tsx similarity index 94% rename from frontend/src/pages/private/workflows/workflowsEditor/components/sidebarForm.component/containerResourceForm.component.tsx rename to frontend/src/features/workflowEditor/components/WorkflowEditorPanel/sidebarForm/containerResourceForm.tsx index 7ab7f33b..6bc4a237 100644 --- a/frontend/src/pages/private/workflows/workflowsEditor/components/sidebarForm.component/containerResourceForm.component.tsx +++ b/frontend/src/features/workflowEditor/components/WorkflowEditorPanel/sidebarForm/containerResourceForm.tsx @@ -1,7 +1,7 @@ import { Grid, Typography } from "@mui/material"; -import CheckboxInput from "components/checkboxInput"; -import NumberInput from "components/numberInput"; -import { type IContainerResourceFormData } from "context/workflows/types"; +import CheckboxInput from "components/CheckboxInput"; +import NumberInput from "components/NumberInput"; +import { type IContainerResourceFormData } from "features/workflowEditor/context/types"; import React from "react"; import * as yup from "yup"; diff --git a/frontend/src/pages/private/workflows/workflowsEditor/components/sidebarForm.component/index.tsx b/frontend/src/features/workflowEditor/components/WorkflowEditorPanel/sidebarForm/index.tsx similarity index 95% rename from frontend/src/pages/private/workflows/workflowsEditor/components/sidebarForm.component/index.tsx rename to frontend/src/features/workflowEditor/components/WorkflowEditorPanel/sidebarForm/index.tsx index b32fb221..ee781048 100644 --- a/frontend/src/pages/private/workflows/workflowsEditor/components/sidebarForm.component/index.tsx +++ b/frontend/src/features/workflowEditor/components/WorkflowEditorPanel/sidebarForm/index.tsx @@ -7,8 +7,8 @@ import { AccordionSummary, AccordionDetails, } from "@mui/material"; -import { type IWorkflowPieceData } from "context/workflows/types"; -import { useWorkflowsEditor } from "context/workflows/workflowsEditor.context"; +import { type IWorkflowPieceData } from "features/workflowEditor/context/types"; +import { useWorkflowsEditor } from "features/workflowEditor/context/workflowsEditor"; import React, { useCallback, useEffect, useMemo, useState } from "react"; import { FormProvider, useForm } from "react-hook-form"; import { yupResolver } from "utils"; @@ -16,10 +16,10 @@ import * as yup from "yup"; import ContainerResourceForm, { ContainerResourceFormSchema, -} from "./containerResourceForm.component"; -import PieceForm from "./pieceForm.component"; -import { createInputsSchemaValidation } from "./pieceForm.component/validation"; -import StorageForm, { storageFormSchema } from "./storageForm.component"; +} from "./containerResourceForm"; +import PieceForm from "./pieceForm"; +import { createInputsSchemaValidation } from "./pieceForm/validation"; +import StorageForm, { storageFormSchema } from "./storageForm"; interface ISidebarPieceFormProps { formId: string; diff --git a/frontend/src/pages/private/workflows/workflowsEditor/components/sidebarForm.component/pieceForm.component/index.tsx b/frontend/src/features/workflowEditor/components/WorkflowEditorPanel/sidebarForm/pieceForm/index.tsx similarity index 89% rename from frontend/src/pages/private/workflows/workflowsEditor/components/sidebarForm.component/pieceForm.component/index.tsx rename to frontend/src/features/workflowEditor/components/WorkflowEditorPanel/sidebarForm/pieceForm/index.tsx index deae3677..f8581d4d 100644 --- a/frontend/src/pages/private/workflows/workflowsEditor/components/sidebarForm.component/pieceForm.component/index.tsx +++ b/frontend/src/features/workflowEditor/components/WorkflowEditorPanel/sidebarForm/pieceForm/index.tsx @@ -1,9 +1,9 @@ -import { type IWorkflowPieceData } from "context/workflows/types"; -import { useWorkflowsEditor } from "context/workflows/workflowsEditor.context"; +import { type IWorkflowPieceData } from "features/workflowEditor/context/types"; +import { useWorkflowsEditor } from "features/workflowEditor/context/workflowsEditor"; import React, { useCallback, useEffect, useMemo, useState } from "react"; import { useFormContext } from "react-hook-form"; -import PieceFormItem from "./pieceFormItem.component"; +import PieceFormItem from "./pieceFormItem"; import { type UpstreamOptions, getUpstreamOptions } from "./upstreamOptions"; interface PieceFormProps { diff --git a/frontend/src/pages/private/workflows/workflowsEditor/components/sidebarForm.component/pieceForm.component/pieceFormItem.component/arrayInput.tsx b/frontend/src/features/workflowEditor/components/WorkflowEditorPanel/sidebarForm/pieceForm/pieceFormItem/arrayInput.tsx similarity index 95% rename from frontend/src/pages/private/workflows/workflowsEditor/components/sidebarForm.component/pieceForm.component/pieceFormItem.component/arrayInput.tsx rename to frontend/src/features/workflowEditor/components/WorkflowEditorPanel/sidebarForm/pieceForm/pieceFormItem/arrayInput.tsx index 0f30b442..a8a38b01 100644 --- a/frontend/src/pages/private/workflows/workflowsEditor/components/sidebarForm.component/pieceForm.component/pieceFormItem.component/arrayInput.tsx +++ b/frontend/src/features/workflowEditor/components/WorkflowEditorPanel/sidebarForm/pieceForm/pieceFormItem/arrayInput.tsx @@ -1,16 +1,16 @@ import AddIcon from "@mui/icons-material/Add"; import DeleteIcon from "@mui/icons-material/Delete"; import { Card, CardContent, IconButton, Grid } from "@mui/material"; -import CheckboxInput from "components/checkboxInput"; -import CodeEditorInput from "components/codeeditorInput"; -import DatetimeInput from "components/datetimeInput"; -import NumberInput from "components/numberInput"; -import SelectInput from "components/selectInput"; -import TextInput from "components/textInput"; +import CheckboxInput from "components/CheckboxInput"; +import CodeEditorInput from "components/CodeEditorInput"; +import DatetimeInput from "components/DatetimeInput"; +import NumberInput from "components/NumberInput"; +import SelectInput from "components/SelectInput"; +import TextInput from "components/TextInput"; import { - type IWorkflowPieceData, type InputArray, -} from "context/workflows/types"; + type IWorkflowPieceData, +} from "features/workflowEditor/context/types"; import React, { useCallback, useMemo, useState } from "react"; import { type Control, @@ -20,7 +20,7 @@ import { } from "react-hook-form"; import { getFromUpstream } from "utils"; -import { type ArrayOption } from "../../pieceForm.component/upstreamOptions"; +import { type ArrayOption } from "../../pieceForm/upstreamOptions"; import { disableCheckboxOptions } from "./disableCheckboxOptions"; import ObjectInputComponent from "./objectInput"; diff --git a/frontend/src/pages/private/workflows/workflowsEditor/components/sidebarForm.component/pieceForm.component/pieceFormItem.component/disableCheckboxOptions.ts b/frontend/src/features/workflowEditor/components/WorkflowEditorPanel/sidebarForm/pieceForm/pieceFormItem/disableCheckboxOptions.ts similarity index 100% rename from frontend/src/pages/private/workflows/workflowsEditor/components/sidebarForm.component/pieceForm.component/pieceFormItem.component/disableCheckboxOptions.ts rename to frontend/src/features/workflowEditor/components/WorkflowEditorPanel/sidebarForm/pieceForm/pieceFormItem/disableCheckboxOptions.ts diff --git a/frontend/src/pages/private/workflows/workflowsEditor/components/sidebarForm.component/pieceForm.component/pieceFormItem.component/index.tsx b/frontend/src/features/workflowEditor/components/WorkflowEditorPanel/sidebarForm/pieceForm/pieceFormItem/index.tsx similarity index 91% rename from frontend/src/pages/private/workflows/workflowsEditor/components/sidebarForm.component/pieceForm.component/pieceFormItem.component/index.tsx rename to frontend/src/features/workflowEditor/components/WorkflowEditorPanel/sidebarForm/pieceForm/pieceFormItem/index.tsx index 1a0f2bc2..c34d8423 100644 --- a/frontend/src/pages/private/workflows/workflowsEditor/components/sidebarForm.component/pieceForm.component/pieceFormItem.component/index.tsx +++ b/frontend/src/features/workflowEditor/components/WorkflowEditorPanel/sidebarForm/pieceForm/pieceFormItem/index.tsx @@ -1,18 +1,15 @@ import { Box, Grid } from "@mui/material"; -import CheckboxInput from "components/checkboxInput"; -import CodeEditorInput from "components/codeeditorInput"; -import DatetimeInput from "components/datetimeInput"; -import NumberInput from "components/numberInput"; -import SelectInput from "components/selectInput"; -import TextInput from "components/textInput"; -import { type IWorkflowPieceData } from "context/workflows/types"; +import CheckboxInput from "components/CheckboxInput"; +import CodeEditorInput from "components/CodeEditorInput"; +import DatetimeInput from "components/DatetimeInput"; +import NumberInput from "components/NumberInput"; +import SelectInput from "components/SelectInput"; +import TextInput from "components/TextInput"; +import { type IWorkflowPieceData } from "features/workflowEditor/context/types"; import React, { useMemo } from "react"; import { type Control, useWatch } from "react-hook-form"; -import { - type ArrayOption, - type Option, -} from "../../pieceForm.component/upstreamOptions"; +import { type ArrayOption, type Option } from "../../pieceForm/upstreamOptions"; import ArrayInput from "./arrayInput"; import { disableCheckboxOptions } from "./disableCheckboxOptions"; diff --git a/frontend/src/pages/private/workflows/workflowsEditor/components/sidebarForm.component/pieceForm.component/pieceFormItem.component/objectInput.tsx b/frontend/src/features/workflowEditor/components/WorkflowEditorPanel/sidebarForm/pieceForm/pieceFormItem/objectInput.tsx similarity index 94% rename from frontend/src/pages/private/workflows/workflowsEditor/components/sidebarForm.component/pieceForm.component/pieceFormItem.component/objectInput.tsx rename to frontend/src/features/workflowEditor/components/WorkflowEditorPanel/sidebarForm/pieceForm/pieceFormItem/objectInput.tsx index 766d723c..b95410c5 100644 --- a/frontend/src/pages/private/workflows/workflowsEditor/components/sidebarForm.component/pieceForm.component/pieceFormItem.component/objectInput.tsx +++ b/frontend/src/features/workflowEditor/components/WorkflowEditorPanel/sidebarForm/pieceForm/pieceFormItem/objectInput.tsx @@ -1,12 +1,12 @@ import { Grid } from "@mui/material"; -import CheckboxInput from "components/checkboxInput"; -import SelectInput from "components/selectInput"; -import TextInput from "components/textInput"; +import CheckboxInput from "components/CheckboxInput"; +import SelectInput from "components/SelectInput"; +import TextInput from "components/TextInput"; import React, { useCallback, useMemo, useState } from "react"; import { useWatch } from "react-hook-form"; import { getDefinition } from "utils"; -import { type Option } from "../../pieceForm.component/upstreamOptions"; +import { type Option } from "../../pieceForm/upstreamOptions"; import { disableCheckboxOptions } from "./disableCheckboxOptions"; import SelectUpstreamInput from "./selectUpstreamInput"; diff --git a/frontend/src/pages/private/workflows/workflowsEditor/components/sidebarForm.component/pieceForm.component/pieceFormItem.component/selectUpstreamInput.tsx b/frontend/src/features/workflowEditor/components/WorkflowEditorPanel/sidebarForm/pieceForm/pieceFormItem/selectUpstreamInput.tsx similarity index 94% rename from frontend/src/pages/private/workflows/workflowsEditor/components/sidebarForm.component/pieceForm.component/pieceFormItem.component/selectUpstreamInput.tsx rename to frontend/src/features/workflowEditor/components/WorkflowEditorPanel/sidebarForm/pieceForm/pieceFormItem/selectUpstreamInput.tsx index 8eae5049..ce95d429 100644 --- a/frontend/src/pages/private/workflows/workflowsEditor/components/sidebarForm.component/pieceForm.component/pieceFormItem.component/selectUpstreamInput.tsx +++ b/frontend/src/features/workflowEditor/components/WorkflowEditorPanel/sidebarForm/pieceForm/pieceFormItem/selectUpstreamInput.tsx @@ -6,12 +6,12 @@ import { Select, type SelectChangeEvent, } from "@mui/material"; -import { type IWorkflowPieceData } from "context/workflows/types"; +import { type IWorkflowPieceData } from "features/workflowEditor/context/types"; import React, { useCallback } from "react"; import { Controller, useFormContext } from "react-hook-form"; import { fetchFromObject } from "utils"; -import { type Option } from "../../pieceForm.component/upstreamOptions"; +import { type Option } from "../../pieceForm/upstreamOptions"; type ObjectName = `inputs.${string}.value.${number}.upstreamValue.${string}`; type Name = `inputs.${string}`; diff --git a/frontend/src/pages/private/workflows/workflowsEditor/components/sidebarForm.component/pieceForm.component/upstreamOptions.ts b/frontend/src/features/workflowEditor/components/WorkflowEditorPanel/sidebarForm/pieceForm/upstreamOptions.ts similarity index 100% rename from frontend/src/pages/private/workflows/workflowsEditor/components/sidebarForm.component/pieceForm.component/upstreamOptions.ts rename to frontend/src/features/workflowEditor/components/WorkflowEditorPanel/sidebarForm/pieceForm/upstreamOptions.ts diff --git a/frontend/src/pages/private/workflows/workflowsEditor/components/sidebarForm.component/pieceForm.component/validation.ts b/frontend/src/features/workflowEditor/components/WorkflowEditorPanel/sidebarForm/pieceForm/validation.ts similarity index 100% rename from frontend/src/pages/private/workflows/workflowsEditor/components/sidebarForm.component/pieceForm.component/validation.ts rename to frontend/src/features/workflowEditor/components/WorkflowEditorPanel/sidebarForm/pieceForm/validation.ts diff --git a/frontend/src/pages/private/workflows/workflowsEditor/components/sidebarForm.component/storageForm.component.tsx b/frontend/src/features/workflowEditor/components/WorkflowEditorPanel/sidebarForm/storageForm.tsx similarity index 97% rename from frontend/src/pages/private/workflows/workflowsEditor/components/sidebarForm.component/storageForm.component.tsx rename to frontend/src/features/workflowEditor/components/WorkflowEditorPanel/sidebarForm/storageForm.tsx index 3d45afcd..7e022112 100644 --- a/frontend/src/pages/private/workflows/workflowsEditor/components/sidebarForm.component/storageForm.component.tsx +++ b/frontend/src/features/workflowEditor/components/WorkflowEditorPanel/sidebarForm/storageForm.tsx @@ -12,7 +12,7 @@ import { type IWorkflowPieceData, type StorageAccessModes, storageAccessModes, -} from "context/workflows/types"; +} from "features/workflowEditor/context/types"; import React from "react"; import { Controller, useFormContext } from "react-hook-form"; import * as yup from "yup"; diff --git a/frontend/src/pages/private/workflows/workflowsEditor/components/workflowsEditor.component.tsx b/frontend/src/features/workflowEditor/components/WorkflowsEditor.tsx similarity index 91% rename from frontend/src/pages/private/workflows/workflowsEditor/components/workflowsEditor.component.tsx rename to frontend/src/features/workflowEditor/components/WorkflowsEditor.tsx index 04127939..b590648a 100644 --- a/frontend/src/pages/private/workflows/workflowsEditor/components/workflowsEditor.component.tsx +++ b/frontend/src/features/workflowEditor/components/WorkflowsEditor.tsx @@ -4,21 +4,22 @@ import DownloadIcon from "@mui/icons-material/Download"; import SaveIcon from "@mui/icons-material/Save"; import { Button, Grid, Paper, Backdrop, CircularProgress } from "@mui/material"; import { AxiosError } from "axios"; -import { useWorkflowsEditor } from "context/workflows/workflowsEditor.context"; -import { useWorkspaces } from "context/workspaces/workspaces.context"; +import { useWorkspaces } from "context/workspaces"; import { useCallback, useState } from "react"; import { toast } from "react-toastify"; import { yupResolver } from "utils"; import * as yup from "yup"; -import { PermanentDrawerRightWorkflows } from "./drawerMenuComponent"; -import { ContainerResourceFormSchema } from "./sidebarForm.component/containerResourceForm.component"; -import { createInputsSchemaValidation } from "./sidebarForm.component/pieceForm.component/validation"; -import { storageFormSchema } from "./sidebarForm.component/storageForm.component"; +import { useWorkflowsEditor } from "../context/workflowsEditor"; + +import { PermanentDrawerRightWorkflows } from "./DrawerMenu"; import SidebarSettingsForm, { WorkflowSettingsFormSchema, -} from "./sidebarSettingsForm.component"; -import WorkflowEditorPanelComponent from "./workflowEditorPanel.component"; +} from "./SidebarSettingsForm"; +import WorkflowEditorPanelComponent from "./WorkflowEditorPanel"; +import { ContainerResourceFormSchema } from "./WorkflowEditorPanel/sidebarForm/containerResourceForm"; +import { createInputsSchemaValidation } from "./WorkflowEditorPanel/sidebarForm/pieceForm/validation"; +import { storageFormSchema } from "./WorkflowEditorPanel/sidebarForm/storageForm"; /** * Create workflow tab // TODO refactor/simplify inner files diff --git a/frontend/src/features/workflowEditor/context/types/containerResources.ts b/frontend/src/features/workflowEditor/context/types/containerResources.ts new file mode 100644 index 00000000..5a162d69 --- /dev/null +++ b/frontend/src/features/workflowEditor/context/types/containerResources.ts @@ -0,0 +1,11 @@ +export interface IContainerResourceFormData { + useGpu: boolean; + cpu: { + min: number; + max: number; + }; + memory: { + min: number; + max: number; + }; +} diff --git a/frontend/src/features/workflowEditor/context/types/index.ts b/frontend/src/features/workflowEditor/context/types/index.ts new file mode 100644 index 00000000..087062d5 --- /dev/null +++ b/frontend/src/features/workflowEditor/context/types/index.ts @@ -0,0 +1,4 @@ +export * from "./containerResources"; +export * from "./storage"; +export * from "./workflowPieceData"; +export * from "./input"; diff --git a/frontend/src/features/workflowEditor/context/types/input.ts b/frontend/src/features/workflowEditor/context/types/input.ts new file mode 100644 index 00000000..2edb4035 --- /dev/null +++ b/frontend/src/features/workflowEditor/context/types/input.ts @@ -0,0 +1,24 @@ +import { type Dayjs } from "dayjs"; + +type Value = string | number | boolean | Dayjs; +interface BaseInput { + fromUpstream: boolean; // ? allowed | never | always + upstreamArgument: string; + upstreamId: string; + upstreamValue: string; + value: Value; +} + +export interface ObjectInput { + fromUpstream: Record; + upstreamArgument: Record; + upstreamId: Record; + upstreamValue: Record; + value: Record; +} + +export type InputArray = BaseInput & { + value: BaseInput[] | ObjectInput[]; +}; + +export type Input = BaseInput; diff --git a/frontend/src/features/workflowEditor/context/types/settings.ts b/frontend/src/features/workflowEditor/context/types/settings.ts new file mode 100644 index 00000000..0657c33b --- /dev/null +++ b/frontend/src/features/workflowEditor/context/types/settings.ts @@ -0,0 +1,50 @@ +export enum scheduleIntervals { + None = "none", + Once = "once", + Hourly = "hourly", + Daily = "daily", + Weekly = "weekly", + Monthly = "monthly", + Yearly = "yearly", +} + +export type ScheduleIntervals = `${scheduleIntervals}`; + +export enum endDateTypes { + Never = "never", + UserDefined = "User defined", +} + +export type EndDateTypes = `${endDateTypes}`; + +export enum storageSourcesAWS { + None = "None", + AWSS3 = "AWS S3", +} + +export type StorageSourcesAWS = `${storageSourcesAWS}`; + +export enum storageSourcesLocal { + None = "None", + Local = "Local", +} + +export type StorageSourcesLocal = `${storageSourcesLocal}`; + +export interface IWorkflowSettingsConfig { + name: string; + scheduleInterval: ScheduleIntervals; + startDate: string; + endDate?: string; + endDateType: EndDateTypes; +} + +export interface IWorkflowSettingsStorage { + storageSource: StorageSourcesAWS | StorageSourcesLocal; + baseFolder?: string; + bucket?: string; +} +export interface IWorkflowSettings { + config: IWorkflowSettingsConfig; + storage: IWorkflowSettingsStorage; +} diff --git a/frontend/src/features/workflowEditor/context/types/storage.ts b/frontend/src/features/workflowEditor/context/types/storage.ts new file mode 100644 index 00000000..88708693 --- /dev/null +++ b/frontend/src/features/workflowEditor/context/types/storage.ts @@ -0,0 +1,11 @@ +export enum storageAccessModes { + None = "None", + Read = "Read", + ReadWrite = "Read/Write", +} +// Equivalent to type StorageAccessModes = "None" | "Read" | "Read/Write" +export type StorageAccessModes = `${storageAccessModes}`; + +export interface IStorageFormData { + storageAccessMode: StorageAccessModes; +} diff --git a/frontend/src/features/workflowEditor/context/types/workflowPieceData.ts b/frontend/src/features/workflowEditor/context/types/workflowPieceData.ts new file mode 100644 index 00000000..72b02b85 --- /dev/null +++ b/frontend/src/features/workflowEditor/context/types/workflowPieceData.ts @@ -0,0 +1,72 @@ +import { type Edge } from "reactflow"; +import { type IWorkflowElement } from "services/requests/workflow"; + +import { type IContainerResourceFormData } from "./containerResources"; +import { type InputArray, type Input } from "./input"; +import { + type EndDateTypes, + type ScheduleIntervals, + type StorageSourcesAWS, + type StorageSourcesLocal, +} from "./settings"; +import { type IStorageFormData, type StorageAccessModes } from "./storage"; + +export interface IWorkflowPieceData { + storage: IStorageFormData; + containerResources: IContainerResourceFormData; + inputs: Record; +} + +interface WorkflowBaseSettings { + name: string; + start_date: string; // ISOFormat + select_end_date: EndDateTypes; + schedule_interval: ScheduleIntervals; + + end_date?: string; // ISOFormat + catchup?: boolean; + generate_report?: boolean; + description?: string; +} + +interface UiSchema { + nodes: Record; + edges: Edge[]; +} + +interface WorkflowSharedStorageDataModel { + source: StorageSourcesLocal | StorageSourcesAWS; + base_folder?: string; + mode: StorageAccessModes; + provider_options?: Record; +} + +interface SystemRequirementsModel { + cpu: number; + memory: number; +} +interface ContainerResourcesDataModel { + requests: SystemRequirementsModel; + limits: SystemRequirementsModel; + use_gpu: boolean; +} + +export interface TasksDataModel { + workflow_shared_storage: WorkflowSharedStorageDataModel; + container_resources: ContainerResourcesDataModel; + task_id: string; + piece: { + id: number; + name: string; + }; + piece_input_kwargs: Record; + dependencies?: string[]; +} + +type TasksDict = Record; + +export interface CreateWorkflowRequest { + workflow: WorkflowBaseSettings; + tasks: TasksDict; + ui_schema: UiSchema; +} diff --git a/frontend/src/features/workflowEditor/context/workflowsEditor/index.tsx b/frontend/src/features/workflowEditor/context/workflowsEditor/index.tsx new file mode 100644 index 00000000..0ccfe587 --- /dev/null +++ b/frontend/src/features/workflowEditor/context/workflowsEditor/index.tsx @@ -0,0 +1,35 @@ +import PiecesProvider from "./pieces"; +import WorkflowsEdgesProvider from "./workflowEdges"; +import WorkflowsNodesProvider from "./workflowNodes"; +import WorkflowPiecesProvider from "./workflowPieces"; +import WorkflowPiecesDataProvider from "./workflowPiecesData"; +import WorkflowsEditorProviderItem, { + useWorkflowsEditor, +} from "./workflowsEditor"; +import WorkflowSettingsDataProvider from "./workflowSettingsData"; + +export { useWorkflowsEditor }; + +const WorkflowsEditorProvider: React.FC<{ + children: React.ReactNode; +}> = ({ children }) => { + return ( + + + + + + + + {children} + + + + + + + + ); +}; + +export default WorkflowsEditorProvider; diff --git a/frontend/src/context/workflows/workflowsEditor.context/pieces.context.tsx b/frontend/src/features/workflowEditor/context/workflowsEditor/pieces.tsx similarity index 100% rename from frontend/src/context/workflows/workflowsEditor.context/pieces.context.tsx rename to frontend/src/features/workflowEditor/context/workflowsEditor/pieces.tsx diff --git a/frontend/src/context/workflows/workflowsEditor.context/workflowEdges.context.tsx b/frontend/src/features/workflowEditor/context/workflowsEditor/workflowEdges.tsx similarity index 100% rename from frontend/src/context/workflows/workflowsEditor.context/workflowEdges.context.tsx rename to frontend/src/features/workflowEditor/context/workflowsEditor/workflowEdges.tsx diff --git a/frontend/src/context/workflows/workflowsEditor.context/workflowNodes.context.tsx b/frontend/src/features/workflowEditor/context/workflowsEditor/workflowNodes.tsx similarity index 100% rename from frontend/src/context/workflows/workflowsEditor.context/workflowNodes.context.tsx rename to frontend/src/features/workflowEditor/context/workflowsEditor/workflowNodes.tsx diff --git a/frontend/src/context/workflows/workflowsEditor.context/workflowPieces.context.tsx b/frontend/src/features/workflowEditor/context/workflowsEditor/workflowPieces.tsx similarity index 100% rename from frontend/src/context/workflows/workflowsEditor.context/workflowPieces.context.tsx rename to frontend/src/features/workflowEditor/context/workflowsEditor/workflowPieces.tsx diff --git a/frontend/src/context/workflows/workflowsEditor.context/workflowPiecesData.context.tsx b/frontend/src/features/workflowEditor/context/workflowsEditor/workflowPiecesData.tsx similarity index 100% rename from frontend/src/context/workflows/workflowsEditor.context/workflowPiecesData.context.tsx rename to frontend/src/features/workflowEditor/context/workflowsEditor/workflowPiecesData.tsx diff --git a/frontend/src/context/workflows/workflowsEditor.context/workflowSettingsData.context.tsx b/frontend/src/features/workflowEditor/context/workflowsEditor/workflowSettingsData.tsx similarity index 100% rename from frontend/src/context/workflows/workflowsEditor.context/workflowSettingsData.context.tsx rename to frontend/src/features/workflowEditor/context/workflowsEditor/workflowSettingsData.tsx diff --git a/frontend/src/context/workflows/workflowsEditor.context/index.tsx b/frontend/src/features/workflowEditor/context/workflowsEditor/workflowsEditor.tsx similarity index 94% rename from frontend/src/context/workflows/workflowsEditor.context/index.tsx rename to frontend/src/features/workflowEditor/context/workflowsEditor/workflowsEditor.tsx index 78de53ff..b1318770 100644 --- a/frontend/src/context/workflows/workflowsEditor.context/index.tsx +++ b/frontend/src/features/workflowEditor/context/workflowsEditor/workflowsEditor.tsx @@ -1,4 +1,4 @@ -import { useWorkspaces } from "context/workspaces/workspaces.context"; +import { useWorkspaces } from "context/workspaces"; import React, { type FC, useCallback } from "react"; import { type IPostWorkflowParams, @@ -9,27 +9,24 @@ import { createCustomContext, generateTaskName, getIdSlice } from "utils"; import { type CreateWorkflowRequest, type TasksDataModel } from "../types"; -import { usesPieces, type IPiecesContext } from "./pieces.context"; +import { usesPieces, type IPiecesContext } from "./pieces"; import { useWorkflowsEdges, type IWorkflowsEdgesContext, -} from "./workflowEdges.context"; +} from "./workflowEdges"; import { useWorkflowsNodes, type IWorkflowsNodesContext, -} from "./workflowNodes.context"; -import { - useWorkflowPiece, - type IWorkflowPieceContext, -} from "./workflowPieces.context"; +} from "./workflowNodes"; +import { useWorkflowPiece, type IWorkflowPieceContext } from "./workflowPieces"; import { useWorkflowPiecesData, type IWorkflowPiecesDataContext, -} from "./workflowPiecesData.context"; +} from "./workflowPiecesData"; import { type IWorkflowSettingsContext, useWorkflowSettings, -} from "./workflowSettingsData.context"; +} from "./workflowSettingsData"; interface IWorkflowsEditorContext extends IPiecesContext, @@ -49,7 +46,7 @@ interface IWorkflowsEditorContext export const [WorkflowsEditorContext, useWorkflowsEditor] = createCustomContext("WorkflowsEditor Context"); -export const WorkflowsEditorProvider: FC<{ children?: React.ReactNode }> = ({ +const WorkflowsEditorProvider: FC<{ children?: React.ReactNode }> = ({ children, }) => { const { workspace } = useWorkspaces(); @@ -312,3 +309,5 @@ export const WorkflowsEditorProvider: FC<{ children?: React.ReactNode }> = ({ ); }; + +export default WorkflowsEditorProvider; diff --git a/frontend/src/features/workflowEditor/pages/index.ts b/frontend/src/features/workflowEditor/pages/index.ts new file mode 100644 index 00000000..28528430 --- /dev/null +++ b/frontend/src/features/workflowEditor/pages/index.ts @@ -0,0 +1 @@ +export * from "./workflowEditorPage"; diff --git a/frontend/src/features/workflowEditor/pages/workflowEditorPage.tsx b/frontend/src/features/workflowEditor/pages/workflowEditorPage.tsx new file mode 100644 index 00000000..0ca798b8 --- /dev/null +++ b/frontend/src/features/workflowEditor/pages/workflowEditorPage.tsx @@ -0,0 +1,22 @@ +import { Grid } from "@mui/material"; +import PrivateLayout from "components/PrivateLayout"; + +import { WorkflowsEditorComponent } from "../components/WorkflowsEditor"; +import WorkflowsEditorProvider from "../context/workflowsEditor"; +/** + * Workflows editor page + */ + +export const WorkflowsEditorPage: React.FC = () => { + return ( + + + + + + + + + + ); +}; diff --git a/frontend/src/common/schemas/containerResourcesSchemas.ts b/frontend/src/features/workflowEditor/schemas/containerResourcesSchemas.ts similarity index 100% rename from frontend/src/common/schemas/containerResourcesSchemas.ts rename to frontend/src/features/workflowEditor/schemas/containerResourcesSchemas.ts diff --git a/frontend/src/pages/private/workflows/workflows/components/workflows.component.tsx b/frontend/src/features/workflows/components/Workflows.tsx similarity index 87% rename from frontend/src/pages/private/workflows/workflows/components/workflows.component.tsx rename to frontend/src/features/workflows/components/Workflows.tsx index 708f07ca..1e9b2fb3 100644 --- a/frontend/src/pages/private/workflows/workflows/components/workflows.component.tsx +++ b/frontend/src/features/workflows/components/Workflows.tsx @@ -2,22 +2,17 @@ import LoopIcon from "@mui/icons-material/Loop"; import NavigateNextIcon from "@mui/icons-material/NavigateNext"; import TabContext from "@mui/lab/TabContext"; import { Button, Grid, Typography, Breadcrumbs, Link } from "@mui/material"; -import { withContext } from "common/hocs/withContext.hoc"; -import { - useWorkflows, - WorkflowsProvider, -} from "context/workflows/workflows.context"; -import { useState, useMemo } from "react"; +import { useWorkflows } from "features/workflows/context/workflows"; +import React, { useState, useMemo } from "react"; -import { WorkflowsRunsTable } from "./workflowsRunsTable.component"; -import { WorflowRunTaskFlowchart } from "./workflowsRunTasksFlowchart.component"; -import { WorkflowsTable } from "./workflowsTable.component"; -// Icons +import { WorkflowsRunsTable } from "./WorkflowsRunsTable"; +import { WorkflowRunTaskFlowchart } from "./WorkflowsRunTasksFlowchart"; +import { WorkflowsTable } from "./WorkflowsTable"; /** * @todo continue refactor of SummaryWorkflows */ -export const WorkflowsComponent = withContext(WorkflowsProvider, () => { +export const WorkflowsComponent: React.FC = () => { const [value, setValue] = useState("1"); const { @@ -147,7 +142,7 @@ export const WorkflowsComponent = withContext(WorkflowsProvider, () => { ) : value === "2" ? ( ) : value === "3" ? ( - + ) : ( "" )} @@ -155,4 +150,4 @@ export const WorkflowsComponent = withContext(WorkflowsProvider, () => { ); -}); +}; diff --git a/frontend/src/pages/private/workflows/workflows/components/workflowTaskDetails.component.tsx b/frontend/src/features/workflows/components/WorkflowsRunTasksFlowchart/WorkflowTaskDetails.tsx similarity index 98% rename from frontend/src/pages/private/workflows/workflows/components/workflowTaskDetails.component.tsx rename to frontend/src/features/workflows/components/WorkflowsRunTasksFlowchart/WorkflowTaskDetails.tsx index f867b15f..5b1d8d38 100644 --- a/frontend/src/pages/private/workflows/workflows/components/workflowTaskDetails.component.tsx +++ b/frontend/src/features/workflows/components/WorkflowsRunTasksFlowchart/WorkflowTaskDetails.tsx @@ -3,7 +3,7 @@ import TimelapseIcon from "@mui/icons-material/Timelapse"; import { Grid, List, ListItem, Chip, Typography } from "@mui/material"; import { type IWorkflowRunTasks } from "services/requests/runs"; -import { taskStatesColorMap } from "../../../../../constants"; +import { taskStatesColorMap } from "../../constants"; interface IWorkflowRunTasksExtended extends IWorkflowRunTasks { operatorName: string; diff --git a/frontend/src/pages/private/workflows/workflows/components/workflowTaskLogs.component.tsx b/frontend/src/features/workflows/components/WorkflowsRunTasksFlowchart/WorkflowTaskLogs.tsx similarity index 100% rename from frontend/src/pages/private/workflows/workflows/components/workflowTaskLogs.component.tsx rename to frontend/src/features/workflows/components/WorkflowsRunTasksFlowchart/WorkflowTaskLogs.tsx diff --git a/frontend/src/pages/private/workflows/workflows/components/workflowTaskResult.component.tsx b/frontend/src/features/workflows/components/WorkflowsRunTasksFlowchart/WorkflowTaskResult.tsx similarity index 100% rename from frontend/src/pages/private/workflows/workflows/components/workflowTaskResult.component.tsx rename to frontend/src/features/workflows/components/WorkflowsRunTasksFlowchart/WorkflowTaskResult.tsx diff --git a/frontend/src/pages/private/workflows/workflows/components/workflowsRunTasksFlowchart.component.tsx b/frontend/src/features/workflows/components/WorkflowsRunTasksFlowchart/index.tsx similarity index 96% rename from frontend/src/pages/private/workflows/workflows/components/workflowsRunTasksFlowchart.component.tsx rename to frontend/src/features/workflows/components/WorkflowsRunTasksFlowchart/index.tsx index 413bbc87..28ff20f1 100644 --- a/frontend/src/pages/private/workflows/workflows/components/workflowsRunTasksFlowchart.component.tsx +++ b/frontend/src/features/workflows/components/WorkflowsRunTasksFlowchart/index.tsx @@ -1,17 +1,16 @@ import { Button, Card, Grid, ButtonGroup, CardContent } from "@mui/material"; -import { useWorkflows } from "context/workflows/workflows.context"; +import CustomNode from "components/CustomNode"; import { useCallback, useRef, useState, useEffect } from "react"; import { toast } from "react-toastify"; import ReactFlow, { Background, Controls, ReactFlowProvider } from "reactflow"; - import "reactflow/dist/style.css"; -import { taskStatesColorMap } from "../../../../../constants"; -import CustomNode from "../../workflowsEditor/components/customNode.component"; // todo move to shared +import { taskStatesColorMap } from "../../constants"; +import { useWorkflows } from "../../context/workflows"; -import { TaskDetails } from "./workflowTaskDetails.component"; -import { TaskLogs } from "./workflowTaskLogs.component"; -import { TaskResult } from "./workflowTaskResult.component"; +import { TaskDetails } from "./WorkflowTaskDetails"; +import { TaskLogs } from "./WorkflowTaskLogs"; +import { TaskResult } from "./WorkflowTaskResult"; const nodeTypes = { CustomNode, @@ -43,7 +42,7 @@ const buttonSXActive = { }, }; -export const WorflowRunTaskFlowchart = () => { +export const WorkflowRunTaskFlowchart = () => { const reactFlowWrapper = useRef(null); const [nodes, setNodes] = useState([]); const [edges, setEdges] = useState([]); diff --git a/frontend/src/pages/private/workflows/workflows/components/workflowsRunsTable.component.tsx b/frontend/src/features/workflows/components/WorkflowsRunsTable/index.tsx similarity index 98% rename from frontend/src/pages/private/workflows/workflows/components/workflowsRunsTable.component.tsx rename to frontend/src/features/workflows/components/WorkflowsRunsTable/index.tsx index b04dc6b1..37478d08 100644 --- a/frontend/src/pages/private/workflows/workflows/components/workflowsRunsTable.component.tsx +++ b/frontend/src/features/workflows/components/WorkflowsRunsTable/index.tsx @@ -6,9 +6,10 @@ import { type GridRowId, GridActionsCellItem, } from "@mui/x-data-grid"; -import { useWorkflows } from "context/workflows/workflows.context"; import { useMemo, useCallback, useState, useEffect } from "react"; +import { useWorkflows } from "../../context/workflows"; + export const WorkflowsRunsTable = () => { const [selectionModel, setSelectionModel] = useState([]); const updateTime = 5000; // ms diff --git a/frontend/src/pages/private/workflows/workflows/components/workflowsTable.component.tsx b/frontend/src/features/workflows/components/WorkflowsTable/index.tsx similarity index 99% rename from frontend/src/pages/private/workflows/workflows/components/workflowsTable.component.tsx rename to frontend/src/features/workflows/components/WorkflowsTable/index.tsx index b8814211..d24d9755 100644 --- a/frontend/src/pages/private/workflows/workflows/components/workflowsTable.component.tsx +++ b/frontend/src/features/workflows/components/WorkflowsTable/index.tsx @@ -23,10 +23,11 @@ import { GridActionsCellItem, type GridRowId, } from "@mui/x-data-grid"; -import { useWorkflows } from "context/workflows/workflows.context"; import { useCallback, useEffect, useMemo, useState } from "react"; import { toast } from "react-toastify"; +import { useWorkflows } from "../../context/workflows"; + // import { toast } from "react-toastify"; // import DeleteOutlineIcon from '@mui/icons-material/DeleteOutline'; diff --git a/frontend/src/constants/index.ts b/frontend/src/features/workflows/constants/index.ts similarity index 72% rename from frontend/src/constants/index.ts rename to frontend/src/features/workflows/constants/index.ts index be5488ef..146901d4 100644 --- a/frontend/src/constants/index.ts +++ b/frontend/src/features/workflows/constants/index.ts @@ -14,14 +14,3 @@ export const taskStatesColorMap = { restarting: "#8ee7fd", default: "#ffffff", }; - -export const storageOptions = [ - { - name: "None", - fields: [], - }, - { - name: "AWS s3", - fields: ["AWS Access Key ID"], - }, -]; diff --git a/frontend/src/context/workflows/workflows.context.tsx b/frontend/src/features/workflows/context/workflows/index.tsx similarity index 100% rename from frontend/src/context/workflows/workflows.context.tsx rename to frontend/src/features/workflows/context/workflows/index.tsx diff --git a/frontend/src/features/workflows/pages/index.ts b/frontend/src/features/workflows/pages/index.ts new file mode 100644 index 00000000..22365253 --- /dev/null +++ b/frontend/src/features/workflows/pages/index.ts @@ -0,0 +1 @@ +export * from "./workflowsPage"; diff --git a/frontend/src/features/workflows/pages/workflowsPage.tsx b/frontend/src/features/workflows/pages/workflowsPage.tsx new file mode 100644 index 00000000..25572aee --- /dev/null +++ b/frontend/src/features/workflows/pages/workflowsPage.tsx @@ -0,0 +1,18 @@ +import PrivateLayout from "components/PrivateLayout"; + +import { WorkflowsComponent } from "../components/Workflows"; +import { WorkflowsProvider } from "../context/workflows"; + +/** + * Workflows summary page + */ + +export const WorkflowsPage: React.FC = () => { + return ( + + + + + + ); +}; diff --git a/frontend/src/pages/private/workspaces/workspaceSettings/components/repositoriesCard.component.tsx b/frontend/src/features/workspaces/components/workspaceSettings/RepositoriesCard.tsx similarity index 98% rename from frontend/src/pages/private/workspaces/workspaceSettings/components/repositoriesCard.component.tsx rename to frontend/src/features/workspaces/components/workspaceSettings/RepositoriesCard.tsx index fb16e806..dc53ae8b 100644 --- a/frontend/src/pages/private/workspaces/workspaceSettings/components/repositoriesCard.component.tsx +++ b/frontend/src/features/workspaces/components/workspaceSettings/RepositoriesCard.tsx @@ -28,12 +28,13 @@ import { Tooltip, } from "@mui/material"; import TextField from "@mui/material/TextField"; -import { ERepositorySource } from "common/interfaces/repositorySource.enum"; -import { useWorkspaceSettings } from "context/workspaces/workspaceSettings.context"; +import { ERepositorySource } from "interfaces/repositorySource.enum"; import { type FC, type ReactNode, useCallback, useMemo, useState } from "react"; import { toast } from "react-toastify"; import { type IOperatorRepositoryMetadata } from "services/requests/piece"; +import { useWorkspaceSettings } from "../../context/workspaceSettings"; + /** * @todo this file is growing too much, maybe it's time to split into smaller components * @todo add more repo options (sync this info with backend) diff --git a/frontend/src/pages/private/workspaces/workspaceSettings/components/repositorySecretsCard.component.tsx b/frontend/src/features/workspaces/components/workspaceSettings/SecretsCard.tsx similarity index 100% rename from frontend/src/pages/private/workspaces/workspaceSettings/components/repositorySecretsCard.component.tsx rename to frontend/src/features/workspaces/components/workspaceSettings/SecretsCard.tsx diff --git a/frontend/src/pages/private/workspaces/workspaceSettings/components/storageSecretsCard.component.tsx b/frontend/src/features/workspaces/components/workspaceSettings/StorageSecretsCard.tsx similarity index 98% rename from frontend/src/pages/private/workspaces/workspaceSettings/components/storageSecretsCard.component.tsx rename to frontend/src/features/workspaces/components/workspaceSettings/StorageSecretsCard.tsx index 9542fcc2..a7bd4c54 100644 --- a/frontend/src/pages/private/workspaces/workspaceSettings/components/storageSecretsCard.component.tsx +++ b/frontend/src/features/workspaces/components/workspaceSettings/StorageSecretsCard.tsx @@ -15,7 +15,6 @@ import { IconButton, Alert, } from "@mui/material"; -import { useWorkspaceSettings } from "context/workspaces/workspaceSettings.context"; import { useState, useCallback, useMemo, useEffect } from "react"; import { useForm } from "react-hook-form"; import { toast } from "react-toastify"; @@ -24,6 +23,8 @@ import { useAuthenticatedPatchRepositorySecret, } from "services/requests/repository"; +import { useWorkspaceSettings } from "../../context/workspaceSettings"; + /* eslint-disable react/prop-types */ const StorageSecretsCard = () => { const filledDefaultValue = "******"; diff --git a/frontend/src/pages/private/workspaces/workspaceSettings/components/usersCard.component.tsx b/frontend/src/features/workspaces/components/workspaceSettings/UsersCard.tsx similarity index 95% rename from frontend/src/pages/private/workspaces/workspaceSettings/components/usersCard.component.tsx rename to frontend/src/features/workspaces/components/workspaceSettings/UsersCard.tsx index 056036dd..6e7b88e5 100644 --- a/frontend/src/pages/private/workspaces/workspaceSettings/components/usersCard.component.tsx +++ b/frontend/src/features/workspaces/components/workspaceSettings/UsersCard.tsx @@ -13,11 +13,12 @@ import { FormControl, } from "@mui/material"; import TextField from "@mui/material/TextField"; -import { useWorkspaces } from "context/workspaces/workspaces.context"; -import { useWorkspaceSettings } from "context/workspaces/workspaceSettings.context"; +import { useWorkspaces } from "context/workspaces"; import { type FC, useCallback, useState } from "react"; import { toast } from "react-toastify"; +import { useWorkspaceSettings } from "../../context/workspaceSettings"; + /** * @todo integrate with backend * @returns Users card component diff --git a/frontend/src/pages/private/workspaces/workspaceSettings/components/workspaceUsersCard.component.tsx b/frontend/src/features/workspaces/components/workspaceSettings/WorkspaceMembersCard.tsx similarity index 98% rename from frontend/src/pages/private/workspaces/workspaceSettings/components/workspaceUsersCard.component.tsx rename to frontend/src/features/workspaces/components/workspaceSettings/WorkspaceMembersCard.tsx index 5db212d9..6d01082c 100644 --- a/frontend/src/pages/private/workspaces/workspaceSettings/components/workspaceUsersCard.component.tsx +++ b/frontend/src/features/workspaces/components/workspaceSettings/WorkspaceMembersCard.tsx @@ -18,7 +18,7 @@ import { type GridColumns, GridActionsCellItem, } from "@mui/x-data-grid"; -import { useWorkspaces } from "context/workspaces/workspaces.context"; +import { useWorkspaces } from "context/workspaces"; import { useState, useMemo, useCallback } from "react"; const WorkspaceMembersCard = () => { diff --git a/frontend/src/pages/private/workspaces/workspaceSettings/components/workspaceSecretsCard.component.tsx b/frontend/src/features/workspaces/components/workspaceSettings/WorkspaceSecretsCard.tsx similarity index 97% rename from frontend/src/pages/private/workspaces/workspaceSettings/components/workspaceSecretsCard.component.tsx rename to frontend/src/features/workspaces/components/workspaceSettings/WorkspaceSecretsCard.tsx index f4048309..bef9251e 100644 --- a/frontend/src/pages/private/workspaces/workspaceSettings/components/workspaceSecretsCard.component.tsx +++ b/frontend/src/features/workspaces/components/workspaceSettings/WorkspaceSecretsCard.tsx @@ -14,13 +14,14 @@ import { Tooltip, IconButton, } from "@mui/material"; -import { useWorkspaces } from "context/workspaces/workspaces.context"; -import { useWorkspaceSettings } from "context/workspaces/workspaceSettings.context"; +import { useWorkspaces } from "context/workspaces"; import { useState, useCallback, useEffect } from "react"; import { useForm } from "react-hook-form"; import { toast } from "react-toastify"; import { useAuthenticatedPatchWorkspace } from "services/requests/workspaces"; +import { useWorkspaceSettings } from "../../context/workspaceSettings"; + /* eslint-disable react/prop-types */ const WorkspaceSecretsCard = () => { // const filledDefaultValue = '******' diff --git a/frontend/src/features/workspaces/components/workspaceSettings/index.tsx b/frontend/src/features/workspaces/components/workspaceSettings/index.tsx new file mode 100644 index 00000000..94776ec5 --- /dev/null +++ b/frontend/src/features/workspaces/components/workspaceSettings/index.tsx @@ -0,0 +1,89 @@ +import TabContext from "@mui/lab/TabContext"; +import TabList from "@mui/lab/TabList"; +import TabPanel from "@mui/lab/TabPanel"; +import { Box, Grid, Typography } from "@mui/material"; +import Tab from "@mui/material/Tab"; +import PrivateLayout from "components/PrivateLayout"; +import { useState } from "react"; + +import { useWorkspaceSettings } from "../../context/workspaceSettings"; + +import { RepositoriesCard } from "./RepositoriesCard"; +import SecretsCard from "./SecretsCard"; +import StorageSecretsCard from "./StorageSecretsCard"; +import { UsersCard } from "./UsersCard"; +import WorkspaceMembersCard from "./WorkspaceMembersCard"; +import WorkspaceSecretsCard from "./WorkspaceSecretsCard"; + +const WorkspaceSettingsComponent = () => { + const { workspace, selectedRepositoryId } = useWorkspaceSettings(); + + const [value, setValue] = useState("1"); + + return ( + + + + + Workspace: {workspace?.workspace_name} + + + + + { + setValue(newValue); + }} + aria-label="workspace-tabs" + > + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ); +}; + +export default WorkspaceSettingsComponent; diff --git a/frontend/src/pages/private/workspaces/workspaces/components/addWorkspace.component.tsx b/frontend/src/features/workspaces/components/workspaces/AddWorkspace.tsx similarity index 96% rename from frontend/src/pages/private/workspaces/workspaces/components/addWorkspace.component.tsx rename to frontend/src/features/workspaces/components/workspaces/AddWorkspace.tsx index 74a071b2..e89cd0f3 100644 --- a/frontend/src/pages/private/workspaces/workspaces/components/addWorkspace.component.tsx +++ b/frontend/src/features/workspaces/components/workspaces/AddWorkspace.tsx @@ -8,7 +8,7 @@ import { CircularProgress, } from "@mui/material"; import TextField from "@mui/material/TextField"; -import { useWorkspaces } from "context/workspaces/workspaces.context"; +import { useWorkspaces } from "context/workspaces"; import { type FC, useCallback, useState } from "react"; export const AddWorkspace: FC = () => { diff --git a/frontend/src/pages/private/workspaces/workspaces/components/item.component.tsx b/frontend/src/features/workspaces/components/workspaces/WorkspaceListItem.tsx similarity index 100% rename from frontend/src/pages/private/workspaces/workspaces/components/item.component.tsx rename to frontend/src/features/workspaces/components/workspaces/WorkspaceListItem.tsx diff --git a/frontend/src/pages/private/workspaces/workspaces/components/pendingItem.component.tsx b/frontend/src/features/workspaces/components/workspaces/WorkspacePendingListItem.tsx similarity index 97% rename from frontend/src/pages/private/workspaces/workspaces/components/pendingItem.component.tsx rename to frontend/src/features/workspaces/components/workspaces/WorkspacePendingListItem.tsx index f32da43d..d7d84d40 100644 --- a/frontend/src/pages/private/workspaces/workspaces/components/pendingItem.component.tsx +++ b/frontend/src/features/workspaces/components/workspaces/WorkspacePendingListItem.tsx @@ -8,7 +8,7 @@ import { Button, Grid, } from "@mui/material"; -import { useWorkspaces } from "context/workspaces/workspaces.context"; +import { useWorkspaces } from "context/workspaces"; import { type FC } from "react"; import { type IWorkspaceSummary } from "services/requests/workspaces"; diff --git a/frontend/src/pages/private/workspaces/workspaces/workspacesPage.component.tsx b/frontend/src/features/workspaces/components/workspaces/index.tsx similarity index 93% rename from frontend/src/pages/private/workspaces/workspaces/workspacesPage.component.tsx rename to frontend/src/features/workspaces/components/workspaces/index.tsx index 584d851b..7f09ddb4 100644 --- a/frontend/src/pages/private/workspaces/workspaces/workspacesPage.component.tsx +++ b/frontend/src/features/workspaces/components/workspaces/index.tsx @@ -9,21 +9,21 @@ import { DialogTitle, Button, } from "@mui/material"; +import PrivateLayout from "components/PrivateLayout"; import { useAuthentication } from "context/authentication"; -import { useWorkspaces } from "context/workspaces/workspaces.context"; -import { PrivateLayout } from "modules/layout"; +import { useWorkspaces } from "context/workspaces"; import { type FC, useCallback, useState } from "react"; -import { AddWorkspace } from "./components/addWorkspace.component"; -import { WorkspaceListItem } from "./components/item.component"; -import { WorkspacePendingListItem } from "./components/pendingItem.component"; +import { AddWorkspace } from "./AddWorkspace"; +import { WorkspaceListItem } from "./WorkspaceListItem"; +import { WorkspacePendingListItem } from "./WorkspacePendingListItem"; /** * Workspace list page * @todo handle error/loading/empty * @todo handle add new workspace */ -export const WorkspacesPage: FC = () => { +const WorkspacesComponent: FC = () => { const { workspace, workspaces, @@ -178,3 +178,5 @@ export const WorkspacesPage: FC = () => { ); }; + +export default WorkspacesComponent; diff --git a/frontend/src/context/workspaces/workspaceSettings.context.tsx b/frontend/src/features/workspaces/context/workspaceSettings.tsx similarity index 98% rename from frontend/src/context/workspaces/workspaceSettings.context.tsx rename to frontend/src/features/workspaces/context/workspaceSettings.tsx index 83e03871..f11fe7f8 100644 --- a/frontend/src/context/workspaces/workspaceSettings.context.tsx +++ b/frontend/src/features/workspaces/context/workspaceSettings.tsx @@ -1,3 +1,4 @@ +import { useWorkspaces } from "context/workspaces"; import { type FC, useCallback, useState } from "react"; import { toast } from "react-toastify"; import { @@ -17,8 +18,6 @@ import { } from "services/requests/workspaces"; import { createCustomContext } from "utils"; -import { useWorkspaces } from "./workspaces.context"; - interface IWorkspaceSettingsContext { workspace: IWorkspaceSummary | null; diff --git a/frontend/src/features/workspaces/pages/index.ts b/frontend/src/features/workspaces/pages/index.ts new file mode 100644 index 00000000..0b109e26 --- /dev/null +++ b/frontend/src/features/workspaces/pages/index.ts @@ -0,0 +1,2 @@ +export * from "./workspaceSettingsPage"; +export * from "./workspacesPage"; diff --git a/frontend/src/features/workspaces/pages/workspaceSettingsPage.tsx b/frontend/src/features/workspaces/pages/workspaceSettingsPage.tsx new file mode 100644 index 00000000..d3f887bb --- /dev/null +++ b/frontend/src/features/workspaces/pages/workspaceSettingsPage.tsx @@ -0,0 +1,12 @@ +import React from "react"; + +import WorkspaceSettingsComponent from "../components/workspaceSettings"; +import { WorkspaceSettingsProvider } from "../context/workspaceSettings"; + +export const WorkspaceSettingsPage: React.FC = () => { + return ( + + + + ); +}; diff --git a/frontend/src/features/workspaces/pages/workspacesPage.tsx b/frontend/src/features/workspaces/pages/workspacesPage.tsx new file mode 100644 index 00000000..21d27a64 --- /dev/null +++ b/frontend/src/features/workspaces/pages/workspacesPage.tsx @@ -0,0 +1,7 @@ +import React from "react"; + +import WorkspacesComponent from "../components/workspaces"; + +export const WorkspacesPage: React.FC = () => { + return ; +}; diff --git a/frontend/src/index.tsx b/frontend/src/index.tsx index a12c4262..8220ab9d 100644 --- a/frontend/src/index.tsx +++ b/frontend/src/index.tsx @@ -1,4 +1,4 @@ -import App from "modules/app/app.component"; +import App from "providers/app"; import React from "react"; import ReactDOM from "react-dom/client"; diff --git a/frontend/src/common/interfaces/repositorySource.enum.ts b/frontend/src/interfaces/repositorySource.enum.ts similarity index 100% rename from frontend/src/common/interfaces/repositorySource.enum.ts rename to frontend/src/interfaces/repositorySource.enum.ts diff --git a/frontend/src/modules/layout/index.ts b/frontend/src/modules/layout/index.ts deleted file mode 100644 index 7c12987f..00000000 --- a/frontend/src/modules/layout/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from "./privateLayout/privateLayout.component"; -export * from "./publicLayout/publicLayout.component"; diff --git a/frontend/src/pages/private/workflows/index.ts b/frontend/src/pages/private/workflows/index.ts deleted file mode 100644 index 1e553c83..00000000 --- a/frontend/src/pages/private/workflows/index.ts +++ /dev/null @@ -1,4 +0,0 @@ -export * from "./workflows/workflowsPage.component"; -export * from "./workflowsEditor/workflowsEditorPage.component"; -export * from "./workflows/components/workflows.component"; -export * from "./workflowsEditor/components/workflowsEditor.component"; diff --git a/frontend/src/pages/private/workflows/workflows/workflowsPage.component.tsx b/frontend/src/pages/private/workflows/workflows/workflowsPage.component.tsx deleted file mode 100644 index b76576e8..00000000 --- a/frontend/src/pages/private/workflows/workflows/workflowsPage.component.tsx +++ /dev/null @@ -1,17 +0,0 @@ -import { PrivateLayout } from "modules/layout"; - -import { WorkflowsComponent } from "./components/workflows.component"; - -/** - * Workflows summary page - */ - -export const WorkflowsPage = () => { - return ( - - - - ); -}; - -export default WorkflowsPage; diff --git a/frontend/src/pages/private/workflows/workflowsEditor/workflowsEditorPage.component.tsx b/frontend/src/pages/private/workflows/workflowsEditor/workflowsEditorPage.component.tsx deleted file mode 100644 index 9f52754f..00000000 --- a/frontend/src/pages/private/workflows/workflowsEditor/workflowsEditorPage.component.tsx +++ /dev/null @@ -1,27 +0,0 @@ -import { Grid } from "@mui/material"; -import { WorkflowsEditorProvider } from "context/workflows/workflowsEditor.context"; -import ProviderContextWrapper from "context/workflows/workflowsEditor.context/providerContextWrapper"; -import { PrivateLayout } from "modules/layout"; - -import { WorkflowsEditorComponent } from "./components/workflowsEditor.component"; -/** - * Workflows editor page - */ - -export const WorkflowsEditorPage = () => { - return ( - - - - - - - - - - - - ); -}; - -export default WorkflowsEditorPage; diff --git a/frontend/src/pages/private/workspaces/index.ts b/frontend/src/pages/private/workspaces/index.ts deleted file mode 100644 index 603f7892..00000000 --- a/frontend/src/pages/private/workspaces/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from "./workspaces/workspacesPage.component"; -export * from "./workspaceSettings/workspaceSettingsPage.component"; diff --git a/frontend/src/pages/private/workspaces/workspaceSettings/workspaceSettingsPage.component.tsx b/frontend/src/pages/private/workspaces/workspaceSettings/workspaceSettingsPage.component.tsx deleted file mode 100644 index 84153838..00000000 --- a/frontend/src/pages/private/workspaces/workspaceSettings/workspaceSettingsPage.component.tsx +++ /dev/null @@ -1,93 +0,0 @@ -import TabContext from "@mui/lab/TabContext"; -import TabList from "@mui/lab/TabList"; -import TabPanel from "@mui/lab/TabPanel"; -import { Box, Grid, Typography } from "@mui/material"; -import Tab from "@mui/material/Tab"; -import { withContext } from "common/hocs/withContext.hoc"; -import { - WorkspaceSettingsProvider, - useWorkspaceSettings, -} from "context/workspaces/workspaceSettings.context"; -import { PrivateLayout } from "modules/layout"; -import { useState } from "react"; - -import { RepositoriesCard } from "./components/repositoriesCard.component"; -import SecretsCard from "./components/repositorySecretsCard.component"; -import StorageSecretsCard from "./components/storageSecretsCard.component"; -import { UsersCard } from "./components/usersCard.component"; -import WorkspaceSecretsCard from "./components/workspaceSecretsCard.component"; -import WorkspaceMembersCard from "./components/workspaceUsersCard.component"; - -export const WorkspaceSettingsPage = withContext( - WorkspaceSettingsProvider, - () => { - const { workspace, selectedRepositoryId } = useWorkspaceSettings(); - - const [value, setValue] = useState("1"); - - return ( - - - - - Workspace: {workspace?.workspace_name} - - - - - { - setValue(newValue); - }} - aria-label="workspace-tabs" - > - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ); - }, -); diff --git a/frontend/src/modules/app/app.component.tsx b/frontend/src/providers/app.tsx similarity index 88% rename from frontend/src/modules/app/app.component.tsx rename to frontend/src/providers/app.tsx index 8bf63708..4230d045 100644 --- a/frontend/src/modules/app/app.component.tsx +++ b/frontend/src/providers/app.tsx @@ -1,7 +1,7 @@ import CssBaseline from "@mui/material/CssBaseline"; import { ThemeProvider } from "@mui/material/styles"; import { AuthenticationProvider } from "context/authentication"; -import { WorkspacesProvider } from "context/workspaces/workspaces.context"; +import { WorkspacesProvider } from "context/workspaces"; import { type FC } from "react"; import "react-datepicker/dist/react-datepicker.css"; import { BrowserRouter } from "react-router-dom"; @@ -9,7 +9,8 @@ import { ToastContainer } from "react-toastify"; import "react-toastify/dist/ReactToastify.css"; import { SWRConfig } from "swr"; -import ApplicationRoutes from "./router/applicationRoutes.component"; +import ApplicationRoutes from "../routes"; + import { theme } from "./theme.config"; import "ag-grid-community/dist/styles/ag-grid.css"; diff --git a/frontend/src/modules/app/theme.config.ts b/frontend/src/providers/theme.config.ts similarity index 100% rename from frontend/src/modules/app/theme.config.ts rename to frontend/src/providers/theme.config.ts diff --git a/frontend/src/modules/app/router/applicationRoutes.component.tsx b/frontend/src/routes/index.tsx similarity index 81% rename from frontend/src/modules/app/router/applicationRoutes.component.tsx rename to frontend/src/routes/index.tsx index 4bbf1954..4f74b340 100644 --- a/frontend/src/modules/app/router/applicationRoutes.component.tsx +++ b/frontend/src/routes/index.tsx @@ -1,15 +1,16 @@ -import { WorkflowsEditorPage, WorkflowsPage } from "pages/private/workflows/"; +import SignInPage from "features/auth/pages/signIn/signInPage"; +import SignUpPage from "features/auth/pages/signUp/signUpPage"; +import { WorkflowsEditorPage } from "features/workflowEditor/pages"; +import { WorkflowsPage } from "features/workflows/pages"; import { - WorkspacesPage, WorkspaceSettingsPage, -} from "pages/private/workspaces"; -import SignInPage from "pages/public/signIn/signInPage.component"; -import SignUpPage from "pages/public/signUp/signUpPage.component"; + WorkspacesPage, +} from "features/workspaces/pages"; import { type FC } from "react"; import { Navigate, Route, Routes } from "react-router-dom"; -import { PrivateRoute } from "./privateRoute.component"; -import { PublicRoute } from "./publicRoute.component"; +import { PrivateRoute } from "./privateRoute"; +import { PublicRoute } from "./publicRoute"; /** * Application router diff --git a/frontend/src/modules/app/router/privateRoute.component.tsx b/frontend/src/routes/privateRoute.tsx similarity index 95% rename from frontend/src/modules/app/router/privateRoute.component.tsx rename to frontend/src/routes/privateRoute.tsx index c0331a06..30a048c9 100644 --- a/frontend/src/modules/app/router/privateRoute.component.tsx +++ b/frontend/src/routes/privateRoute.tsx @@ -1,5 +1,5 @@ import { useAuthentication } from "context/authentication"; -import { useWorkspaces } from "context/workspaces/workspaces.context"; +import { useWorkspaces } from "context/workspaces"; import { type FC } from "react"; import { Navigate } from "react-router-dom"; diff --git a/frontend/src/modules/app/router/publicRoute.component.tsx b/frontend/src/routes/publicRoute.tsx similarity index 100% rename from frontend/src/modules/app/router/publicRoute.component.tsx rename to frontend/src/routes/publicRoute.tsx diff --git a/frontend/src/services/clients/domino.client.ts b/frontend/src/services/clients/domino.client.ts index e7101f54..086fafa3 100644 --- a/frontend/src/services/clients/domino.client.ts +++ b/frontend/src/services/clients/domino.client.ts @@ -1,5 +1,5 @@ import axios from "axios"; -import { environment } from "common/config/environment.config"; +import { environment } from "config/environment.config"; import { dispatchLogout } from "context/authentication"; import { endpoints } from "../config/endpoints.config"; diff --git a/frontend/src/services/config/endpoints.config.ts b/frontend/src/services/config/endpoints.config.ts index 136a022f..da9048d6 100644 --- a/frontend/src/services/config/endpoints.config.ts +++ b/frontend/src/services/config/endpoints.config.ts @@ -1,5 +1,4 @@ -import { environment } from "common/config/environment.config"; -import { type IApiEnv } from "common/interfaces/environment.interface"; +import { environment, type IApiEnv } from "config/environment.config"; interface IEndpoints { api: string; diff --git a/frontend/src/services/requests/piece/getOperatorRepositories.request.ts b/frontend/src/services/requests/piece/getOperatorRepositories.request.ts index 8447c0fc..8bef3808 100644 --- a/frontend/src/services/requests/piece/getOperatorRepositories.request.ts +++ b/frontend/src/services/requests/piece/getOperatorRepositories.request.ts @@ -1,5 +1,5 @@ import { type AxiosResponse } from "axios"; -import { useWorkspaces } from "context/workspaces/workspaces.context"; +import { useWorkspaces } from "context/workspaces"; import useSWR from "swr"; import { dominoApiClient } from "../../clients/domino.client"; diff --git a/frontend/src/services/requests/piece/getOperatorsRepositoriesReleases.request.ts b/frontend/src/services/requests/piece/getOperatorsRepositoriesReleases.request.ts index f27094ef..a356669f 100644 --- a/frontend/src/services/requests/piece/getOperatorsRepositoriesReleases.request.ts +++ b/frontend/src/services/requests/piece/getOperatorsRepositoriesReleases.request.ts @@ -1,5 +1,5 @@ import { type AxiosResponse } from "axios"; -import { useWorkspaces } from "context/workspaces/workspaces.context"; +import { useWorkspaces } from "context/workspaces"; import { dominoApiClient } from "../../clients/domino.client"; diff --git a/frontend/src/services/requests/piece/operator.interface.ts b/frontend/src/services/requests/piece/operator.interface.ts index e2ca4e59..046d1f26 100644 --- a/frontend/src/services/requests/piece/operator.interface.ts +++ b/frontend/src/services/requests/piece/operator.interface.ts @@ -1,4 +1,4 @@ -import { type ERepositorySource } from "common/interfaces/repositorySource.enum"; +import { type ERepositorySource } from "interfaces/repositorySource.enum"; /** * Operator object diff --git a/frontend/src/services/requests/repository/deleteOperatorRepository.request.ts b/frontend/src/services/requests/repository/deleteOperatorRepository.request.ts index 65159535..0ef3a6d0 100644 --- a/frontend/src/services/requests/repository/deleteOperatorRepository.request.ts +++ b/frontend/src/services/requests/repository/deleteOperatorRepository.request.ts @@ -1,6 +1,6 @@ // TODO move to /runs import { type AxiosResponse } from "axios"; -import { useWorkspaces } from "context/workspaces/workspaces.context"; +import { useWorkspaces } from "context/workspaces"; import { dominoApiClient } from "../../clients/domino.client"; diff --git a/frontend/src/services/requests/repository/getOperatorRepositorySecrets.request.ts b/frontend/src/services/requests/repository/getOperatorRepositorySecrets.request.ts index 3afab78f..fc248617 100644 --- a/frontend/src/services/requests/repository/getOperatorRepositorySecrets.request.ts +++ b/frontend/src/services/requests/repository/getOperatorRepositorySecrets.request.ts @@ -1,5 +1,5 @@ import { type AxiosResponse } from "axios"; -import { useWorkspaces } from "context/workspaces/workspaces.context"; +import { useWorkspaces } from "context/workspaces"; import useSWR from "swr"; import { dominoApiClient } from "../../clients/domino.client"; diff --git a/frontend/src/services/requests/repository/patchOperatorRepositorySecret.request.ts b/frontend/src/services/requests/repository/patchOperatorRepositorySecret.request.ts index f2079e03..396b9d95 100644 --- a/frontend/src/services/requests/repository/patchOperatorRepositorySecret.request.ts +++ b/frontend/src/services/requests/repository/patchOperatorRepositorySecret.request.ts @@ -1,6 +1,6 @@ // TODO move to /runs import { type AxiosResponse } from "axios"; -import { useWorkspaces } from "context/workspaces/workspaces.context"; +import { useWorkspaces } from "context/workspaces"; import { dominoApiClient } from "../../clients/domino.client"; diff --git a/frontend/src/services/requests/runs/getWorkflowRunTaskLogs.request.ts b/frontend/src/services/requests/runs/getWorkflowRunTaskLogs.request.ts index 0a9fae8a..3e1650dd 100644 --- a/frontend/src/services/requests/runs/getWorkflowRunTaskLogs.request.ts +++ b/frontend/src/services/requests/runs/getWorkflowRunTaskLogs.request.ts @@ -1,5 +1,5 @@ import { type AxiosResponse } from "axios"; -import { useWorkspaces } from "context/workspaces/workspaces.context"; +import { useWorkspaces } from "context/workspaces"; import { dominoApiClient } from "../../clients/domino.client"; diff --git a/frontend/src/services/requests/runs/getWorkflowRunTaskResult.request.ts b/frontend/src/services/requests/runs/getWorkflowRunTaskResult.request.ts index dbf11b77..c3ff0659 100644 --- a/frontend/src/services/requests/runs/getWorkflowRunTaskResult.request.ts +++ b/frontend/src/services/requests/runs/getWorkflowRunTaskResult.request.ts @@ -1,5 +1,5 @@ import { type AxiosResponse } from "axios"; -import { useWorkspaces } from "context/workspaces/workspaces.context"; +import { useWorkspaces } from "context/workspaces"; import { dominoApiClient } from "../../clients/domino.client"; diff --git a/frontend/src/services/requests/runs/getWorkflowRunTasks.request.ts b/frontend/src/services/requests/runs/getWorkflowRunTasks.request.ts index 9e25a463..6f90a9bd 100644 --- a/frontend/src/services/requests/runs/getWorkflowRunTasks.request.ts +++ b/frontend/src/services/requests/runs/getWorkflowRunTasks.request.ts @@ -1,5 +1,5 @@ import { type AxiosResponse } from "axios"; -import { useWorkspaces } from "context/workspaces/workspaces.context"; +import { useWorkspaces } from "context/workspaces"; import { dominoApiClient } from "../../clients/domino.client"; diff --git a/frontend/src/services/requests/runs/getWorkflowRuns.request.ts b/frontend/src/services/requests/runs/getWorkflowRuns.request.ts index 185c8be9..cd60e6b1 100644 --- a/frontend/src/services/requests/runs/getWorkflowRuns.request.ts +++ b/frontend/src/services/requests/runs/getWorkflowRuns.request.ts @@ -1,5 +1,5 @@ import { type AxiosResponse } from "axios"; -import { useWorkspaces } from "context/workspaces/workspaces.context"; +import { useWorkspaces } from "context/workspaces"; import useSWR from "swr"; import { dominoApiClient } from "../../clients/domino.client"; diff --git a/frontend/src/services/requests/workflow/deleteWorkflowId.request.ts b/frontend/src/services/requests/workflow/deleteWorkflowId.request.ts index d5364696..24633fec 100644 --- a/frontend/src/services/requests/workflow/deleteWorkflowId.request.ts +++ b/frontend/src/services/requests/workflow/deleteWorkflowId.request.ts @@ -1,5 +1,5 @@ import { type AxiosResponse } from "axios"; -import { useWorkspaces } from "context/workspaces/workspaces.context"; +import { useWorkspaces } from "context/workspaces"; import { dominoApiClient } from "../../clients/domino.client"; diff --git a/frontend/src/services/requests/workflow/getWorkflow.request.ts b/frontend/src/services/requests/workflow/getWorkflow.request.ts index 4c1728ee..59574f11 100644 --- a/frontend/src/services/requests/workflow/getWorkflow.request.ts +++ b/frontend/src/services/requests/workflow/getWorkflow.request.ts @@ -1,5 +1,5 @@ import { type AxiosResponse } from "axios"; -import { useWorkspaces } from "context/workspaces/workspaces.context"; +import { useWorkspaces } from "context/workspaces"; import useSWR from "swr"; import { dominoApiClient } from "../../clients/domino.client"; diff --git a/frontend/src/services/requests/workflow/getWorkflowId.request.ts b/frontend/src/services/requests/workflow/getWorkflowId.request.ts index 4771a48c..6ed2d9f7 100644 --- a/frontend/src/services/requests/workflow/getWorkflowId.request.ts +++ b/frontend/src/services/requests/workflow/getWorkflowId.request.ts @@ -1,5 +1,5 @@ import { type AxiosResponse } from "axios"; -import { useWorkspaces } from "context/workspaces/workspaces.context"; +import { useWorkspaces } from "context/workspaces"; import { dominoApiClient } from "../../clients/domino.client"; diff --git a/frontend/src/services/requests/workflow/postWorkflowRunId.request.ts b/frontend/src/services/requests/workflow/postWorkflowRunId.request.ts index 4e487382..16e8492d 100644 --- a/frontend/src/services/requests/workflow/postWorkflowRunId.request.ts +++ b/frontend/src/services/requests/workflow/postWorkflowRunId.request.ts @@ -1,6 +1,6 @@ // TODO move to /runs import { type AxiosResponse } from "axios"; -import { useWorkspaces } from "context/workspaces/workspaces.context"; +import { useWorkspaces } from "context/workspaces"; import { dominoApiClient } from "../../clients/domino.client"; diff --git a/frontend/src/services/requests/workspaces/patchWorkspace.reques.ts b/frontend/src/services/requests/workspaces/patchWorkspace.reques.ts index 6329cfae..c7c91022 100644 --- a/frontend/src/services/requests/workspaces/patchWorkspace.reques.ts +++ b/frontend/src/services/requests/workspaces/patchWorkspace.reques.ts @@ -1,6 +1,6 @@ // TODO move to /runs import { type AxiosResponse } from "axios"; -import { useWorkspaces } from "context/workspaces/workspaces.context"; +import { useWorkspaces } from "context/workspaces"; import { dominoApiClient } from "../../clients/domino.client"; diff --git a/frontend/src/services/requests/workspaces/workspaces.interface.ts b/frontend/src/services/requests/workspaces/workspaces.interface.ts index 31f059d9..4ad7ba77 100644 --- a/frontend/src/services/requests/workspaces/workspaces.interface.ts +++ b/frontend/src/services/requests/workspaces/workspaces.interface.ts @@ -1,4 +1,4 @@ -import { type ERepositorySource } from "common/interfaces/repositorySource.enum"; +import { type ERepositorySource } from "interfaces/repositorySource.enum"; // Workspace status enum with values (pending, accepted and rejected) export enum EWorkspaceStatus { diff --git a/frontend/src/utils/index.ts b/frontend/src/utils/index.ts index d4ff9fab..1d0a4e0a 100644 --- a/frontend/src/utils/index.ts +++ b/frontend/src/utils/index.ts @@ -6,3 +6,4 @@ export { getIdSlice, getUuidSlice, getUuid } from "./getUuidSlice"; export { generateTaskName } from "./generateTaskName"; export { getDefinition } from "./getDefinition"; export { getFromUpstream } from "./getFromUpstream"; +export { lazyImport } from "./lazyImports"; diff --git a/frontend/src/utils/lazyImports.ts b/frontend/src/utils/lazyImports.ts new file mode 100644 index 00000000..6a97b39e --- /dev/null +++ b/frontend/src/utils/lazyImports.ts @@ -0,0 +1,17 @@ +import * as React from "react"; + +// named imports for React.lazy: https://github.com/facebook/react/issues/14603#issuecomment-726551598 +export function lazyImport< + T extends React.ComponentType, + I extends { [K2 in K]: T }, + K extends keyof I, +>(factory: () => Promise, name: K): I { + return Object.create({ + [name]: React.lazy( + async () => await factory().then((module) => ({ default: module[name] })), + ), + }); +} + +// Usage +// const { Home } = lazyImport(() => import("./Home"), "Home"); From aa630c6d14056a43f606b2ddb0d50721d134704b Mon Sep 17 00:00:00 2001 From: Nathan Vieira Marcelino Date: Tue, 5 Sep 2023 21:05:24 -0300 Subject: [PATCH 226/328] fix: wrap text in result logs --- .../WorkflowsRunTasksFlowchart/WorkflowTaskLogs.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/frontend/src/features/workflows/components/WorkflowsRunTasksFlowchart/WorkflowTaskLogs.tsx b/frontend/src/features/workflows/components/WorkflowsRunTasksFlowchart/WorkflowTaskLogs.tsx index 9736b779..0afe917f 100644 --- a/frontend/src/features/workflows/components/WorkflowsRunTasksFlowchart/WorkflowTaskLogs.tsx +++ b/frontend/src/features/workflows/components/WorkflowsRunTasksFlowchart/WorkflowTaskLogs.tsx @@ -33,8 +33,8 @@ export const TaskLogs = (props: ITaskLogsProps) => { return { width: "100%", border: "none", - overflowX: renderOverflowX ? "scroll" : "hidden", - whiteSpace: renderOverflowX ? "pre" : "pre-wrap", + overflowX: renderOverflowX ? "hidden" : "scroll", + whiteSpace: renderOverflowX ? "pre-wrap" : "pre", outline: "none", }; }, [renderOverflowX]); From c7c82ff9d9bf468d833ac2290b30ff1e419718c8 Mon Sep 17 00:00:00 2001 From: Nathan Vieira Marcelino Date: Wed, 6 Sep 2023 17:12:33 -0300 Subject: [PATCH 227/328] fix : Replace old "Operator" references for "Piece" #81 --- frontend/src/@types/global.d.ts | 77 +---------- frontend/src/@types/piece/index.d.ts | 19 +++ frontend/src/@types/piece/piece.d.ts | 85 ++++++++++++ .../src/@types/{ => piece}/properties.d.ts | 3 + .../DrawerMenu/pieceDocsPopover.tsx | 40 +++--- .../components/DrawerMenu/sidebarAddNode.tsx | 29 ++--- .../components/DrawerMenu/sidebarNode.tsx | 9 +- .../components/WorkflowEditorPanel/index.tsx | 2 +- .../WorkflowEditorPanel/sidebarForm/index.tsx | 2 +- .../context/workflowsEditor/pieces.tsx | 53 ++++---- .../workflowsEditor/workflowPieces.tsx | 5 +- .../workflowsEditor/workflowsEditor.tsx | 4 +- .../WorkflowTaskDetails.tsx | 6 +- .../WorkflowsRunTasksFlowchart/index.tsx | 2 +- .../workspaceSettings/RepositoriesCard.tsx | 8 +- .../workspaces/context/workspaceSettings.tsx | 27 ++-- ...est.ts => getPieceRepositories.request.ts} | 35 ++--- .../piece/getPieceRepositoryPieces.request.ts | 16 +-- ... getPiecesRepositoriesReleases.request.ts} | 24 ++-- frontend/src/services/requests/piece/index.ts | 4 +- .../requests/piece/operator.interface.ts | 123 ------------------ .../requests/piece/piece.interface.ts | 44 +++++++ ...st.ts => deletePieceRepository.request.ts} | 0 ...s => getPieceRepositorySecrets.request.ts} | 4 +- .../src/services/requests/repository/index.ts | 6 +- ... => patchPieceRepositorySecret.request.ts} | 0 ...erface.ts => pieceRepository.interface.ts} | 2 +- .../src/services/requests/workspaces/index.ts | 2 +- ...t.ts => postPiecesRepositories.request.ts} | 12 +- .../workspaces/workspaces.interface.ts | 2 +- frontend/src/utils/jsonSchema.ts | 4 +- 31 files changed, 297 insertions(+), 352 deletions(-) create mode 100644 frontend/src/@types/piece/index.d.ts create mode 100644 frontend/src/@types/piece/piece.d.ts rename frontend/src/@types/{ => piece}/properties.d.ts (99%) rename frontend/src/services/requests/piece/{getOperatorRepositories.request.ts => getPieceRepositories.request.ts} (58%) rename frontend/src/services/requests/piece/{getOperatorsRepositoriesReleases.request.ts => getPiecesRepositoriesReleases.request.ts} (57%) delete mode 100644 frontend/src/services/requests/piece/operator.interface.ts create mode 100644 frontend/src/services/requests/piece/piece.interface.ts rename frontend/src/services/requests/repository/{deleteOperatorRepository.request.ts => deletePieceRepository.request.ts} (100%) rename frontend/src/services/requests/repository/{getOperatorRepositorySecrets.request.ts => getPieceRepositorySecrets.request.ts} (90%) rename frontend/src/services/requests/repository/{patchOperatorRepositorySecret.request.ts => patchPieceRepositorySecret.request.ts} (100%) rename frontend/src/services/requests/repository/{operatorRepository.interface.ts => pieceRepository.interface.ts} (51%) rename frontend/src/services/requests/workspaces/{postOperatorsRepositories.request.ts => postPiecesRepositories.request.ts} (72%) diff --git a/frontend/src/@types/global.d.ts b/frontend/src/@types/global.d.ts index 562bb43e..8ba9778e 100644 --- a/frontend/src/@types/global.d.ts +++ b/frontend/src/@types/global.d.ts @@ -1,75 +1,2 @@ -/* eslint-disable @typescript-eslint/consistent-type-imports */ -import { type CSSProperties } from "react"; - -export {}; - -declare global { - type InputSchemaProperty = import("./properties").InputSchemaProperty; - type ArrayObjectProperty = import("./properties").ArrayObjectProperty; - - type SimpleInputSchemaProperty = - import("./properties").SimpleInputSchemaProperty; - type FromUpstream = import("./properties").FromUpstream; - - interface EnumDefinition { - title: string; - description: string; - type: "string"; - enum: string[]; - } - - interface ObjectDefinition { - title: string; - description: string; - type: "object"; - properties: Record; - } - - type Definition = EnumDefinition | ObjectDefinition; - - type Definitions = Record; - - interface InputSchema { - title: string; - description: string; - - type: "object"; - - properties: Record; - definitions: Definitions; - } - - // eslint-disable-next-line @typescript-eslint/no-empty-interface - interface OutputSchema {} - - interface PieceSchema { - id: number; - name: string; - description: string; - - repository_id: number; - - input_schema: InputSchema; - output_schema: OutputSchema; - - secrets_schema: null; - source_image: string; - source_url: string; - dependency: { - dockerfile: string | null; - requirements_file: string | null; - }; - - style: { - label: string; - module: string; - - nodeType: string; - nodeStyle: CSSProperties; - - useIcon: boolean; - iconClassName?: string; - iconStyle: CSSProperties; - }; - } -} +/* eslint-disable @typescript-eslint/triple-slash-reference */ +/// diff --git a/frontend/src/@types/piece/index.d.ts b/frontend/src/@types/piece/index.d.ts new file mode 100644 index 00000000..cbce8176 --- /dev/null +++ b/frontend/src/@types/piece/index.d.ts @@ -0,0 +1,19 @@ +/* eslint-disable @typescript-eslint/consistent-type-imports */ +declare global { + type Piece = import("./piece").Piece; + type PieceSchema = import("./piece").PieceSchema; + type Definitions = import("./piece").Definitions; + type Definition = import("./piece").Definition; + type ObjectDefinition = import("./piece").ObjectDefinition; + type EnumDefinition = import("./piece").EnumDefinition; + type SimpleInputSchemaProperty = import("./piece").SimpleInputSchemaProperty; + type ArrayObjectProperty = import("./piece").ArrayObjectProperty; + type InputSchemaProperty = import("./piece").InputSchemaProperty; + type FromUpstream = import("./piece").FromUpstream; + + type PieceForageSchema = import("./piece").PieceForageSchema; + type PiecesRepository = import("./piece").PiecesRepository; + type PieceRepository = import("./piece").PieceRepository; +} + +export {}; diff --git a/frontend/src/@types/piece/piece.d.ts b/frontend/src/@types/piece/piece.d.ts new file mode 100644 index 00000000..e3f404f8 --- /dev/null +++ b/frontend/src/@types/piece/piece.d.ts @@ -0,0 +1,85 @@ +/* eslint-disable @typescript-eslint/consistent-type-imports */ +export type FromUpstream = import("./properties").FromUpstream; + +export type InputSchemaProperty = import("./properties").InputSchemaProperty; +export type ArrayObjectProperty = import("./properties").ArrayObjectProperty; + +export type SimpleInputSchemaProperty = + import("./properties").SimpleInputSchemaProperty; + +export interface EnumDefinition { + title: string; + description: string; + type: "string"; + enum: string[]; +} + +export interface ObjectDefinition { + title: string; + description: string; + type: "object"; + properties: Record; +} + +export type Definition = EnumDefinition | ObjectDefinition; + +export type Definitions = Record; + +export type SchemaProperties = Record; + +export interface PieceSchema { + title: string; + description: string; + + type: "object"; + + properties: SchemaProperties; + definitions: Definitions; +} + +export interface Piece { + id: number; + name: string; + description: string; + + repository_id: number; + + input_schema: PieceSchema; + output_schema: PieceSchema; + secrets_schema: PieceSchema | null; + + source_image: string; + source_url: string | null; + dependency: { + docker_image: string | null; + dockerfile: string | null; + requirements_file: string | null; + }; + + style?: { + label?: string; + module?: string; + + nodeType?: string; + nodeStyle?: CSSProperties; + + useIcon?: boolean; + iconClassName?: string; + iconStyle?: CSSProperties; + }; +} + +export type PieceForageSchema = Record; + +export type PiecesRepository = Record; + +export interface PieceRepository { + id: string; + name: string; + label: string; + created_at: string; + source: string; + path: string; + version: string; + workspace_id: number; +} diff --git a/frontend/src/@types/properties.d.ts b/frontend/src/@types/piece/properties.d.ts similarity index 99% rename from frontend/src/@types/properties.d.ts rename to frontend/src/@types/piece/properties.d.ts index c2b98fe8..38637624 100644 --- a/frontend/src/@types/properties.d.ts +++ b/frontend/src/@types/piece/properties.d.ts @@ -13,12 +13,14 @@ type BooleanProperty = DefaultPropertyProps & { type: "boolean"; default: boolean; }; + type NumberProperty = DefaultPropertyProps & { type: "number" | "integer" | "float"; default: number; exclusiveMaximum?: number; exclusiveMinimum?: number; }; + type StringProperty = DefaultPropertyProps & { type: "string"; default: string; @@ -26,6 +28,7 @@ type StringProperty = DefaultPropertyProps & { widget?: string; format?: "date" | "time" | "date-time"; }; + type EnumProperty = DefaultPropertyProps & { allOf: Reference[]; default: string; diff --git a/frontend/src/features/workflowEditor/components/DrawerMenu/pieceDocsPopover.tsx b/frontend/src/features/workflowEditor/components/DrawerMenu/pieceDocsPopover.tsx index b0bb68be..2017bb86 100644 --- a/frontend/src/features/workflowEditor/components/DrawerMenu/pieceDocsPopover.tsx +++ b/frontend/src/features/workflowEditor/components/DrawerMenu/pieceDocsPopover.tsx @@ -3,29 +3,28 @@ import DragHandleIcon from "@mui/icons-material/DragHandle"; import { Popover, IconButton, Typography } from "@mui/material"; import React from "react"; import Draggable from "react-draggable"; -import { type IOperator, type IIOProperty } from "services/requests/piece"; function renderPieceProperties( - operator: IOperator, + piece: Piece, key: "input_schema" | "output_schema" | "secrets_schema", ) { - const schema = operator[key]; - const properties = schema?.properties || {}; + const schema = piece[key]; + const properties = schema?.properties ?? {}; return Object.entries(properties).map(([key, value]) => { - const argument = value as IIOProperty; - let typeName: string = argument.type; + const argument = value; + let typeName: string = "allOf" in argument ? "enum" : argument.type; let valuesOptions: string[] = []; - if (argument.allOf && argument.allOf.length > 0) { + if ("allOf" in argument && argument.allOf.length > 0) { typeName = "enum"; - const typeClass = argument.allOf[0].$ref.split("/").pop(); - valuesOptions = schema?.definitions?.[typeClass].enum; + const typeClass = argument.allOf[0].$ref.split("/").pop() as string; + valuesOptions = (schema?.definitions?.[typeClass] as EnumDefinition).enum; } return ( {key} [{typeName}] - {argument.description} - {argument.allOf && argument.allOf.length > 0 && ( + {valuesOptions && valuesOptions.length > 0 && ( <> {" Options: "} {valuesOptions.join(", ")} @@ -37,7 +36,7 @@ function renderPieceProperties( } interface PieceDocsPopoverProps { - operator: IOperator; + piece: Piece; popoverOpen: boolean; handlePopoverClose: ( event: React.MouseEvent, @@ -46,7 +45,7 @@ interface PieceDocsPopoverProps { } const PieceDocsPopover: React.FC = ({ - operator, + piece, popoverOpen, handlePopoverClose, }) => ( @@ -124,7 +123,7 @@ const PieceDocsPopover: React.FC = ({ textAlign: "center", }} > - {operator.name} + {piece.name}

= ({
diff --git a/frontend/src/features/workflowEditor/components/DrawerMenu/sidebarAddNode.tsx b/frontend/src/features/workflowEditor/components/DrawerMenu/sidebarAddNode.tsx index c3a329c7..0d40f69d 100644 --- a/frontend/src/features/workflowEditor/components/DrawerMenu/sidebarAddNode.tsx +++ b/frontend/src/features/workflowEditor/components/DrawerMenu/sidebarAddNode.tsx @@ -11,31 +11,28 @@ import { } from "@mui/material"; import { useWorkflowsEditor } from "features/workflowEditor/context/workflowsEditor"; import { type FC, type SyntheticEvent, useState } from "react"; -import { type IOperator } from "services/requests/piece"; import PiecesSidebarNode from "./sidebarNode"; /** * @todo cleanup comments when no longer needed - * @todo move operators rules to create workflow context + * @todo move pieces rules to create workflow context * @todo improve loading/error/empty states */ const SidebarAddNode: FC = () => { const { repositories, repositoriesLoading, - repositoryOperators, + repositoryPieces, nodeDirection, toggleNodeDirection, } = useWorkflowsEditor(); - const [piecesMap, setPiecesMap] = useState>({}); + const [piecesMap, setPiecesMap] = useState>({}); const [expandedRepos, setExpandedRepos] = useState([]); - /** controls if an accordion is loading operators */ - const [loadingOperators, setLoadingOperators] = useState( - false, - ); + /** controls if an accordion is loading Pieces */ + const [loadingPieces, setLoadingPieces] = useState(false); return ( @@ -90,8 +87,8 @@ const SidebarAddNode: FC = () => { expanded={expandedRepos.includes(repo.id)} key={repo.id} onChange={(event: SyntheticEvent, expanded: boolean) => { - if (loadingOperators) return; - setLoadingOperators(repo.id); + if (loadingPieces) return; + setLoadingPieces(repo.id); // Check if the repo is currently expanded const isExpanded = expandedRepos.includes(repo.id); @@ -108,11 +105,11 @@ const SidebarAddNode: FC = () => { if (!isExpanded) { setPiecesMap((prev) => ({ ...prev, - [repo.id]: repositoryOperators[repo.id], + [repo.id]: repositoryPieces[repo.id], })); } - setLoadingOperators(false); + setLoadingPieces(false); }} > }> @@ -135,13 +132,13 @@ const SidebarAddNode: FC = () => { padding: "0px 0px 0px 0px", }} > - {!!loadingOperators && loadingOperators === repo.id && ( - Loading operators... + {!!loadingPieces && loadingPieces === repo.id && ( + Loading Pieces... )} {expandedRepos.includes(repo.id) && piecesMap[repo.id]?.length && - piecesMap[repo.id].map((operator) => ( - + piecesMap[repo.id].map((piece) => ( + ))} diff --git a/frontend/src/features/workflowEditor/components/DrawerMenu/sidebarNode.tsx b/frontend/src/features/workflowEditor/components/DrawerMenu/sidebarNode.tsx index 6aff2a7f..65d61a05 100644 --- a/frontend/src/features/workflowEditor/components/DrawerMenu/sidebarNode.tsx +++ b/frontend/src/features/workflowEditor/components/DrawerMenu/sidebarNode.tsx @@ -1,11 +1,10 @@ import HelpIcon from "@mui/icons-material/Help"; import { Box, Typography, IconButton } from "@mui/material"; import React, { type FC, useState } from "react"; -import { type IOperator } from "services/requests/piece"; import PieceDocsPopover from "./pieceDocsPopover"; -const PiecesSidebarNode: FC<{ operator: IOperator }> = ({ operator }) => { +const PiecesSidebarNode: FC<{ piece: Piece }> = ({ piece }) => { const [popoverOpen, setPopoverOpen] = useState(false); // Drag and drop from sidebar to Workflow area @@ -40,7 +39,7 @@ const PiecesSidebarNode: FC<{ operator: IOperator }> = ({ operator }) => { borderRadius: "5px", }} onDragStart={(event) => { - onDragStart(event, { nodeData: operator }); + onDragStart(event, { nodeData: piece }); }} draggable > @@ -54,7 +53,7 @@ const PiecesSidebarNode: FC<{ operator: IOperator }> = ({ operator }) => { maxWidth: "180px", }} > - {operator?.name ?? "-"} + {piece?.name ?? "-"} @@ -63,7 +62,7 @@ const PiecesSidebarNode: FC<{ operator: IOperator }> = ({ operator }) => {
diff --git a/frontend/src/features/workflowEditor/components/WorkflowEditorPanel/index.tsx b/frontend/src/features/workflowEditor/components/WorkflowEditorPanel/index.tsx index 6af78d6c..6ddc6e77 100644 --- a/frontend/src/features/workflowEditor/components/WorkflowEditorPanel/index.tsx +++ b/frontend/src/features/workflowEditor/components/WorkflowEditorPanel/index.tsx @@ -160,7 +160,7 @@ const WorkflowEditorPanelComponent = ({ nodesWithErros }: Props) => { setNodes((ns: Node[]) => ns.concat(newNode)); const piece = await fetchForagePieceById(data.id); const defaultInputs = extractDefaultInputValues( - piece as unknown as PieceSchema, + piece as unknown as Piece, ); const defaultContainerResources = extractDefaultValues( containerResourcesSchema as any, diff --git a/frontend/src/features/workflowEditor/components/WorkflowEditorPanel/sidebarForm/index.tsx b/frontend/src/features/workflowEditor/components/WorkflowEditorPanel/sidebarForm/index.tsx index 0f6b7c88..7afdc387 100644 --- a/frontend/src/features/workflowEditor/components/WorkflowEditorPanel/sidebarForm/index.tsx +++ b/frontend/src/features/workflowEditor/components/WorkflowEditorPanel/sidebarForm/index.tsx @@ -23,7 +23,7 @@ import StorageForm, { storageFormSchema } from "./storageForm"; interface ISidebarPieceFormProps { formId: string; - schema: InputSchema; + schema: PieceSchema; title: string; open: boolean; onClose: (event: any) => void; diff --git a/frontend/src/features/workflowEditor/context/workflowsEditor/pieces.tsx b/frontend/src/features/workflowEditor/context/workflowsEditor/pieces.tsx index 0396562f..9437f3e9 100644 --- a/frontend/src/features/workflowEditor/context/workflowsEditor/pieces.tsx +++ b/frontend/src/features/workflowEditor/context/workflowsEditor/pieces.tsx @@ -2,29 +2,25 @@ import React, { useCallback, useEffect, useMemo, useState } from "react"; import { toast } from "react-toastify"; import localForage from "services/config/localForage.config"; import { - type IGetRepoOperatorsResponseInterface, - type IOperator, - type IOperatorForageSchema, - type IOperatorRepository, - type IRepositoryOperators, - useAuthenticatedGetOperatorRepositories, + type IGetRepoPiecesResponseInterface, + useAuthenticatedGetPieceRepositories, } from "services/requests/piece"; -import { useFetchAuthenticatedGetRepoIdOperators } from "services/requests/piece/getPieceRepositoryPieces.request"; +import { useFetchAuthenticatedGetRepoIdPieces } from "services/requests/piece/getPieceRepositoryPieces.request"; import { createCustomContext } from "utils"; export interface IPiecesContext { - repositories: IOperatorRepository[]; + repositories: PieceRepository[]; repositoriesError: boolean; repositoriesLoading: boolean; - repositoryOperators: IRepositoryOperators; + repositoryPieces: PiecesRepository; search: string; handleSearch: (word: string) => void; fetchRepoById: (params: { id: string; - }) => Promise; - fetchForagePieceById: (id: number) => Promise; + }) => Promise; + fetchForagePieceById: (id: number) => Promise; } export const [PiecesContext, usesPieces] = @@ -34,52 +30,53 @@ const PiecesProvider: React.FC<{ children: React.ReactNode }> = ({ children, }) => { const [search, handleSearch] = useState(""); - const [repositoryOperators, setRepositoryOperatos] = - useState({}); + const [repositoryPieces, setRepositoryPieces] = useState( + {}, + ); - const fetchRepoById = useFetchAuthenticatedGetRepoIdOperators(); + const fetchRepoById = useFetchAuthenticatedGetRepoIdPieces(); const { data, error: repositoriesError, isValidating: repositoriesLoading, // mutate: repositoriesRefresh - } = useAuthenticatedGetOperatorRepositories({}); + } = useAuthenticatedGetPieceRepositories({}); - const repositories: IOperatorRepository[] = useMemo( + const repositories: PieceRepository[] = useMemo( () => data?.data.filter((repo) => repo.name.includes(search)) ?? [], [data, search], ); const fetchForagePieceById = useCallback(async (id: number) => { - const pieces = await localForage.getItem("pieces"); + const pieces = await localForage.getItem("pieces"); if (pieces !== null) { return pieces[id]; } }, []); useEffect(() => { - const updateRepositoriesOperators = async () => { - const repositoyOperatorsAux: IRepositoryOperators = {}; - const forageOperators: IOperatorForageSchema = {}; + const updateRepositoriesPieces = async () => { + const repositoryPiecesAux: PiecesRepository = {}; + const foragePieces: PieceForageSchema = {}; for (const repo of repositories) { fetchRepoById({ id: repo.id }) .then((pieces: any) => { - repositoyOperatorsAux[repo.id] = []; + repositoryPiecesAux[repo.id] = []; for (const op of pieces) { - repositoyOperatorsAux[repo.id].push(op); - forageOperators[op.id] = op; + repositoryPiecesAux[repo.id].push(op); + foragePieces[op.id] = op; } - setRepositoryOperatos(repositoyOperatorsAux); - void localForage.setItem("pieces", forageOperators); + setRepositoryPieces(repositoryPiecesAux); + void localForage.setItem("pieces", foragePieces); }) .catch((e) => { console.log(e); }); - // Set piece item to storage -> {piece_id: Operator} + // Set piece item to storage -> {piece_id: Piece} } }; - void updateRepositoriesOperators(); + void updateRepositoriesPieces(); }, [repositories, fetchRepoById]); useEffect(() => { @@ -95,7 +92,7 @@ const PiecesProvider: React.FC<{ children: React.ReactNode }> = ({ repositories, repositoriesError, repositoriesLoading, - repositoryOperators, + repositoryPieces, search, }; diff --git a/frontend/src/features/workflowEditor/context/workflowsEditor/workflowPieces.tsx b/frontend/src/features/workflowEditor/context/workflowsEditor/workflowPieces.tsx index 20cca559..8d0f92f2 100644 --- a/frontend/src/features/workflowEditor/context/workflowsEditor/workflowPieces.tsx +++ b/frontend/src/features/workflowEditor/context/workflowsEditor/workflowPieces.tsx @@ -1,13 +1,12 @@ import React, { useCallback } from "react"; import localForage from "services/config/localForage.config"; -import { type IOperator } from "services/requests/piece"; import { createCustomContext } from "utils"; export interface IWorkflowPieceContext { setForageWorkflowPieces: (workflowPieces: any) => Promise; // TODO add type - getForageWorkflowPieces: () => Promise>; // TODO add type + getForageWorkflowPieces: () => Promise>; // TODO add type removeForageWorkflowPiecesById: (id: string) => Promise; - fetchWorkflowPieceById: (id: string) => Promise; // TODO add type + fetchWorkflowPieceById: (id: string) => Promise; // TODO add type clearForageWorkflowPieces: () => Promise; setForageWorkflowPiecesOutputSchema: ( id: string, diff --git a/frontend/src/features/workflowEditor/context/workflowsEditor/workflowsEditor.tsx b/frontend/src/features/workflowEditor/context/workflowsEditor/workflowsEditor.tsx index b1318770..ea179221 100644 --- a/frontend/src/features/workflowEditor/context/workflowsEditor/workflowsEditor.tsx +++ b/frontend/src/features/workflowEditor/context/workflowsEditor/workflowsEditor.tsx @@ -56,7 +56,7 @@ const WorkflowsEditorProvider: FC<{ children?: React.ReactNode }> = ({ repositories, repositoriesError, repositoriesLoading, - repositoryOperators, + repositoryPieces, fetchForagePieceById, fetchRepoById, search, @@ -265,7 +265,7 @@ const WorkflowsEditorProvider: FC<{ children?: React.ReactNode }> = ({ repositories, repositoriesError: !!repositoriesError, repositoriesLoading, - repositoryOperators, + repositoryPieces, search, edges, setEdges, diff --git a/frontend/src/features/workflows/components/WorkflowsRunTasksFlowchart/WorkflowTaskDetails.tsx b/frontend/src/features/workflows/components/WorkflowsRunTasksFlowchart/WorkflowTaskDetails.tsx index 5b1d8d38..0fdd400c 100644 --- a/frontend/src/features/workflows/components/WorkflowsRunTasksFlowchart/WorkflowTaskDetails.tsx +++ b/frontend/src/features/workflows/components/WorkflowsRunTasksFlowchart/WorkflowTaskDetails.tsx @@ -6,7 +6,7 @@ import { type IWorkflowRunTasks } from "services/requests/runs"; import { taskStatesColorMap } from "../../constants"; interface IWorkflowRunTasksExtended extends IWorkflowRunTasks { - operatorName: string; + pieceName: string; } interface ITaskDetailsProps { @@ -48,7 +48,7 @@ export const TaskDetails = (props: ITaskDetailsProps) => { - Operator: + Piece: { color="text.secondary" fontWeight="500" > - {props.taskData.operatorName} + {props.taskData.pieceName} diff --git a/frontend/src/features/workflows/components/WorkflowsRunTasksFlowchart/index.tsx b/frontend/src/features/workflows/components/WorkflowsRunTasksFlowchart/index.tsx index 28ff20f1..1ae561c4 100644 --- a/frontend/src/features/workflows/components/WorkflowsRunTasksFlowchart/index.tsx +++ b/frontend/src/features/workflows/components/WorkflowsRunTasksFlowchart/index.tsx @@ -98,7 +98,7 @@ export const WorkflowRunTaskFlowchart = () => { selectedWorkflow?.ui_schema?.nodes?.[task.task_id]; nodeIdTaskMap[node.id] = { ...task, - operatorName: node?.data?.style?.label ?? node?.data?.name, + pieceName: node?.data?.style?.label ?? node?.data?.name, }; const color = diff --git a/frontend/src/features/workspaces/components/workspaceSettings/RepositoriesCard.tsx b/frontend/src/features/workspaces/components/workspaceSettings/RepositoriesCard.tsx index 8a26a6ca..75b0063a 100644 --- a/frontend/src/features/workspaces/components/workspaceSettings/RepositoriesCard.tsx +++ b/frontend/src/features/workspaces/components/workspaceSettings/RepositoriesCard.tsx @@ -31,7 +31,7 @@ import TextField from "@mui/material/TextField"; import { ERepositorySource } from "interfaces/repositorySource.enum"; import { type FC, type ReactNode, useCallback, useMemo, useState } from "react"; import { toast } from "react-toastify"; -import { type IOperatorRepositoryMetadata } from "services/requests/piece"; +import { type IPieceRepositoryMetadata } from "services/requests/piece"; import { useWorkspaceSettings } from "../../context/workspaceSettings"; @@ -48,7 +48,7 @@ export const RepositoriesCard: FC = () => { const [version, setVersion] = useState(""); const [selectedIndex, setSelectedIndex] = useState(null); const [availableVersions, setAvailableVersions] = useState< - IOperatorRepositoryMetadata[] + IPieceRepositoryMetadata[] >([]); const { @@ -172,7 +172,7 @@ export const RepositoriesCard: FC = () => { [setSelectedRepositoryId, selectedRepositoryId], ); - const handleDeleteOperatorRepository = useCallback( + const handleDeletePieceRepository = useCallback( (e: React.SyntheticEvent) => { const repositoryId = e.currentTarget.value; handleDeleteRepository(repositoryId) @@ -298,7 +298,7 @@ export const RepositoriesCard: FC = () => {
diff --git a/frontend/src/features/workspaces/context/workspaceSettings.tsx b/frontend/src/features/workspaces/context/workspaceSettings.tsx index f11fe7f8..d0235c5a 100644 --- a/frontend/src/features/workspaces/context/workspaceSettings.tsx +++ b/frontend/src/features/workspaces/context/workspaceSettings.tsx @@ -2,19 +2,18 @@ import { useWorkspaces } from "context/workspaces"; import { type FC, useCallback, useState } from "react"; import { toast } from "react-toastify"; import { - type IGetOperatorsRepositoriesReleasesParams, - type IGetOperatorsRepositoriesReleasesResponseInterface, - type IOperatorRepository, - useAuthenticatedGetOperatorRepositories, + type IGetPiecesRepositoriesReleasesParams, + type IGetPiecesRepositoriesReleasesResponseInterface, + useAuthenticatedGetPieceRepositories, } from "services/requests/piece"; -import { useAuthenticatedGetOperatorRepositoriesReleases } from "services/requests/piece/getOperatorsRepositoriesReleases.request"; +import { useAuthenticatedGetPieceRepositoriesReleases } from "services/requests/piece/getPiecesRepositoriesReleases.request"; import { useAuthenticatedDeleteRepository } from "services/requests/repository"; import { type IPostWorkspaceRepositoryPayload, type IPostWorkspaceRepositoryResponseInterface, type IWorkspaceSummary, useAuthenticatedGetWorkspace, - useAuthenticatedPostOperatorsRepository, + useAuthenticatedPostPiecesRepository, } from "services/requests/workspaces"; import { createCustomContext } from "utils"; @@ -26,7 +25,7 @@ interface IWorkspaceSettingsContext { workspaceDataLoading: boolean; handleRefreshWorkspaceData: () => void; - repositories: IOperatorRepository[]; + repositories: PieceRepository[]; repositoriesError: boolean; repositoriesLoading: boolean; handleRefreshRepositories: () => void; @@ -36,13 +35,13 @@ interface IWorkspaceSettingsContext { ) => Promise; handleFetchRepoReleases: ( - params: IGetOperatorsRepositoriesReleasesParams, - ) => Promise; + params: IGetPiecesRepositoriesReleasesParams, + ) => Promise; handleDeleteRepository: (id: string) => Promise; selectedRepositoryId: number | null; setSelectedRepositoryId: (id: number | null) => void; - defaultRepositories: IOperatorRepository[]; + defaultRepositories: PieceRepository[]; defaultRepositoriesError: boolean; defaultRepositoriesLoading: boolean; handleRefreshDefaultRepositories: () => void; @@ -79,20 +78,20 @@ export const WorkspaceSettingsProvider: FC = ({ error: repositoriesError, isValidating: repositoriesLoading, mutate: refreshRepositories, - } = useAuthenticatedGetOperatorRepositories({}); + } = useAuthenticatedGetPieceRepositories({}); const { data: defaultRepositories, error: defaultRepositoriesError, isValidating: defaultRepositoriesLoading, mutate: refreshDefaultRepositories, - } = useAuthenticatedGetOperatorRepositories({ source: "default" }); + } = useAuthenticatedGetPieceRepositories({ source: "default" }); - const postRepository = useAuthenticatedPostOperatorsRepository({ + const postRepository = useAuthenticatedPostPiecesRepository({ workspace: workspace?.id ?? "", }); const handleFetchRepoReleases = - useAuthenticatedGetOperatorRepositoriesReleases(); + useAuthenticatedGetPieceRepositoriesReleases(); const handleDeleteRepository = useAuthenticatedDeleteRepository(); // Handlers diff --git a/frontend/src/services/requests/piece/getOperatorRepositories.request.ts b/frontend/src/services/requests/piece/getPieceRepositories.request.ts similarity index 58% rename from frontend/src/services/requests/piece/getOperatorRepositories.request.ts rename to frontend/src/services/requests/piece/getPieceRepositories.request.ts index 8bef3808..0b24ad24 100644 --- a/frontend/src/services/requests/piece/getOperatorRepositories.request.ts +++ b/frontend/src/services/requests/piece/getPieceRepositories.request.ts @@ -4,9 +4,9 @@ import useSWR from "swr"; import { dominoApiClient } from "../../clients/domino.client"; -import { type IGetOperatorsRepositoriesResponseInterface } from "./operator.interface"; +import { type IGetPiecesRepositoriesResponseInterface } from "./piece.interface"; -interface IGetOperatorRepositoryFilters { +interface IGetPieceRepositoryFilters { page?: number; page_size?: number; name__like?: string; @@ -15,9 +15,9 @@ interface IGetOperatorRepositoryFilters { source?: "github" | "default"; } -const getOperatorsRepositoriesUrl = ( +const getPiecesRepositoriesUrl = ( workspace: string, - filters: IGetOperatorRepositoryFilters, + filters: IGetPieceRepositoryFilters, ) => { const query = new URLSearchParams(); query.set("workspace_id", workspace); @@ -28,18 +28,19 @@ const getOperatorsRepositoriesUrl = ( }; /** - * Get operator using GET /pieces-repositories - * @returns operator + * Get Piece using GET /pieces-repositories + * @returns Piece */ -const getOperatorsRepositories: ( +const getPiecesRepositories: ( workspace: string, - filters: IGetOperatorRepositoryFilters, -) => Promise< - AxiosResponse -> = async (workspace, filters) => { + filters: IGetPieceRepositoryFilters, +) => Promise> = async ( + workspace, + filters, +) => { // return await dominoApiClient.get( - getOperatorsRepositoriesUrl(workspace, filters), + getPiecesRepositoriesUrl(workspace, filters), ); }; @@ -47,8 +48,8 @@ const getOperatorsRepositories: ( * Get pieces repositories for current workspace * @returns pieces repositories as swr response */ -export const useAuthenticatedGetOperatorRepositories = ( - filters: IGetOperatorRepositoryFilters, +export const useAuthenticatedGetPieceRepositories = ( + filters: IGetPieceRepositoryFilters, ) => { const { workspace } = useWorkspaces(); @@ -57,13 +58,13 @@ export const useAuthenticatedGetOperatorRepositories = ( "Impossible to fetch pieces repositories without specifying a workspace", ); - const fetcher = async (filters: IGetOperatorRepositoryFilters) => - await getOperatorsRepositories(workspace.id, filters).then( + const fetcher = async (filters: IGetPieceRepositoryFilters) => + await getPiecesRepositories(workspace.id, filters).then( (data) => data.data, ); return useSWR( - getOperatorsRepositoriesUrl(workspace.id, filters), + getPiecesRepositoriesUrl(workspace.id, filters), async () => await fetcher(filters), { revalidateOnFocus: false, diff --git a/frontend/src/services/requests/piece/getPieceRepositoryPieces.request.ts b/frontend/src/services/requests/piece/getPieceRepositoryPieces.request.ts index 610ace1e..daadda0f 100644 --- a/frontend/src/services/requests/piece/getPieceRepositoryPieces.request.ts +++ b/frontend/src/services/requests/piece/getPieceRepositoryPieces.request.ts @@ -3,9 +3,9 @@ import { useCallback } from "react"; import { dominoApiClient } from "../../clients/domino.client"; -import { type IGetRepoOperatorsResponseInterface } from "./operator.interface"; +import { type IGetRepoPiecesResponseInterface } from "./piece.interface"; -interface IGetRepoOperatorsParams { +interface IGetRepoPiecesParams { id: string; } @@ -15,9 +15,9 @@ interface IGetRepoOperatorsParams { * @param id repo id * @returns pieces */ -const getRepoIdOperators: (args: { - params: IGetRepoOperatorsParams; -}) => Promise> = async ({ +const getRepoIdPieces: (args: { + params: IGetRepoPiecesParams; +}) => Promise> = async ({ params, }) => { return await dominoApiClient.get(`pieces-repositories/${params.id}/pieces`); @@ -28,9 +28,9 @@ const getRepoIdOperators: (args: { * @param params `{ id: string }` * @returns pieces from repo */ -export const useFetchAuthenticatedGetRepoIdOperators = () => { - const fetcher = useCallback(async (params: IGetRepoOperatorsParams) => { - return await getRepoIdOperators({ params }).then((data) => data.data); +export const useFetchAuthenticatedGetRepoIdPieces = () => { + const fetcher = useCallback(async (params: IGetRepoPiecesParams) => { + return await getRepoIdPieces({ params }).then((data) => data.data); }, []); return fetcher; }; diff --git a/frontend/src/services/requests/piece/getOperatorsRepositoriesReleases.request.ts b/frontend/src/services/requests/piece/getPiecesRepositoriesReleases.request.ts similarity index 57% rename from frontend/src/services/requests/piece/getOperatorsRepositoriesReleases.request.ts rename to frontend/src/services/requests/piece/getPiecesRepositoriesReleases.request.ts index a356669f..878ca7f3 100644 --- a/frontend/src/services/requests/piece/getOperatorsRepositoriesReleases.request.ts +++ b/frontend/src/services/requests/piece/getPiecesRepositoriesReleases.request.ts @@ -4,19 +4,19 @@ import { useWorkspaces } from "context/workspaces"; import { dominoApiClient } from "../../clients/domino.client"; import { - type IGetOperatorsRepositoriesReleasesParams, - type IGetOperatorsRepositoriesReleasesResponseInterface, -} from "./operator.interface"; + type IGetPiecesRepositoriesReleasesParams, + type IGetPiecesRepositoriesReleasesResponseInterface, +} from "./piece.interface"; /** - * Get operator repository releases using GET /pieces-repositories/releases + * Get Piece repository releases using GET /pieces-repositories/releases * @param token auth token (string) - * @returns operator repository + * @returns Piece repository */ -const getOperatorsRepositoriesReleases: ( - params: IGetOperatorsRepositoriesReleasesParams, +const getPiecesRepositoriesReleases: ( + params: IGetPiecesRepositoriesReleasesParams, ) => Promise< - AxiosResponse + AxiosResponse > = async ({ source, path, workspaceId }) => { const search = new URLSearchParams(); search.set("source", source); @@ -31,10 +31,10 @@ const getOperatorsRepositoriesReleases: ( }; /** - * Get releases for a given operator repository + * Get releases for a given Piece repository * @returns pieces repositories releases */ -export const useAuthenticatedGetOperatorRepositoriesReleases = () => { +export const useAuthenticatedGetPieceRepositoriesReleases = () => { const { workspace } = useWorkspaces(); if (!workspace) @@ -42,8 +42,8 @@ export const useAuthenticatedGetOperatorRepositoriesReleases = () => { "Impossible to fetch pieces repositories without specifying a workspace", ); - return async (params: IGetOperatorsRepositoriesReleasesParams) => - await getOperatorsRepositoriesReleases({ + return async (params: IGetPiecesRepositoriesReleasesParams) => + await getPiecesRepositoriesReleases({ ...params, workspaceId: workspace.id, }).then((data) => { diff --git a/frontend/src/services/requests/piece/index.ts b/frontend/src/services/requests/piece/index.ts index d6e920ef..02e4af24 100644 --- a/frontend/src/services/requests/piece/index.ts +++ b/frontend/src/services/requests/piece/index.ts @@ -1,2 +1,2 @@ -export * from "./getOperatorRepositories.request"; -export * from "./operator.interface"; +export * from "./getPieceRepositories.request"; +export * from "./piece.interface"; diff --git a/frontend/src/services/requests/piece/operator.interface.ts b/frontend/src/services/requests/piece/operator.interface.ts deleted file mode 100644 index 046d1f26..00000000 --- a/frontend/src/services/requests/piece/operator.interface.ts +++ /dev/null @@ -1,123 +0,0 @@ -import { type ERepositorySource } from "interfaces/repositorySource.enum"; - -/** - * Operator object - */ -export interface IOperator { - id: string; - name: string; - description: string; - dependency: { - docker_image: string | null; - dockerfile: string | null; - requirements_file: string | null; - }; - docker_image: string; - input_schema: IIOSchema; - output_schema: IIOSchema; - secrets_schema: IIOSchema | null; - source_url: string | null; - style?: { - module?: string; - label?: string; - nodeType?: string; - nodeStyle?: any; - useIcon?: boolean; - iconClassName?: string; - iconStyle?: any; - }; - repository_id: string; -} - -export type IOperatorForageSchema = Record; - -export type IRepositoryOperators = Record; - -/** - * Operator input/output schema - */ -export interface IIOProperty { - title: string; - type: string; - description: string | null; - default: string | null; - allOf: any[] | null; -} - -export interface IIOSchema { - title: string; - description: string; - type: string; - properties: any; - required: string[]; - definitions: any; -} - -export interface IOperatorRepository { - id: string; - name: string; - label: string; - created_at: string; - source: string; - path: string; - version: string; - workspace_id: number; -} - -export interface IOperatorSchema { - Operator_config: IOperatorConfig; - tasks: Record; -} - -export interface IOperatorConfig { - name: string; - start_date: string; - end_date: string; - schedule_interval: string; - catchup: boolean; - generate_report: string; - description: string; -} - -interface IPaginationMetadata { - page: number; - records: number; - total: number; - last_page: number; -} - -/** - * Get Operator Repositories response interface - */ -export interface IGetOperatorsRepositoriesResponseInterface { - data: IOperatorRepository[]; - metadata: IPaginationMetadata; -} - -/** - * Get Operator Repositories id Operators - */ -export type IGetRepoOperatorsResponseInterface = IOperator[]; - -/** - * Operator repository metadata - */ -export interface IOperatorRepositoryMetadata { - version: string; - last_modified: string; -} - -/** - * Get Operators Repositories Releases response interface - */ -export type IGetOperatorsRepositoriesReleasesResponseInterface = - IOperatorRepositoryMetadata[]; - -/** - * Get Operators Repositories Releases request params - */ -export interface IGetOperatorsRepositoriesReleasesParams { - source: ERepositorySource; - path: string; - workspaceId?: string; -} diff --git a/frontend/src/services/requests/piece/piece.interface.ts b/frontend/src/services/requests/piece/piece.interface.ts new file mode 100644 index 00000000..e2b84ee5 --- /dev/null +++ b/frontend/src/services/requests/piece/piece.interface.ts @@ -0,0 +1,44 @@ +import { type ERepositorySource } from "interfaces/repositorySource.enum"; + +interface IPaginationMetadata { + page: number; + records: number; + total: number; + last_page: number; +} + +/** + * Get Piece Repositories response interface + */ +export interface IGetPiecesRepositoriesResponseInterface { + data: PieceRepository[]; + metadata: IPaginationMetadata; +} + +/** + * Get Piece Repositories id Pieces + */ +export type IGetRepoPiecesResponseInterface = Piece[]; + +/** + * Piece repository metadata + */ +export interface IPieceRepositoryMetadata { + version: string; + last_modified: string; +} + +/** + * Get Pieces Repositories Releases response interface + */ +export type IGetPiecesRepositoriesReleasesResponseInterface = + IPieceRepositoryMetadata[]; + +/** + * Get Pieces Repositories Releases request params + */ +export interface IGetPiecesRepositoriesReleasesParams { + source: ERepositorySource; + path: string; + workspaceId?: string; +} diff --git a/frontend/src/services/requests/repository/deleteOperatorRepository.request.ts b/frontend/src/services/requests/repository/deletePieceRepository.request.ts similarity index 100% rename from frontend/src/services/requests/repository/deleteOperatorRepository.request.ts rename to frontend/src/services/requests/repository/deletePieceRepository.request.ts diff --git a/frontend/src/services/requests/repository/getOperatorRepositorySecrets.request.ts b/frontend/src/services/requests/repository/getPieceRepositorySecrets.request.ts similarity index 90% rename from frontend/src/services/requests/repository/getOperatorRepositorySecrets.request.ts rename to frontend/src/services/requests/repository/getPieceRepositorySecrets.request.ts index fc248617..584c2cdc 100644 --- a/frontend/src/services/requests/repository/getOperatorRepositorySecrets.request.ts +++ b/frontend/src/services/requests/repository/getPieceRepositorySecrets.request.ts @@ -4,7 +4,7 @@ import useSWR from "swr"; import { dominoApiClient } from "../../clients/domino.client"; -import { type IOperatorRepositorySecretsData } from "./operatorRepository.interface"; +import { type IPieceRepositorySecretsData } from "./pieceRepository.interface"; interface IGetRepositorySecretsParams { repositoryId: string; @@ -19,7 +19,7 @@ const getRepositorySecretsUrl = (repositoryId: string) => */ const getRepositorySecrets: ( repositoryId: string, -) => Promise> = async ( +) => Promise> = async ( repositoryId, ) => { return await dominoApiClient.get(getRepositorySecretsUrl(repositoryId)); diff --git a/frontend/src/services/requests/repository/index.ts b/frontend/src/services/requests/repository/index.ts index 295fe0a7..91a74f87 100644 --- a/frontend/src/services/requests/repository/index.ts +++ b/frontend/src/services/requests/repository/index.ts @@ -1,3 +1,3 @@ -export * from "./getOperatorRepositorySecrets.request"; -export * from "./patchOperatorRepositorySecret.request"; -export * from "./deleteOperatorRepository.request"; +export * from "./getPieceRepositorySecrets.request"; +export * from "./patchPieceRepositorySecret.request"; +export * from "./deletePieceRepository.request"; diff --git a/frontend/src/services/requests/repository/patchOperatorRepositorySecret.request.ts b/frontend/src/services/requests/repository/patchPieceRepositorySecret.request.ts similarity index 100% rename from frontend/src/services/requests/repository/patchOperatorRepositorySecret.request.ts rename to frontend/src/services/requests/repository/patchPieceRepositorySecret.request.ts diff --git a/frontend/src/services/requests/repository/operatorRepository.interface.ts b/frontend/src/services/requests/repository/pieceRepository.interface.ts similarity index 51% rename from frontend/src/services/requests/repository/operatorRepository.interface.ts rename to frontend/src/services/requests/repository/pieceRepository.interface.ts index bd14ea55..224fdef7 100644 --- a/frontend/src/services/requests/repository/operatorRepository.interface.ts +++ b/frontend/src/services/requests/repository/pieceRepository.interface.ts @@ -1,4 +1,4 @@ -export interface IOperatorRepositorySecretsData { +export interface IPieceRepositorySecretsData { id: number; name: string; is_filled: boolean; diff --git a/frontend/src/services/requests/workspaces/index.ts b/frontend/src/services/requests/workspaces/index.ts index 66816196..363eeffb 100644 --- a/frontend/src/services/requests/workspaces/index.ts +++ b/frontend/src/services/requests/workspaces/index.ts @@ -1,6 +1,6 @@ export * from "./getWorkspaceId.request"; export * from "./getWorkspaces.request"; -export * from "./postOperatorsRepositories.request"; +export * from "./postPiecesRepositories.request"; export * from "./postWorkspaces.request"; export * from "./deleteWorkspace.request"; export * from "./workspaces.interface"; diff --git a/frontend/src/services/requests/workspaces/postOperatorsRepositories.request.ts b/frontend/src/services/requests/workspaces/postPiecesRepositories.request.ts similarity index 72% rename from frontend/src/services/requests/workspaces/postOperatorsRepositories.request.ts rename to frontend/src/services/requests/workspaces/postPiecesRepositories.request.ts index 7e704ca5..3383850c 100644 --- a/frontend/src/services/requests/workspaces/postOperatorsRepositories.request.ts +++ b/frontend/src/services/requests/workspaces/postPiecesRepositories.request.ts @@ -8,10 +8,10 @@ import { } from "./workspaces.interface"; /** - * Create workspacesidoperatorsrepositories using POST /workspacesidoperatorsrepositories + * Create workspacesidPiecesrepositories using POST /workspacesidPiecesrepositories * @returns ? */ -const postOperatorsRepository: ( +const postPiecesRepository: ( params: IPostWorkspaceRepositoryParams, ) => Promise> = async ( params, @@ -20,18 +20,18 @@ const postOperatorsRepository: ( }; /** - * Create authenticated workspacesidoperatorsrepositories + * Create authenticated workspacesidPiecesrepositories * @param params `{ id: string, data: Record }`` - * @returns crate workspacesidoperatorsrepositories function + * @returns crate workspacesidPiecesrepositories function */ -export const useAuthenticatedPostOperatorsRepository = (params: { +export const useAuthenticatedPostPiecesRepository = (params: { workspace: string; }) => { if (!params?.workspace) throw new Error("Impossible to add repositories without a workspace!"); const fetcher = async (payload: IPostWorkspaceRepositoryPayload) => - await postOperatorsRepository({ + await postPiecesRepository({ id: params.workspace, data: payload, }).then((data) => data.data); diff --git a/frontend/src/services/requests/workspaces/workspaces.interface.ts b/frontend/src/services/requests/workspaces/workspaces.interface.ts index 7b393b56..7f47c5c4 100644 --- a/frontend/src/services/requests/workspaces/workspaces.interface.ts +++ b/frontend/src/services/requests/workspaces/workspaces.interface.ts @@ -27,7 +27,7 @@ export interface IWorkspaceDetails { workspace_name: string; github_access_token_filled: string; // users: { user_id: string, permission: string }[] - // operators_repositories: { + // Pieces_repositories: { // repository_id: string // repository_name: string // repository_source: ERepositorySource | string diff --git a/frontend/src/utils/jsonSchema.ts b/frontend/src/utils/jsonSchema.ts index c584bf69..854755d1 100644 --- a/frontend/src/utils/jsonSchema.ts +++ b/frontend/src/utils/jsonSchema.ts @@ -4,7 +4,7 @@ import { type IWorkflowPieceData } from "context/workflows/types"; import { getFromUpstream } from "./getFromUpstream"; -export const extractDefaultInputValues = (pieceSchema: PieceSchema) => { +export const extractDefaultInputValues = (pieceSchema: Piece) => { const schema = pieceSchema.input_schema.properties; const definitions = pieceSchema.input_schema.definitions; const defaultData = extractDefaultValues(pieceSchema.input_schema); @@ -80,7 +80,7 @@ export const extractDefaultInputValues = (pieceSchema: PieceSchema) => { }; export const extractDefaultValues = ( - schema: InputSchema, + schema: PieceSchema, output: any | null = null, ) => { output = output === null ? {} : output; From c1b6bbb235edd7bf17ff05590bfe8030706be47d Mon Sep 17 00:00:00 2001 From: Nathan Vieira Marcelino Date: Fri, 8 Sep 2023 10:29:48 -0300 Subject: [PATCH 228/328] fix: api contexts --- frontend/.eslintrc.json | 35 ++++- .../src/context/authentication/api/index.ts | 2 + .../authentication/api/postAuthLogin.ts} | 3 +- .../authentication/api/postAuthRegister.ts} | 3 +- .../authentication/authentication.context.tsx | 5 +- .../workflows/types/containerResources.ts | 11 -- frontend/src/context/workflows/types/index.ts | 4 - frontend/src/context/workflows/types/input.ts | 24 ---- .../src/context/workflows/types/settings.ts | 50 ------- .../src/context/workflows/types/storage.ts | 11 -- .../workflows/types/workflowPieceData.ts | 72 ---------- .../workspaces/api/acceptWorkspaceInvite.ts} | 9 +- .../workspaces/api/deleteUserWorkspace.ts} | 3 +- .../workspaces/api/deleteWorkspace.ts} | 3 +- .../workspaces/api/getWorkspaceId.ts} | 2 +- .../workspaces/api/getWorkspaceMembers.ts} | 2 +- .../workspaces/api/getWorkspaces.ts} | 2 +- frontend/src/context/workspaces/api/index.ts | 11 ++ .../workspaces/api/inviteWorkspace.ts} | 3 +- .../workspaces/api/patchWorkspace.ts} | 3 +- .../workspaces/api/postPiecesRepositories.ts} | 2 +- .../workspaces/api/postWorkspaces.ts} | 3 +- .../workspaces/api/rejectWorkspaceInvite.ts} | 9 +- frontend/src/context/workspaces/index.tsx | 7 +- .../src/context/workspaces/types/index.ts | 1 + .../workspaces/types/workspaces.ts} | 0 .../components/DrawerMenu/sidebarAddNode.tsx | 2 +- .../components/SidebarSettingsForm/index.tsx | 4 +- ...WorkflowsEditor.tsx => WorkflowEditor.tsx} | 3 +- .../components/WorkflowEditorPanel/index.tsx | 7 +- .../WorkflowEditorPanel/sidebarForm/index.tsx | 2 +- .../sidebarForm/pieceForm/index.tsx | 2 +- .../pieceForm/pieceFormItem/arrayInput.tsx | 2 +- .../context/{workflowsEditor => }/index.tsx | 4 +- .../context/{workflowsEditor => }/pieces.tsx | 10 +- .../workflowEditor/context/types/index.ts | 1 + .../context/types/workflowPieceData.ts | 2 +- .../{workflowsEditor => }/workflowEdges.tsx | 0 .../{workflowsEditor => }/workflowNodes.tsx | 2 +- .../{workflowsEditor => }/workflowPieces.tsx | 0 .../workflowPiecesData.tsx | 2 +- .../workflowSettingsData.tsx | 2 +- .../{workflowsEditor => }/workflowsEditor.tsx | 9 +- .../pages/workflowEditorPage.tsx | 8 +- .../workflowEditor}/utils/getFromUpstream.ts | 0 .../features/workflowEditor/utils/index.ts | 2 + .../workflowEditor}/utils/jsonSchema.ts | 16 +-- frontend/src/features/workflows/api/index.ts | 4 + .../piece/getPieceRepositories.request.ts | 3 +- .../api/piece/getPieceRepositoryPieces.ts} | 3 +- .../getPiecesRepositoriesReleases.request.ts | 3 +- .../src/features/workflows/api/piece/index.ts | 4 + .../workflows/api}/piece/piece.interface.ts | 0 .../deletePieceRepository.request.ts | 3 +- .../getPieceRepositorySecrets.request.ts | 3 +- .../workflows/api}/repository/index.ts | 0 .../patchPieceRepositorySecret.request.ts | 3 +- .../repository/pieceRepository.interface.ts | 0 .../api/runs/getWorkflowRunTaskLogs.ts} | 6 +- .../api/runs/getWorkflowRunTaskResult.ts} | 6 +- .../api/runs/getWorkflowRunTasks.ts} | 6 +- .../workflows/api/runs/getWorkflowRuns.ts} | 6 +- .../src/features/workflows/api/runs/index.ts | 4 + .../api/workflow/deleteWorkflowId.ts} | 6 +- .../workflows/api/workflow/getWorkflow.ts} | 6 +- .../workflows/api/workflow/getWorkflowId.ts} | 6 +- .../features/workflows/api/workflow/index.ts | 5 + .../workflows/api/workflow/postWorkflow.ts} | 8 +- .../api/workflow/postWorkflowRunId.ts} | 6 +- .../WorkflowTaskDetails.tsx | 5 +- .../WorkflowsRunTasksFlowchart/index.tsx | 10 +- .../components/WorkflowsRunsTable/index.tsx | 3 +- .../components/WorkflowsTable/index.tsx | 43 +++--- .../src/features/workflows/context/index.ts | 1 + .../{workflows/index.tsx => workflows.tsx} | 18 +-- frontend/src/features/workflows/index.ts | 3 + .../src/features/workflows/types/index.ts | 2 + .../workflows/types/runs.ts} | 0 .../workflows/types/workflow.ts} | 0 .../workspaceSettings/RepositoriesCard.tsx | 2 +- .../workspaceSettings/SecretsCard.tsx | 8 +- .../workspaceSettings/StorageSecretsCard.tsx | 8 +- .../WorkspaceSecretsCard.tsx | 2 +- .../workspaces/WorkspaceListItem.tsx | 2 +- .../workspaces/WorkspacePendingListItem.tsx | 2 +- .../workspaces/context/workspaceSettings.tsx | 24 ++-- frontend/src/routes/index.tsx | 125 +++++++++++------- frontend/src/services/clients/domino.mock.ts | 3 +- .../services/requests/authentication/index.ts | 2 - frontend/src/services/requests/piece/index.ts | 2 - frontend/src/services/requests/runs/index.ts | 5 - .../src/services/requests/workflow/index.ts | 6 - .../src/services/requests/workspaces/index.ts | 12 -- frontend/src/utils/fetchFromObject.ts | 8 +- frontend/src/utils/index.ts | 2 - 95 files changed, 302 insertions(+), 447 deletions(-) create mode 100644 frontend/src/context/authentication/api/index.ts rename frontend/src/{services/requests/authentication/postAuthLogin.request.ts => context/authentication/api/postAuthLogin.ts} (91%) rename frontend/src/{services/requests/authentication/postAuthRegister.request.ts => context/authentication/api/postAuthRegister.ts} (92%) delete mode 100644 frontend/src/context/workflows/types/containerResources.ts delete mode 100644 frontend/src/context/workflows/types/index.ts delete mode 100644 frontend/src/context/workflows/types/input.ts delete mode 100644 frontend/src/context/workflows/types/settings.ts delete mode 100644 frontend/src/context/workflows/types/storage.ts delete mode 100644 frontend/src/context/workflows/types/workflowPieceData.ts rename frontend/src/{services/requests/workspaces/acceptWorkspaceInvite.request.ts => context/workspaces/api/acceptWorkspaceInvite.ts} (76%) rename frontend/src/{services/requests/workspaces/deleteUserWorkspace.request.ts => context/workspaces/api/deleteUserWorkspace.ts} (92%) rename frontend/src/{services/requests/workspaces/deleteWorkspace.request.ts => context/workspaces/api/deleteWorkspace.ts} (91%) rename frontend/src/{services/requests/workspaces/getWorkspaceId.request.ts => context/workspaces/api/getWorkspaceId.ts} (93%) rename frontend/src/{services/requests/workspaces/getWorkspaceMembers.request.ts => context/workspaces/api/getWorkspaceMembers.ts} (95%) rename frontend/src/{services/requests/workspaces/getWorkspaces.request.ts => context/workspaces/api/getWorkspaces.ts} (92%) create mode 100644 frontend/src/context/workspaces/api/index.ts rename frontend/src/{services/requests/workspaces/inviteWorkspace.request.ts => context/workspaces/api/inviteWorkspace.ts} (93%) rename frontend/src/{services/requests/workspaces/patchWorkspace.reques.ts => context/workspaces/api/patchWorkspace.ts} (94%) rename frontend/src/{services/requests/workspaces/postPiecesRepositories.request.ts => context/workspaces/api/postPiecesRepositories.ts} (97%) rename frontend/src/{services/requests/workspaces/postWorkspaces.request.ts => context/workspaces/api/postWorkspaces.ts} (92%) rename frontend/src/{services/requests/workspaces/rejectWorkspaceInvite.request.ts => context/workspaces/api/rejectWorkspaceInvite.ts} (76%) create mode 100644 frontend/src/context/workspaces/types/index.ts rename frontend/src/{services/requests/workspaces/workspaces.interface.ts => context/workspaces/types/workspaces.ts} (100%) rename frontend/src/features/workflowEditor/components/{WorkflowsEditor.tsx => WorkflowEditor.tsx} (99%) rename frontend/src/features/workflowEditor/context/{workflowsEditor => }/index.tsx (91%) rename frontend/src/features/workflowEditor/context/{workflowsEditor => }/pieces.tsx (95%) rename frontend/src/features/workflowEditor/context/{workflowsEditor => }/workflowEdges.tsx (100%) rename frontend/src/features/workflowEditor/context/{workflowsEditor => }/workflowNodes.tsx (97%) rename frontend/src/features/workflowEditor/context/{workflowsEditor => }/workflowPieces.tsx (100%) rename frontend/src/features/workflowEditor/context/{workflowsEditor => }/workflowPiecesData.tsx (98%) rename frontend/src/features/workflowEditor/context/{workflowsEditor => }/workflowSettingsData.tsx (95%) rename frontend/src/features/workflowEditor/context/{workflowsEditor => }/workflowsEditor.tsx (98%) rename frontend/src/{ => features/workflowEditor}/utils/getFromUpstream.ts (100%) create mode 100644 frontend/src/features/workflowEditor/utils/index.ts rename frontend/src/{ => features/workflowEditor}/utils/jsonSchema.ts (89%) create mode 100644 frontend/src/features/workflows/api/index.ts rename frontend/src/{services/requests => features/workflows/api}/piece/getPieceRepositories.request.ts (96%) rename frontend/src/{services/requests/piece/getPieceRepositoryPieces.request.ts => features/workflows/api/piece/getPieceRepositoryPieces.ts} (93%) rename frontend/src/{services/requests => features/workflows/api}/piece/getPiecesRepositoriesReleases.request.ts (95%) create mode 100644 frontend/src/features/workflows/api/piece/index.ts rename frontend/src/{services/requests => features/workflows/api}/piece/piece.interface.ts (100%) rename frontend/src/{services/requests => features/workflows/api}/repository/deletePieceRepository.request.ts (92%) rename frontend/src/{services/requests => features/workflows/api}/repository/getPieceRepositorySecrets.request.ts (96%) rename frontend/src/{services/requests => features/workflows/api}/repository/index.ts (100%) rename frontend/src/{services/requests => features/workflows/api}/repository/patchPieceRepositorySecret.request.ts (94%) rename frontend/src/{services/requests => features/workflows/api}/repository/pieceRepository.interface.ts (100%) rename frontend/src/{services/requests/runs/getWorkflowRunTaskLogs.request.ts => features/workflows/api/runs/getWorkflowRunTaskLogs.ts} (90%) rename frontend/src/{services/requests/runs/getWorkflowRunTaskResult.request.ts => features/workflows/api/runs/getWorkflowRunTaskResult.ts} (90%) rename frontend/src/{services/requests/runs/getWorkflowRunTasks.request.ts => features/workflows/api/runs/getWorkflowRunTasks.ts} (90%) rename frontend/src/{services/requests/runs/getWorkflowRuns.request.ts => features/workflows/api/runs/getWorkflowRuns.ts} (92%) create mode 100644 frontend/src/features/workflows/api/runs/index.ts rename frontend/src/{services/requests/workflow/deleteWorkflowId.request.ts => features/workflows/api/workflow/deleteWorkflowId.ts} (85%) rename frontend/src/{services/requests/workflow/getWorkflow.request.ts => features/workflows/api/workflow/getWorkflow.ts} (89%) rename frontend/src/{services/requests/workflow/getWorkflowId.request.ts => features/workflows/api/workflow/getWorkflowId.ts} (87%) create mode 100644 frontend/src/features/workflows/api/workflow/index.ts rename frontend/src/{services/requests/workflow/postWorkflow.request.ts => features/workflows/api/workflow/postWorkflow.ts} (77%) rename frontend/src/{services/requests/workflow/postWorkflowRunId.request.ts => features/workflows/api/workflow/postWorkflowRunId.ts} (87%) create mode 100644 frontend/src/features/workflows/context/index.ts rename frontend/src/features/workflows/context/{workflows/index.tsx => workflows.tsx} (99%) create mode 100644 frontend/src/features/workflows/index.ts create mode 100644 frontend/src/features/workflows/types/index.ts rename frontend/src/{services/requests/runs/runs.interface.ts => features/workflows/types/runs.ts} (100%) rename frontend/src/{services/requests/workflow/workflow.interface.ts => features/workflows/types/workflow.ts} (100%) delete mode 100644 frontend/src/services/requests/authentication/index.ts delete mode 100644 frontend/src/services/requests/piece/index.ts delete mode 100644 frontend/src/services/requests/runs/index.ts delete mode 100644 frontend/src/services/requests/workflow/index.ts delete mode 100644 frontend/src/services/requests/workspaces/index.ts diff --git a/frontend/.eslintrc.json b/frontend/.eslintrc.json index 65cda401..f9ed79c3 100644 --- a/frontend/.eslintrc.json +++ b/frontend/.eslintrc.json @@ -79,10 +79,37 @@ "checksVoidReturn": false } ], - "@typescript-eslint/naming-convention": ["warn",{ - "selector": "variable", - "format":["snake_case","camelCase", "PascalCase"] - }], + "@typescript-eslint/naming-convention": [ + "warn", + { + "selector": "variable", + "format": [ + "camelCase", + "snake_case", + "PascalCase", + "UPPER_CASE" + ] + }, + { + "selector": "function", + "format": [ + "camelCase", + "PascalCase" + ] + }, + { + "selector": "typeLike", + "format": [ + "PascalCase" + ] + }, + { + "selector": "enum", + "format":[ + "camelCase" + ] + } + ], "prettier/prettier": [ "error", {} diff --git a/frontend/src/context/authentication/api/index.ts b/frontend/src/context/authentication/api/index.ts new file mode 100644 index 00000000..38581eea --- /dev/null +++ b/frontend/src/context/authentication/api/index.ts @@ -0,0 +1,2 @@ +export * from "./postAuthLogin"; +export * from "./postAuthRegister"; diff --git a/frontend/src/services/requests/authentication/postAuthLogin.request.ts b/frontend/src/context/authentication/api/postAuthLogin.ts similarity index 91% rename from frontend/src/services/requests/authentication/postAuthLogin.request.ts rename to frontend/src/context/authentication/api/postAuthLogin.ts index 26de9c64..003a0df9 100644 --- a/frontend/src/services/requests/authentication/postAuthLogin.request.ts +++ b/frontend/src/context/authentication/api/postAuthLogin.ts @@ -1,6 +1,5 @@ import { type AxiosResponse } from "axios"; - -import { dominoApiClient } from "../../clients/domino.client"; +import { dominoApiClient } from "services/clients/domino.client"; interface IPostAuthLoginParams { email: string; diff --git a/frontend/src/services/requests/authentication/postAuthRegister.request.ts b/frontend/src/context/authentication/api/postAuthRegister.ts similarity index 92% rename from frontend/src/services/requests/authentication/postAuthRegister.request.ts rename to frontend/src/context/authentication/api/postAuthRegister.ts index 6c397ea8..1f021ee8 100644 --- a/frontend/src/services/requests/authentication/postAuthRegister.request.ts +++ b/frontend/src/context/authentication/api/postAuthRegister.ts @@ -1,6 +1,5 @@ import { type AxiosResponse } from "axios"; - -import { dominoApiClient } from "../../clients/domino.client"; +import { dominoApiClient } from "services/clients/domino.client"; interface IPostAuthRegisterParams { email: string; diff --git a/frontend/src/context/authentication/authentication.context.tsx b/frontend/src/context/authentication/authentication.context.tsx index 73dd1604..cb119a91 100644 --- a/frontend/src/context/authentication/authentication.context.tsx +++ b/frontend/src/context/authentication/authentication.context.tsx @@ -10,12 +10,9 @@ import React, { } from "react"; import { useNavigate } from "react-router-dom"; import { toast } from "react-toastify"; -import { - postAuthLogin, - postAuthRegister, -} from "services/requests/authentication"; import { createCustomContext } from "utils"; +import { postAuthLogin, postAuthRegister } from "./api"; import { type IAuthenticationContext, type IAuthenticationStore, diff --git a/frontend/src/context/workflows/types/containerResources.ts b/frontend/src/context/workflows/types/containerResources.ts deleted file mode 100644 index 5a162d69..00000000 --- a/frontend/src/context/workflows/types/containerResources.ts +++ /dev/null @@ -1,11 +0,0 @@ -export interface IContainerResourceFormData { - useGpu: boolean; - cpu: { - min: number; - max: number; - }; - memory: { - min: number; - max: number; - }; -} diff --git a/frontend/src/context/workflows/types/index.ts b/frontend/src/context/workflows/types/index.ts deleted file mode 100644 index 087062d5..00000000 --- a/frontend/src/context/workflows/types/index.ts +++ /dev/null @@ -1,4 +0,0 @@ -export * from "./containerResources"; -export * from "./storage"; -export * from "./workflowPieceData"; -export * from "./input"; diff --git a/frontend/src/context/workflows/types/input.ts b/frontend/src/context/workflows/types/input.ts deleted file mode 100644 index 2edb4035..00000000 --- a/frontend/src/context/workflows/types/input.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { type Dayjs } from "dayjs"; - -type Value = string | number | boolean | Dayjs; -interface BaseInput { - fromUpstream: boolean; // ? allowed | never | always - upstreamArgument: string; - upstreamId: string; - upstreamValue: string; - value: Value; -} - -export interface ObjectInput { - fromUpstream: Record; - upstreamArgument: Record; - upstreamId: Record; - upstreamValue: Record; - value: Record; -} - -export type InputArray = BaseInput & { - value: BaseInput[] | ObjectInput[]; -}; - -export type Input = BaseInput; diff --git a/frontend/src/context/workflows/types/settings.ts b/frontend/src/context/workflows/types/settings.ts deleted file mode 100644 index 0657c33b..00000000 --- a/frontend/src/context/workflows/types/settings.ts +++ /dev/null @@ -1,50 +0,0 @@ -export enum scheduleIntervals { - None = "none", - Once = "once", - Hourly = "hourly", - Daily = "daily", - Weekly = "weekly", - Monthly = "monthly", - Yearly = "yearly", -} - -export type ScheduleIntervals = `${scheduleIntervals}`; - -export enum endDateTypes { - Never = "never", - UserDefined = "User defined", -} - -export type EndDateTypes = `${endDateTypes}`; - -export enum storageSourcesAWS { - None = "None", - AWSS3 = "AWS S3", -} - -export type StorageSourcesAWS = `${storageSourcesAWS}`; - -export enum storageSourcesLocal { - None = "None", - Local = "Local", -} - -export type StorageSourcesLocal = `${storageSourcesLocal}`; - -export interface IWorkflowSettingsConfig { - name: string; - scheduleInterval: ScheduleIntervals; - startDate: string; - endDate?: string; - endDateType: EndDateTypes; -} - -export interface IWorkflowSettingsStorage { - storageSource: StorageSourcesAWS | StorageSourcesLocal; - baseFolder?: string; - bucket?: string; -} -export interface IWorkflowSettings { - config: IWorkflowSettingsConfig; - storage: IWorkflowSettingsStorage; -} diff --git a/frontend/src/context/workflows/types/storage.ts b/frontend/src/context/workflows/types/storage.ts deleted file mode 100644 index 88708693..00000000 --- a/frontend/src/context/workflows/types/storage.ts +++ /dev/null @@ -1,11 +0,0 @@ -export enum storageAccessModes { - None = "None", - Read = "Read", - ReadWrite = "Read/Write", -} -// Equivalent to type StorageAccessModes = "None" | "Read" | "Read/Write" -export type StorageAccessModes = `${storageAccessModes}`; - -export interface IStorageFormData { - storageAccessMode: StorageAccessModes; -} diff --git a/frontend/src/context/workflows/types/workflowPieceData.ts b/frontend/src/context/workflows/types/workflowPieceData.ts deleted file mode 100644 index 72b02b85..00000000 --- a/frontend/src/context/workflows/types/workflowPieceData.ts +++ /dev/null @@ -1,72 +0,0 @@ -import { type Edge } from "reactflow"; -import { type IWorkflowElement } from "services/requests/workflow"; - -import { type IContainerResourceFormData } from "./containerResources"; -import { type InputArray, type Input } from "./input"; -import { - type EndDateTypes, - type ScheduleIntervals, - type StorageSourcesAWS, - type StorageSourcesLocal, -} from "./settings"; -import { type IStorageFormData, type StorageAccessModes } from "./storage"; - -export interface IWorkflowPieceData { - storage: IStorageFormData; - containerResources: IContainerResourceFormData; - inputs: Record; -} - -interface WorkflowBaseSettings { - name: string; - start_date: string; // ISOFormat - select_end_date: EndDateTypes; - schedule_interval: ScheduleIntervals; - - end_date?: string; // ISOFormat - catchup?: boolean; - generate_report?: boolean; - description?: string; -} - -interface UiSchema { - nodes: Record; - edges: Edge[]; -} - -interface WorkflowSharedStorageDataModel { - source: StorageSourcesLocal | StorageSourcesAWS; - base_folder?: string; - mode: StorageAccessModes; - provider_options?: Record; -} - -interface SystemRequirementsModel { - cpu: number; - memory: number; -} -interface ContainerResourcesDataModel { - requests: SystemRequirementsModel; - limits: SystemRequirementsModel; - use_gpu: boolean; -} - -export interface TasksDataModel { - workflow_shared_storage: WorkflowSharedStorageDataModel; - container_resources: ContainerResourcesDataModel; - task_id: string; - piece: { - id: number; - name: string; - }; - piece_input_kwargs: Record; - dependencies?: string[]; -} - -type TasksDict = Record; - -export interface CreateWorkflowRequest { - workflow: WorkflowBaseSettings; - tasks: TasksDict; - ui_schema: UiSchema; -} diff --git a/frontend/src/services/requests/workspaces/acceptWorkspaceInvite.request.ts b/frontend/src/context/workspaces/api/acceptWorkspaceInvite.ts similarity index 76% rename from frontend/src/services/requests/workspaces/acceptWorkspaceInvite.request.ts rename to frontend/src/context/workspaces/api/acceptWorkspaceInvite.ts index 9cf887f7..14f509a7 100644 --- a/frontend/src/services/requests/workspaces/acceptWorkspaceInvite.request.ts +++ b/frontend/src/context/workspaces/api/acceptWorkspaceInvite.ts @@ -1,9 +1,8 @@ // TODO move to /runs import { type AxiosResponse } from "axios"; +import { dominoApiClient } from "services/clients/domino.client"; -import { dominoApiClient } from "../../clients/domino.client"; - -interface acceptWorkspaceInviteParams { +interface AcceptWorkspaceInviteParams { workspaceId: string; } @@ -15,7 +14,7 @@ const acceptWorkspaceInviteUrl = (workspaceId: string) => * @returns workflow run result */ const acceptWorkspaceInvite: ( - params: acceptWorkspaceInviteParams, + params: AcceptWorkspaceInviteParams, ) => Promise = async (params) => { return await dominoApiClient.post( acceptWorkspaceInviteUrl(params.workspaceId), @@ -28,7 +27,7 @@ const acceptWorkspaceInvite: ( * @param params `{ id: string }` */ export const useAuthenticatedAcceptWorkspaceInvite = () => { - const fetcher = async (params: acceptWorkspaceInviteParams) => + const fetcher = async (params: AcceptWorkspaceInviteParams) => await acceptWorkspaceInvite(params).then((data) => data); return fetcher; diff --git a/frontend/src/services/requests/workspaces/deleteUserWorkspace.request.ts b/frontend/src/context/workspaces/api/deleteUserWorkspace.ts similarity index 92% rename from frontend/src/services/requests/workspaces/deleteUserWorkspace.request.ts rename to frontend/src/context/workspaces/api/deleteUserWorkspace.ts index b3cee2c2..7d2569a5 100644 --- a/frontend/src/services/requests/workspaces/deleteUserWorkspace.request.ts +++ b/frontend/src/context/workspaces/api/deleteUserWorkspace.ts @@ -1,7 +1,6 @@ // TODO move to /runs import { type AxiosResponse } from "axios"; - -import { dominoApiClient } from "../../clients/domino.client"; +import { dominoApiClient } from "services/clients/domino.client"; interface removeUserWorkspaceParams { workspaceId: string; diff --git a/frontend/src/services/requests/workspaces/deleteWorkspace.request.ts b/frontend/src/context/workspaces/api/deleteWorkspace.ts similarity index 91% rename from frontend/src/services/requests/workspaces/deleteWorkspace.request.ts rename to frontend/src/context/workspaces/api/deleteWorkspace.ts index 69f669e7..99d60ac4 100644 --- a/frontend/src/services/requests/workspaces/deleteWorkspace.request.ts +++ b/frontend/src/context/workspaces/api/deleteWorkspace.ts @@ -1,7 +1,6 @@ import { type AxiosResponse } from "axios"; import { useCallback } from "react"; - -import { dominoApiClient } from "../../clients/domino.client"; +import { dominoApiClient } from "services/clients/domino.client"; type IDeleteWorkspacesResponseInterface = unknown; diff --git a/frontend/src/services/requests/workspaces/getWorkspaceId.request.ts b/frontend/src/context/workspaces/api/getWorkspaceId.ts similarity index 93% rename from frontend/src/services/requests/workspaces/getWorkspaceId.request.ts rename to frontend/src/context/workspaces/api/getWorkspaceId.ts index 4e136e8d..33a69b72 100644 --- a/frontend/src/services/requests/workspaces/getWorkspaceId.request.ts +++ b/frontend/src/context/workspaces/api/getWorkspaceId.ts @@ -2,7 +2,7 @@ import { type AxiosResponse } from "axios"; import { dominoApiClient } from "services/clients/domino.client"; import useSWR from "swr"; -import { type IGetWorkspaceIdResponseInterface } from "./workspaces.interface"; +import { type IGetWorkspaceIdResponseInterface } from "../types/workspaces"; interface IGetWorkspaceIdParams { id: string; diff --git a/frontend/src/services/requests/workspaces/getWorkspaceMembers.request.ts b/frontend/src/context/workspaces/api/getWorkspaceMembers.ts similarity index 95% rename from frontend/src/services/requests/workspaces/getWorkspaceMembers.request.ts rename to frontend/src/context/workspaces/api/getWorkspaceMembers.ts index 58b483d9..d5a06313 100644 --- a/frontend/src/services/requests/workspaces/getWorkspaceMembers.request.ts +++ b/frontend/src/context/workspaces/api/getWorkspaceMembers.ts @@ -4,7 +4,7 @@ import { useCallback } from "react"; import { dominoApiClient } from "services/clients/domino.client"; import useSWR from "swr"; -import { type IGetWorkspaceUsersResponse } from "./workspaces.interface"; +import { type IGetWorkspaceUsersResponse } from "../types/workspaces"; interface IGetWorkspaceMembers { workspaceId: string; diff --git a/frontend/src/services/requests/workspaces/getWorkspaces.request.ts b/frontend/src/context/workspaces/api/getWorkspaces.ts similarity index 92% rename from frontend/src/services/requests/workspaces/getWorkspaces.request.ts rename to frontend/src/context/workspaces/api/getWorkspaces.ts index 0c111686..e0f7805a 100644 --- a/frontend/src/services/requests/workspaces/getWorkspaces.request.ts +++ b/frontend/src/context/workspaces/api/getWorkspaces.ts @@ -4,7 +4,7 @@ import { useCallback } from "react"; import { dominoApiClient } from "services/clients/domino.client"; import useSWR from "swr"; -import { type IGetWorkspacesResponseInterface } from "./workspaces.interface"; +import { type IGetWorkspacesResponseInterface } from "../types/workspaces"; /** * Get workspaces using GET /workspaces diff --git a/frontend/src/context/workspaces/api/index.ts b/frontend/src/context/workspaces/api/index.ts new file mode 100644 index 00000000..4ea560e5 --- /dev/null +++ b/frontend/src/context/workspaces/api/index.ts @@ -0,0 +1,11 @@ +export * from "./getWorkspaceId"; +export * from "./getWorkspaces"; +export * from "./postPiecesRepositories"; +export * from "./postWorkspaces"; +export * from "./deleteWorkspace"; +export * from "./patchWorkspace"; +export * from "./acceptWorkspaceInvite"; +export * from "./rejectWorkspaceInvite"; +export * from "./inviteWorkspace"; +export * from "./deleteUserWorkspace"; +export * from "./getWorkspaceMembers"; diff --git a/frontend/src/services/requests/workspaces/inviteWorkspace.request.ts b/frontend/src/context/workspaces/api/inviteWorkspace.ts similarity index 93% rename from frontend/src/services/requests/workspaces/inviteWorkspace.request.ts rename to frontend/src/context/workspaces/api/inviteWorkspace.ts index 41f0acf0..22aa3615 100644 --- a/frontend/src/services/requests/workspaces/inviteWorkspace.request.ts +++ b/frontend/src/context/workspaces/api/inviteWorkspace.ts @@ -1,7 +1,6 @@ // TODO move to /runs import { type AxiosResponse } from "axios"; - -import { dominoApiClient } from "../../clients/domino.client"; +import { dominoApiClient } from "services/clients/domino.client"; interface inviteWorkspaceParams { workspaceId: string; diff --git a/frontend/src/services/requests/workspaces/patchWorkspace.reques.ts b/frontend/src/context/workspaces/api/patchWorkspace.ts similarity index 94% rename from frontend/src/services/requests/workspaces/patchWorkspace.reques.ts rename to frontend/src/context/workspaces/api/patchWorkspace.ts index c7c91022..3c34bd08 100644 --- a/frontend/src/services/requests/workspaces/patchWorkspace.reques.ts +++ b/frontend/src/context/workspaces/api/patchWorkspace.ts @@ -1,8 +1,7 @@ // TODO move to /runs import { type AxiosResponse } from "axios"; import { useWorkspaces } from "context/workspaces"; - -import { dominoApiClient } from "../../clients/domino.client"; +import { dominoApiClient } from "services/clients/domino.client"; interface patchWorkspaceParams { workspaceId: string; diff --git a/frontend/src/services/requests/workspaces/postPiecesRepositories.request.ts b/frontend/src/context/workspaces/api/postPiecesRepositories.ts similarity index 97% rename from frontend/src/services/requests/workspaces/postPiecesRepositories.request.ts rename to frontend/src/context/workspaces/api/postPiecesRepositories.ts index 3383850c..93b8886d 100644 --- a/frontend/src/services/requests/workspaces/postPiecesRepositories.request.ts +++ b/frontend/src/context/workspaces/api/postPiecesRepositories.ts @@ -5,7 +5,7 @@ import { type IPostWorkspaceRepositoryParams, type IPostWorkspaceRepositoryPayload, type IPostWorkspaceRepositoryResponseInterface, -} from "./workspaces.interface"; +} from "../types/workspaces"; /** * Create workspacesidPiecesrepositories using POST /workspacesidPiecesrepositories diff --git a/frontend/src/services/requests/workspaces/postWorkspaces.request.ts b/frontend/src/context/workspaces/api/postWorkspaces.ts similarity index 92% rename from frontend/src/services/requests/workspaces/postWorkspaces.request.ts rename to frontend/src/context/workspaces/api/postWorkspaces.ts index e5b0eccc..cdb12f69 100644 --- a/frontend/src/services/requests/workspaces/postWorkspaces.request.ts +++ b/frontend/src/context/workspaces/api/postWorkspaces.ts @@ -1,7 +1,6 @@ import { type AxiosResponse } from "axios"; import { useCallback } from "react"; - -import { dominoApiClient } from "../../clients/domino.client"; +import { dominoApiClient } from "services/clients/domino.client"; type IPostWorkspacesResponseInterface = Record; diff --git a/frontend/src/services/requests/workspaces/rejectWorkspaceInvite.request.ts b/frontend/src/context/workspaces/api/rejectWorkspaceInvite.ts similarity index 76% rename from frontend/src/services/requests/workspaces/rejectWorkspaceInvite.request.ts rename to frontend/src/context/workspaces/api/rejectWorkspaceInvite.ts index aaabfbba..132398e5 100644 --- a/frontend/src/services/requests/workspaces/rejectWorkspaceInvite.request.ts +++ b/frontend/src/context/workspaces/api/rejectWorkspaceInvite.ts @@ -1,9 +1,8 @@ // TODO move to /runs import { type AxiosResponse } from "axios"; +import { dominoApiClient } from "services/clients/domino.client"; -import { dominoApiClient } from "../../clients/domino.client"; - -interface rejectWorkspaceInviteParams { +interface RejectWorkspaceInviteParams { workspaceId: string; } @@ -15,7 +14,7 @@ const rejectWorkspaceInviteUrl = (workspaceId: string) => * @returns workflow run result */ const rejectWorkspaceInvite: ( - params: rejectWorkspaceInviteParams, + params: RejectWorkspaceInviteParams, ) => Promise = async (params) => { return await dominoApiClient.post( rejectWorkspaceInviteUrl(params.workspaceId), @@ -28,7 +27,7 @@ const rejectWorkspaceInvite: ( * @param params `{ id: string }` */ export const useAuthenticatedRejectWorkspaceInvite = () => { - const fetcher = async (params: rejectWorkspaceInviteParams) => + const fetcher = async (params: RejectWorkspaceInviteParams) => await rejectWorkspaceInvite(params).then((data) => data); return fetcher; diff --git a/frontend/src/context/workspaces/index.tsx b/frontend/src/context/workspaces/index.tsx index c5dd826c..8a09b2fa 100644 --- a/frontend/src/context/workspaces/index.tsx +++ b/frontend/src/context/workspaces/index.tsx @@ -1,7 +1,8 @@ import { type FC, useCallback, useMemo, useState } from "react"; import { toast } from "react-toastify"; +import { createCustomContext } from "utils"; + import { - type IWorkspaceSummary, useAuthenticatedGetWorkspaces, useAuthenticatedPostWorkspaces, useAuthenticatedDeleteWorkspaces, @@ -10,8 +11,8 @@ import { useAuthenticatedWorkspaceInvite, useAuthenticatedRemoveUserWorkspace, useAuthenticatedGetWorkspaceUsers, -} from "services/requests/workspaces"; -import { createCustomContext } from "utils"; +} from "./api"; +import { type IWorkspaceSummary } from "./types/workspaces"; interface IWorkspacesContext { workspaces: IWorkspaceSummary[]; diff --git a/frontend/src/context/workspaces/types/index.ts b/frontend/src/context/workspaces/types/index.ts new file mode 100644 index 00000000..5b84fc9b --- /dev/null +++ b/frontend/src/context/workspaces/types/index.ts @@ -0,0 +1 @@ +export * from "./workspaces"; diff --git a/frontend/src/services/requests/workspaces/workspaces.interface.ts b/frontend/src/context/workspaces/types/workspaces.ts similarity index 100% rename from frontend/src/services/requests/workspaces/workspaces.interface.ts rename to frontend/src/context/workspaces/types/workspaces.ts diff --git a/frontend/src/features/workflowEditor/components/DrawerMenu/sidebarAddNode.tsx b/frontend/src/features/workflowEditor/components/DrawerMenu/sidebarAddNode.tsx index 0d40f69d..b567eb5b 100644 --- a/frontend/src/features/workflowEditor/components/DrawerMenu/sidebarAddNode.tsx +++ b/frontend/src/features/workflowEditor/components/DrawerMenu/sidebarAddNode.tsx @@ -9,7 +9,7 @@ import { ToggleButtonGroup, Typography, } from "@mui/material"; -import { useWorkflowsEditor } from "features/workflowEditor/context/workflowsEditor"; +import { useWorkflowsEditor } from "features/workflowEditor/context"; import { type FC, type SyntheticEvent, useState } from "react"; import PiecesSidebarNode from "./sidebarNode"; diff --git a/frontend/src/features/workflowEditor/components/SidebarSettingsForm/index.tsx b/frontend/src/features/workflowEditor/components/SidebarSettingsForm/index.tsx index 802bc22f..391839b8 100644 --- a/frontend/src/features/workflowEditor/components/SidebarSettingsForm/index.tsx +++ b/frontend/src/features/workflowEditor/components/SidebarSettingsForm/index.tsx @@ -3,6 +3,7 @@ import DatetimeInput from "components/DatetimeInput"; import SelectInput from "components/SelectInput"; import TextInput from "components/TextInput"; import dayjs from "dayjs"; +import { useWorkflowsEditor } from "features/workflowEditor/context"; import { type EndDateTypes, type IWorkflowSettings, @@ -13,8 +14,7 @@ import { scheduleIntervals, storageSourcesAWS, storageSourcesLocal, -} from "features/workflowEditor/context/types/settings"; -import { useWorkflowsEditor } from "features/workflowEditor/context/workflowsEditor"; +} from "features/workflowEditor/context/types"; import { useCallback, useEffect, useState } from "react"; import { FormProvider, useForm } from "react-hook-form"; import { yupResolver } from "utils"; diff --git a/frontend/src/features/workflowEditor/components/WorkflowsEditor.tsx b/frontend/src/features/workflowEditor/components/WorkflowEditor.tsx similarity index 99% rename from frontend/src/features/workflowEditor/components/WorkflowsEditor.tsx rename to frontend/src/features/workflowEditor/components/WorkflowEditor.tsx index b590648a..dea74956 100644 --- a/frontend/src/features/workflowEditor/components/WorkflowsEditor.tsx +++ b/frontend/src/features/workflowEditor/components/WorkflowEditor.tsx @@ -5,13 +5,12 @@ import SaveIcon from "@mui/icons-material/Save"; import { Button, Grid, Paper, Backdrop, CircularProgress } from "@mui/material"; import { AxiosError } from "axios"; import { useWorkspaces } from "context/workspaces"; +import { useWorkflowsEditor } from "features/workflowEditor/context"; import { useCallback, useState } from "react"; import { toast } from "react-toastify"; import { yupResolver } from "utils"; import * as yup from "yup"; -import { useWorkflowsEditor } from "../context/workflowsEditor"; - import { PermanentDrawerRightWorkflows } from "./DrawerMenu"; import SidebarSettingsForm, { WorkflowSettingsFormSchema, diff --git a/frontend/src/features/workflowEditor/components/WorkflowEditorPanel/index.tsx b/frontend/src/features/workflowEditor/components/WorkflowEditorPanel/index.tsx index 6ddc6e77..d8e36fed 100644 --- a/frontend/src/features/workflowEditor/components/WorkflowEditorPanel/index.tsx +++ b/frontend/src/features/workflowEditor/components/WorkflowEditorPanel/index.tsx @@ -1,10 +1,14 @@ import CustomNode, { type INodeData } from "components/CustomNode"; +import { useWorkflowsEditor } from "features/workflowEditor/context"; import { type IWorkflowPieceData, storageAccessModes, } from "features/workflowEditor/context/types"; -import { useWorkflowsEditor } from "features/workflowEditor/context/workflowsEditor"; import { containerResourcesSchema } from "features/workflowEditor/schemas/containerResourcesSchemas"; +import { + extractDefaultInputValues, + extractDefaultValues, +} from "features/workflowEditor/utils"; import React, { useCallback, useEffect, useRef, useState } from "react"; import ReactFlow, { addEdge, @@ -21,7 +25,6 @@ import ReactFlow, { // removeElements, type Node, } from "reactflow"; -import { extractDefaultValues, extractDefaultInputValues } from "utils"; import { v4 as uuidv4 } from "uuid"; import SidebarForm from "./sidebarForm"; diff --git a/frontend/src/features/workflowEditor/components/WorkflowEditorPanel/sidebarForm/index.tsx b/frontend/src/features/workflowEditor/components/WorkflowEditorPanel/sidebarForm/index.tsx index 7afdc387..e20d7a12 100644 --- a/frontend/src/features/workflowEditor/components/WorkflowEditorPanel/sidebarForm/index.tsx +++ b/frontend/src/features/workflowEditor/components/WorkflowEditorPanel/sidebarForm/index.tsx @@ -7,8 +7,8 @@ import { AccordionSummary, AccordionDetails, } from "@mui/material"; +import { useWorkflowsEditor } from "features/workflowEditor/context"; import { type IWorkflowPieceData } from "features/workflowEditor/context/types"; -import { useWorkflowsEditor } from "features/workflowEditor/context/workflowsEditor"; import React, { useCallback, useEffect, useMemo, useState } from "react"; import { FormProvider, useForm } from "react-hook-form"; import { yupResolver } from "utils"; diff --git a/frontend/src/features/workflowEditor/components/WorkflowEditorPanel/sidebarForm/pieceForm/index.tsx b/frontend/src/features/workflowEditor/components/WorkflowEditorPanel/sidebarForm/pieceForm/index.tsx index f8581d4d..5f308cb2 100644 --- a/frontend/src/features/workflowEditor/components/WorkflowEditorPanel/sidebarForm/pieceForm/index.tsx +++ b/frontend/src/features/workflowEditor/components/WorkflowEditorPanel/sidebarForm/pieceForm/index.tsx @@ -1,5 +1,5 @@ +import { useWorkflowsEditor } from "features/workflowEditor/context"; import { type IWorkflowPieceData } from "features/workflowEditor/context/types"; -import { useWorkflowsEditor } from "features/workflowEditor/context/workflowsEditor"; import React, { useCallback, useEffect, useMemo, useState } from "react"; import { useFormContext } from "react-hook-form"; diff --git a/frontend/src/features/workflowEditor/components/WorkflowEditorPanel/sidebarForm/pieceForm/pieceFormItem/arrayInput.tsx b/frontend/src/features/workflowEditor/components/WorkflowEditorPanel/sidebarForm/pieceForm/pieceFormItem/arrayInput.tsx index a8a38b01..459c5a37 100644 --- a/frontend/src/features/workflowEditor/components/WorkflowEditorPanel/sidebarForm/pieceForm/pieceFormItem/arrayInput.tsx +++ b/frontend/src/features/workflowEditor/components/WorkflowEditorPanel/sidebarForm/pieceForm/pieceFormItem/arrayInput.tsx @@ -11,6 +11,7 @@ import { type InputArray, type IWorkflowPieceData, } from "features/workflowEditor/context/types"; +import { getFromUpstream } from "features/workflowEditor/utils"; import React, { useCallback, useMemo, useState } from "react"; import { type Control, @@ -18,7 +19,6 @@ import { useFieldArray, useWatch, } from "react-hook-form"; -import { getFromUpstream } from "utils"; import { type ArrayOption } from "../../pieceForm/upstreamOptions"; diff --git a/frontend/src/features/workflowEditor/context/workflowsEditor/index.tsx b/frontend/src/features/workflowEditor/context/index.tsx similarity index 91% rename from frontend/src/features/workflowEditor/context/workflowsEditor/index.tsx rename to frontend/src/features/workflowEditor/context/index.tsx index 0ccfe587..b9767278 100644 --- a/frontend/src/features/workflowEditor/context/workflowsEditor/index.tsx +++ b/frontend/src/features/workflowEditor/context/index.tsx @@ -10,7 +10,7 @@ import WorkflowSettingsDataProvider from "./workflowSettingsData"; export { useWorkflowsEditor }; -const WorkflowsEditorProvider: React.FC<{ +const WorkflowsEditorProviderWrapper: React.FC<{ children: React.ReactNode; }> = ({ children }) => { return ( @@ -32,4 +32,4 @@ const WorkflowsEditorProvider: React.FC<{ ); }; -export default WorkflowsEditorProvider; +export default WorkflowsEditorProviderWrapper; diff --git a/frontend/src/features/workflowEditor/context/workflowsEditor/pieces.tsx b/frontend/src/features/workflowEditor/context/pieces.tsx similarity index 95% rename from frontend/src/features/workflowEditor/context/workflowsEditor/pieces.tsx rename to frontend/src/features/workflowEditor/context/pieces.tsx index 9437f3e9..c2af1864 100644 --- a/frontend/src/features/workflowEditor/context/workflowsEditor/pieces.tsx +++ b/frontend/src/features/workflowEditor/context/pieces.tsx @@ -1,11 +1,11 @@ -import React, { useCallback, useEffect, useMemo, useState } from "react"; -import { toast } from "react-toastify"; -import localForage from "services/config/localForage.config"; import { type IGetRepoPiecesResponseInterface, useAuthenticatedGetPieceRepositories, -} from "services/requests/piece"; -import { useFetchAuthenticatedGetRepoIdPieces } from "services/requests/piece/getPieceRepositoryPieces.request"; + useFetchAuthenticatedGetRepoIdPieces, +} from "features/workflows/api"; +import React, { useCallback, useEffect, useMemo, useState } from "react"; +import { toast } from "react-toastify"; +import localForage from "services/config/localForage.config"; import { createCustomContext } from "utils"; export interface IPiecesContext { diff --git a/frontend/src/features/workflowEditor/context/types/index.ts b/frontend/src/features/workflowEditor/context/types/index.ts index 087062d5..9808678a 100644 --- a/frontend/src/features/workflowEditor/context/types/index.ts +++ b/frontend/src/features/workflowEditor/context/types/index.ts @@ -2,3 +2,4 @@ export * from "./containerResources"; export * from "./storage"; export * from "./workflowPieceData"; export * from "./input"; +export * from "./settings"; diff --git a/frontend/src/features/workflowEditor/context/types/workflowPieceData.ts b/frontend/src/features/workflowEditor/context/types/workflowPieceData.ts index 72b02b85..6046a3e1 100644 --- a/frontend/src/features/workflowEditor/context/types/workflowPieceData.ts +++ b/frontend/src/features/workflowEditor/context/types/workflowPieceData.ts @@ -1,5 +1,5 @@ +import { type IWorkflowElement } from "features/workflows/types"; import { type Edge } from "reactflow"; -import { type IWorkflowElement } from "services/requests/workflow"; import { type IContainerResourceFormData } from "./containerResources"; import { type InputArray, type Input } from "./input"; diff --git a/frontend/src/features/workflowEditor/context/workflowsEditor/workflowEdges.tsx b/frontend/src/features/workflowEditor/context/workflowEdges.tsx similarity index 100% rename from frontend/src/features/workflowEditor/context/workflowsEditor/workflowEdges.tsx rename to frontend/src/features/workflowEditor/context/workflowEdges.tsx diff --git a/frontend/src/features/workflowEditor/context/workflowsEditor/workflowNodes.tsx b/frontend/src/features/workflowEditor/context/workflowNodes.tsx similarity index 97% rename from frontend/src/features/workflowEditor/context/workflowsEditor/workflowNodes.tsx rename to frontend/src/features/workflowEditor/context/workflowNodes.tsx index e7e6e7d3..e027e973 100644 --- a/frontend/src/features/workflowEditor/context/workflowsEditor/workflowNodes.tsx +++ b/frontend/src/features/workflowEditor/context/workflowNodes.tsx @@ -1,7 +1,7 @@ +import { type IWorkflowElement } from "features/workflows/types"; import React, { useCallback, useEffect, useState } from "react"; import { type Node } from "reactflow"; import localForage from "services/config/localForage.config"; -import { type IWorkflowElement } from "services/requests/workflow"; import { createCustomContext } from "utils"; export interface IWorkflowsNodesContext { diff --git a/frontend/src/features/workflowEditor/context/workflowsEditor/workflowPieces.tsx b/frontend/src/features/workflowEditor/context/workflowPieces.tsx similarity index 100% rename from frontend/src/features/workflowEditor/context/workflowsEditor/workflowPieces.tsx rename to frontend/src/features/workflowEditor/context/workflowPieces.tsx diff --git a/frontend/src/features/workflowEditor/context/workflowsEditor/workflowPiecesData.tsx b/frontend/src/features/workflowEditor/context/workflowPiecesData.tsx similarity index 98% rename from frontend/src/features/workflowEditor/context/workflowsEditor/workflowPiecesData.tsx rename to frontend/src/features/workflowEditor/context/workflowPiecesData.tsx index 76125912..7d6074b4 100644 --- a/frontend/src/features/workflowEditor/context/workflowsEditor/workflowPiecesData.tsx +++ b/frontend/src/features/workflowEditor/context/workflowPiecesData.tsx @@ -2,7 +2,7 @@ import React, { useCallback } from "react"; import localForage from "services/config/localForage.config"; import { createCustomContext, getUuid } from "utils"; -import { type IWorkflowPieceData } from "../types"; +import { type IWorkflowPieceData } from "./types"; type ForagePiecesData = Record; diff --git a/frontend/src/features/workflowEditor/context/workflowsEditor/workflowSettingsData.tsx b/frontend/src/features/workflowEditor/context/workflowSettingsData.tsx similarity index 95% rename from frontend/src/features/workflowEditor/context/workflowsEditor/workflowSettingsData.tsx rename to frontend/src/features/workflowEditor/context/workflowSettingsData.tsx index 5e2e40b4..d8fd2ed0 100644 --- a/frontend/src/features/workflowEditor/context/workflowsEditor/workflowSettingsData.tsx +++ b/frontend/src/features/workflowEditor/context/workflowSettingsData.tsx @@ -2,7 +2,7 @@ import React, { useCallback } from "react"; import localForage from "services/config/localForage.config"; import { createCustomContext } from "utils"; -import { type IWorkflowSettings } from "../types/settings"; +import { type IWorkflowSettings } from "./types"; export interface IWorkflowSettingsContext { fetchWorkflowSettingsData: () => Promise; diff --git a/frontend/src/features/workflowEditor/context/workflowsEditor/workflowsEditor.tsx b/frontend/src/features/workflowEditor/context/workflowsEditor.tsx similarity index 98% rename from frontend/src/features/workflowEditor/context/workflowsEditor/workflowsEditor.tsx rename to frontend/src/features/workflowEditor/context/workflowsEditor.tsx index ea179221..103a7786 100644 --- a/frontend/src/features/workflowEditor/context/workflowsEditor/workflowsEditor.tsx +++ b/frontend/src/features/workflowEditor/context/workflowsEditor.tsx @@ -1,15 +1,14 @@ import { useWorkspaces } from "context/workspaces"; -import React, { type FC, useCallback } from "react"; import { type IPostWorkflowParams, useAuthenticatedPostWorkflow, - type IPostWorkflowResponseInterface, -} from "services/requests/workflow"; +} from "features/workflows/api"; +import { type IPostWorkflowResponseInterface } from "features/workflows/types"; +import React, { type FC, useCallback } from "react"; import { createCustomContext, generateTaskName, getIdSlice } from "utils"; -import { type CreateWorkflowRequest, type TasksDataModel } from "../types"; - import { usesPieces, type IPiecesContext } from "./pieces"; +import { type CreateWorkflowRequest, type TasksDataModel } from "./types"; import { useWorkflowsEdges, type IWorkflowsEdgesContext, diff --git a/frontend/src/features/workflowEditor/pages/workflowEditorPage.tsx b/frontend/src/features/workflowEditor/pages/workflowEditorPage.tsx index 0ca798b8..6e987c9f 100644 --- a/frontend/src/features/workflowEditor/pages/workflowEditorPage.tsx +++ b/frontend/src/features/workflowEditor/pages/workflowEditorPage.tsx @@ -1,8 +1,8 @@ import { Grid } from "@mui/material"; import PrivateLayout from "components/PrivateLayout"; -import { WorkflowsEditorComponent } from "../components/WorkflowsEditor"; -import WorkflowsEditorProvider from "../context/workflowsEditor"; +import { WorkflowsEditorComponent } from "../components/WorkflowEditor"; +import WorkflowsEditorProviderWrapper from "../context"; /** * Workflows editor page */ @@ -12,9 +12,9 @@ export const WorkflowsEditorPage: React.FC = () => { - + - + diff --git a/frontend/src/utils/getFromUpstream.ts b/frontend/src/features/workflowEditor/utils/getFromUpstream.ts similarity index 100% rename from frontend/src/utils/getFromUpstream.ts rename to frontend/src/features/workflowEditor/utils/getFromUpstream.ts diff --git a/frontend/src/features/workflowEditor/utils/index.ts b/frontend/src/features/workflowEditor/utils/index.ts new file mode 100644 index 00000000..3fca25de --- /dev/null +++ b/frontend/src/features/workflowEditor/utils/index.ts @@ -0,0 +1,2 @@ +export * from "./getFromUpstream"; +export * from "./jsonSchema"; diff --git a/frontend/src/utils/jsonSchema.ts b/frontend/src/features/workflowEditor/utils/jsonSchema.ts similarity index 89% rename from frontend/src/utils/jsonSchema.ts rename to frontend/src/features/workflowEditor/utils/jsonSchema.ts index 854755d1..ed6c962d 100644 --- a/frontend/src/utils/jsonSchema.ts +++ b/frontend/src/features/workflowEditor/utils/jsonSchema.ts @@ -1,6 +1,6 @@ // Extract default values from Schema -import { type IWorkflowPieceData } from "context/workflows/types"; +import { type IWorkflowPieceData } from "../context/types"; import { getFromUpstream } from "./getFromUpstream"; @@ -26,32 +26,32 @@ export const extractDefaultInputValues = (pieceSchema: Piece) => { upstreamValue: {}, value: {}, }; - for (const [_key, _value] of Object.entries(element)) { + for (const [objKey, objValue] of Object.entries(element)) { const fromUpstream = getFromUpstream( schema[key], definitions, - _key, + objKey, ); newValue.fromUpstream = { ...newValue.fromUpstream, - [_key]: fromUpstream, + [objKey]: fromUpstream, }; newValue.upstreamId = { ...newValue.upstreamId, - [_key]: "", + [objKey]: "", }; newValue.upstreamArgument = { ...newValue.upstreamArgument, - [_key]: "", + [objKey]: "", }; newValue.upstreamValue = { ...newValue.upstreamValue, - [_key]: "", + [objKey]: "", }; newValue.value = { ...newValue.value, - [_key]: _value, + [objKey]: objValue, }; } auxDefaultValues.push(newValue); diff --git a/frontend/src/features/workflows/api/index.ts b/frontend/src/features/workflows/api/index.ts new file mode 100644 index 00000000..523a1a7c --- /dev/null +++ b/frontend/src/features/workflows/api/index.ts @@ -0,0 +1,4 @@ +export * from "./runs"; +export * from "./workflow"; +export * from "./piece"; +export * from "./repository"; diff --git a/frontend/src/services/requests/piece/getPieceRepositories.request.ts b/frontend/src/features/workflows/api/piece/getPieceRepositories.request.ts similarity index 96% rename from frontend/src/services/requests/piece/getPieceRepositories.request.ts rename to frontend/src/features/workflows/api/piece/getPieceRepositories.request.ts index 0b24ad24..b47d3bdb 100644 --- a/frontend/src/services/requests/piece/getPieceRepositories.request.ts +++ b/frontend/src/features/workflows/api/piece/getPieceRepositories.request.ts @@ -1,9 +1,8 @@ import { type AxiosResponse } from "axios"; import { useWorkspaces } from "context/workspaces"; +import { dominoApiClient } from "services/clients/domino.client"; import useSWR from "swr"; -import { dominoApiClient } from "../../clients/domino.client"; - import { type IGetPiecesRepositoriesResponseInterface } from "./piece.interface"; interface IGetPieceRepositoryFilters { diff --git a/frontend/src/services/requests/piece/getPieceRepositoryPieces.request.ts b/frontend/src/features/workflows/api/piece/getPieceRepositoryPieces.ts similarity index 93% rename from frontend/src/services/requests/piece/getPieceRepositoryPieces.request.ts rename to frontend/src/features/workflows/api/piece/getPieceRepositoryPieces.ts index daadda0f..b5fbefca 100644 --- a/frontend/src/services/requests/piece/getPieceRepositoryPieces.request.ts +++ b/frontend/src/features/workflows/api/piece/getPieceRepositoryPieces.ts @@ -1,7 +1,6 @@ import { type AxiosResponse } from "axios"; import { useCallback } from "react"; - -import { dominoApiClient } from "../../clients/domino.client"; +import { dominoApiClient } from "services/clients/domino.client"; import { type IGetRepoPiecesResponseInterface } from "./piece.interface"; diff --git a/frontend/src/services/requests/piece/getPiecesRepositoriesReleases.request.ts b/frontend/src/features/workflows/api/piece/getPiecesRepositoriesReleases.request.ts similarity index 95% rename from frontend/src/services/requests/piece/getPiecesRepositoriesReleases.request.ts rename to frontend/src/features/workflows/api/piece/getPiecesRepositoriesReleases.request.ts index 878ca7f3..a0b573e3 100644 --- a/frontend/src/services/requests/piece/getPiecesRepositoriesReleases.request.ts +++ b/frontend/src/features/workflows/api/piece/getPiecesRepositoriesReleases.request.ts @@ -1,7 +1,6 @@ import { type AxiosResponse } from "axios"; import { useWorkspaces } from "context/workspaces"; - -import { dominoApiClient } from "../../clients/domino.client"; +import { dominoApiClient } from "services/clients/domino.client"; import { type IGetPiecesRepositoriesReleasesParams, diff --git a/frontend/src/features/workflows/api/piece/index.ts b/frontend/src/features/workflows/api/piece/index.ts new file mode 100644 index 00000000..867aec15 --- /dev/null +++ b/frontend/src/features/workflows/api/piece/index.ts @@ -0,0 +1,4 @@ +export * from "./getPieceRepositories.request"; +export * from "./getPieceRepositoryPieces"; +export * from "./getPiecesRepositoriesReleases.request"; +export * from "./piece.interface"; diff --git a/frontend/src/services/requests/piece/piece.interface.ts b/frontend/src/features/workflows/api/piece/piece.interface.ts similarity index 100% rename from frontend/src/services/requests/piece/piece.interface.ts rename to frontend/src/features/workflows/api/piece/piece.interface.ts diff --git a/frontend/src/services/requests/repository/deletePieceRepository.request.ts b/frontend/src/features/workflows/api/repository/deletePieceRepository.request.ts similarity index 92% rename from frontend/src/services/requests/repository/deletePieceRepository.request.ts rename to frontend/src/features/workflows/api/repository/deletePieceRepository.request.ts index 0ef3a6d0..33bb30d1 100644 --- a/frontend/src/services/requests/repository/deletePieceRepository.request.ts +++ b/frontend/src/features/workflows/api/repository/deletePieceRepository.request.ts @@ -1,8 +1,7 @@ // TODO move to /runs import { type AxiosResponse } from "axios"; import { useWorkspaces } from "context/workspaces"; - -import { dominoApiClient } from "../../clients/domino.client"; +import { dominoApiClient } from "services/clients/domino.client"; const deleteRepositoryUrl = (id: string) => `/pieces-repositories/${id}`; diff --git a/frontend/src/services/requests/repository/getPieceRepositorySecrets.request.ts b/frontend/src/features/workflows/api/repository/getPieceRepositorySecrets.request.ts similarity index 96% rename from frontend/src/services/requests/repository/getPieceRepositorySecrets.request.ts rename to frontend/src/features/workflows/api/repository/getPieceRepositorySecrets.request.ts index 584c2cdc..e85759a5 100644 --- a/frontend/src/services/requests/repository/getPieceRepositorySecrets.request.ts +++ b/frontend/src/features/workflows/api/repository/getPieceRepositorySecrets.request.ts @@ -1,9 +1,8 @@ import { type AxiosResponse } from "axios"; import { useWorkspaces } from "context/workspaces"; +import { dominoApiClient } from "services/clients/domino.client"; import useSWR from "swr"; -import { dominoApiClient } from "../../clients/domino.client"; - import { type IPieceRepositorySecretsData } from "./pieceRepository.interface"; interface IGetRepositorySecretsParams { diff --git a/frontend/src/services/requests/repository/index.ts b/frontend/src/features/workflows/api/repository/index.ts similarity index 100% rename from frontend/src/services/requests/repository/index.ts rename to frontend/src/features/workflows/api/repository/index.ts diff --git a/frontend/src/services/requests/repository/patchPieceRepositorySecret.request.ts b/frontend/src/features/workflows/api/repository/patchPieceRepositorySecret.request.ts similarity index 94% rename from frontend/src/services/requests/repository/patchPieceRepositorySecret.request.ts rename to frontend/src/features/workflows/api/repository/patchPieceRepositorySecret.request.ts index 396b9d95..9c8c452b 100644 --- a/frontend/src/services/requests/repository/patchPieceRepositorySecret.request.ts +++ b/frontend/src/features/workflows/api/repository/patchPieceRepositorySecret.request.ts @@ -1,8 +1,7 @@ // TODO move to /runs import { type AxiosResponse } from "axios"; import { useWorkspaces } from "context/workspaces"; - -import { dominoApiClient } from "../../clients/domino.client"; +import { dominoApiClient } from "services/clients/domino.client"; interface PatchRepositorySecretParams { repositoryId: string; diff --git a/frontend/src/services/requests/repository/pieceRepository.interface.ts b/frontend/src/features/workflows/api/repository/pieceRepository.interface.ts similarity index 100% rename from frontend/src/services/requests/repository/pieceRepository.interface.ts rename to frontend/src/features/workflows/api/repository/pieceRepository.interface.ts diff --git a/frontend/src/services/requests/runs/getWorkflowRunTaskLogs.request.ts b/frontend/src/features/workflows/api/runs/getWorkflowRunTaskLogs.ts similarity index 90% rename from frontend/src/services/requests/runs/getWorkflowRunTaskLogs.request.ts rename to frontend/src/features/workflows/api/runs/getWorkflowRunTaskLogs.ts index 3e1650dd..d8edcf3a 100644 --- a/frontend/src/services/requests/runs/getWorkflowRunTaskLogs.request.ts +++ b/frontend/src/features/workflows/api/runs/getWorkflowRunTaskLogs.ts @@ -1,9 +1,7 @@ import { type AxiosResponse } from "axios"; import { useWorkspaces } from "context/workspaces"; - -import { dominoApiClient } from "../../clients/domino.client"; - -import { type IGetWorkflowRunTasksResponseInterface } from "./runs.interface"; +import { type IGetWorkflowRunTasksResponseInterface } from "features/workflows/types/runs"; +import { dominoApiClient } from "services/clients/domino.client"; export interface IGetWorkflowRunTaskLogsParams { workflowId: string; diff --git a/frontend/src/services/requests/runs/getWorkflowRunTaskResult.request.ts b/frontend/src/features/workflows/api/runs/getWorkflowRunTaskResult.ts similarity index 90% rename from frontend/src/services/requests/runs/getWorkflowRunTaskResult.request.ts rename to frontend/src/features/workflows/api/runs/getWorkflowRunTaskResult.ts index c3ff0659..d099edef 100644 --- a/frontend/src/services/requests/runs/getWorkflowRunTaskResult.request.ts +++ b/frontend/src/features/workflows/api/runs/getWorkflowRunTaskResult.ts @@ -1,9 +1,7 @@ import { type AxiosResponse } from "axios"; import { useWorkspaces } from "context/workspaces"; - -import { dominoApiClient } from "../../clients/domino.client"; - -import { type IGetWorkflowRunTasksResponseInterface } from "./runs.interface"; +import { type IGetWorkflowRunTasksResponseInterface } from "features/workflows/types/runs"; +import { dominoApiClient } from "services/clients/domino.client"; export interface IGetWorkflowRunTaskResultParams { workflowId: string; diff --git a/frontend/src/services/requests/runs/getWorkflowRunTasks.request.ts b/frontend/src/features/workflows/api/runs/getWorkflowRunTasks.ts similarity index 90% rename from frontend/src/services/requests/runs/getWorkflowRunTasks.request.ts rename to frontend/src/features/workflows/api/runs/getWorkflowRunTasks.ts index 6f90a9bd..63d82f19 100644 --- a/frontend/src/services/requests/runs/getWorkflowRunTasks.request.ts +++ b/frontend/src/features/workflows/api/runs/getWorkflowRunTasks.ts @@ -1,9 +1,7 @@ import { type AxiosResponse } from "axios"; import { useWorkspaces } from "context/workspaces"; - -import { dominoApiClient } from "../../clients/domino.client"; - -import { type IGetWorkflowRunTasksResponseInterface } from "./runs.interface"; +import { type IGetWorkflowRunTasksResponseInterface } from "features/workflows/types/runs"; +import { dominoApiClient } from "services/clients/domino.client"; export interface IGetWorkflowRunTasksParams { workflowId: string; diff --git a/frontend/src/services/requests/runs/getWorkflowRuns.request.ts b/frontend/src/features/workflows/api/runs/getWorkflowRuns.ts similarity index 92% rename from frontend/src/services/requests/runs/getWorkflowRuns.request.ts rename to frontend/src/features/workflows/api/runs/getWorkflowRuns.ts index cd60e6b1..c20e0c8a 100644 --- a/frontend/src/services/requests/runs/getWorkflowRuns.request.ts +++ b/frontend/src/features/workflows/api/runs/getWorkflowRuns.ts @@ -1,11 +1,9 @@ import { type AxiosResponse } from "axios"; import { useWorkspaces } from "context/workspaces"; +import { type IGetWorkflowRunsResponseInterface } from "features/workflows/types/runs"; +import { dominoApiClient } from "services/clients/domino.client"; import useSWR from "swr"; -import { dominoApiClient } from "../../clients/domino.client"; - -import { type IGetWorkflowRunsResponseInterface } from "./runs.interface"; - interface IGetWorkflowRunParams { workflowId: string; page: number; diff --git a/frontend/src/features/workflows/api/runs/index.ts b/frontend/src/features/workflows/api/runs/index.ts new file mode 100644 index 00000000..bc215ffa --- /dev/null +++ b/frontend/src/features/workflows/api/runs/index.ts @@ -0,0 +1,4 @@ +export * from "./getWorkflowRuns"; +export * from "./getWorkflowRunTasks"; +export * from "./getWorkflowRunTaskLogs"; +export * from "./getWorkflowRunTaskResult"; diff --git a/frontend/src/services/requests/workflow/deleteWorkflowId.request.ts b/frontend/src/features/workflows/api/workflow/deleteWorkflowId.ts similarity index 85% rename from frontend/src/services/requests/workflow/deleteWorkflowId.request.ts rename to frontend/src/features/workflows/api/workflow/deleteWorkflowId.ts index 24633fec..01da75dc 100644 --- a/frontend/src/services/requests/workflow/deleteWorkflowId.request.ts +++ b/frontend/src/features/workflows/api/workflow/deleteWorkflowId.ts @@ -1,9 +1,7 @@ import { type AxiosResponse } from "axios"; import { useWorkspaces } from "context/workspaces"; - -import { dominoApiClient } from "../../clients/domino.client"; - -import { type IDeleteWorkflowIdResponseInterface } from "./workflow.interface"; +import { type IDeleteWorkflowIdResponseInterface } from "features/workflows/types/workflow"; +import { dominoApiClient } from "services/clients/domino.client"; interface IDeleteWorkflowIdParams { id: string; diff --git a/frontend/src/services/requests/workflow/getWorkflow.request.ts b/frontend/src/features/workflows/api/workflow/getWorkflow.ts similarity index 89% rename from frontend/src/services/requests/workflow/getWorkflow.request.ts rename to frontend/src/features/workflows/api/workflow/getWorkflow.ts index 59574f11..15af1751 100644 --- a/frontend/src/services/requests/workflow/getWorkflow.request.ts +++ b/frontend/src/features/workflows/api/workflow/getWorkflow.ts @@ -1,11 +1,9 @@ import { type AxiosResponse } from "axios"; import { useWorkspaces } from "context/workspaces"; +import { type IGetWorkflowResponseInterface } from "features/workflows/types/workflow"; +import { dominoApiClient } from "services/clients/domino.client"; import useSWR from "swr"; -import { dominoApiClient } from "../../clients/domino.client"; - -import { type IGetWorkflowResponseInterface } from "./workflow.interface"; - const getWorkflowsUrl = (workspace: string, page: number, pageSize: number) => `/workspaces/${workspace}/workflows?page=${page}&page_size=${pageSize}`; diff --git a/frontend/src/services/requests/workflow/getWorkflowId.request.ts b/frontend/src/features/workflows/api/workflow/getWorkflowId.ts similarity index 87% rename from frontend/src/services/requests/workflow/getWorkflowId.request.ts rename to frontend/src/features/workflows/api/workflow/getWorkflowId.ts index 6ed2d9f7..ce10f77c 100644 --- a/frontend/src/services/requests/workflow/getWorkflowId.request.ts +++ b/frontend/src/features/workflows/api/workflow/getWorkflowId.ts @@ -1,9 +1,7 @@ import { type AxiosResponse } from "axios"; import { useWorkspaces } from "context/workspaces"; - -import { dominoApiClient } from "../../clients/domino.client"; - -import { type IGetWorkflowIdResponseInterface } from "./workflow.interface"; +import { type IGetWorkflowIdResponseInterface } from "features/workflows/types/workflow"; +import { dominoApiClient } from "services/clients/domino.client"; interface IGetWorkflowIdParams { id: string; diff --git a/frontend/src/features/workflows/api/workflow/index.ts b/frontend/src/features/workflows/api/workflow/index.ts new file mode 100644 index 00000000..7164b493 --- /dev/null +++ b/frontend/src/features/workflows/api/workflow/index.ts @@ -0,0 +1,5 @@ +export * from "./deleteWorkflowId"; +export * from "./getWorkflowId"; +export * from "./getWorkflow"; +export * from "./postWorkflowRunId"; +export * from "./postWorkflow"; diff --git a/frontend/src/services/requests/workflow/postWorkflow.request.ts b/frontend/src/features/workflows/api/workflow/postWorkflow.ts similarity index 77% rename from frontend/src/services/requests/workflow/postWorkflow.request.ts rename to frontend/src/features/workflows/api/workflow/postWorkflow.ts index effdc4da..8be5ac62 100644 --- a/frontend/src/services/requests/workflow/postWorkflow.request.ts +++ b/frontend/src/features/workflows/api/workflow/postWorkflow.ts @@ -1,9 +1,7 @@ import { type AxiosResponse } from "axios"; -import { type CreateWorkflowRequest } from "context/workflows/types"; - -import { dominoApiClient } from "../../clients/domino.client"; - -import { type IPostWorkflowResponseInterface } from "./workflow.interface"; +import { type CreateWorkflowRequest } from "features/workflowEditor/context/types"; +import { type IPostWorkflowResponseInterface } from "features/workflows/types"; +import { dominoApiClient } from "services/clients/domino.client"; export interface IPostWorkflowParams extends CreateWorkflowRequest { workspace_id: string; diff --git a/frontend/src/services/requests/workflow/postWorkflowRunId.request.ts b/frontend/src/features/workflows/api/workflow/postWorkflowRunId.ts similarity index 87% rename from frontend/src/services/requests/workflow/postWorkflowRunId.request.ts rename to frontend/src/features/workflows/api/workflow/postWorkflowRunId.ts index 16e8492d..c153a29b 100644 --- a/frontend/src/services/requests/workflow/postWorkflowRunId.request.ts +++ b/frontend/src/features/workflows/api/workflow/postWorkflowRunId.ts @@ -1,10 +1,8 @@ // TODO move to /runs import { type AxiosResponse } from "axios"; import { useWorkspaces } from "context/workspaces"; - -import { dominoApiClient } from "../../clients/domino.client"; - -import { type IPostWorkflowRunIdResponseInterface } from "./workflow.interface"; +import { type IPostWorkflowRunIdResponseInterface } from "features/workflows/types/workflow"; +import { dominoApiClient } from "services/clients/domino.client"; interface IPostWorkflowRunIdParams { id: string; diff --git a/frontend/src/features/workflows/components/WorkflowsRunTasksFlowchart/WorkflowTaskDetails.tsx b/frontend/src/features/workflows/components/WorkflowsRunTasksFlowchart/WorkflowTaskDetails.tsx index 0fdd400c..6e8f01b4 100644 --- a/frontend/src/features/workflows/components/WorkflowsRunTasksFlowchart/WorkflowTaskDetails.tsx +++ b/frontend/src/features/workflows/components/WorkflowsRunTasksFlowchart/WorkflowTaskDetails.tsx @@ -1,9 +1,8 @@ import CalendarMonthIcon from "@mui/icons-material/CalendarMonth"; import TimelapseIcon from "@mui/icons-material/Timelapse"; import { Grid, List, ListItem, Chip, Typography } from "@mui/material"; -import { type IWorkflowRunTasks } from "services/requests/runs"; - -import { taskStatesColorMap } from "../../constants"; +import { taskStatesColorMap } from "features/workflows/constants"; +import { type IWorkflowRunTasks } from "features/workflows/types/runs"; interface IWorkflowRunTasksExtended extends IWorkflowRunTasks { pieceName: string; diff --git a/frontend/src/features/workflows/components/WorkflowsRunTasksFlowchart/index.tsx b/frontend/src/features/workflows/components/WorkflowsRunTasksFlowchart/index.tsx index 1ae561c4..f74856d8 100644 --- a/frontend/src/features/workflows/components/WorkflowsRunTasksFlowchart/index.tsx +++ b/frontend/src/features/workflows/components/WorkflowsRunTasksFlowchart/index.tsx @@ -1,13 +1,12 @@ import { Button, Card, Grid, ButtonGroup, CardContent } from "@mui/material"; import CustomNode from "components/CustomNode"; +import { taskStatesColorMap } from "features/workflows/constants"; +import { useWorkflows } from "features/workflows/context/workflows"; import { useCallback, useRef, useState, useEffect } from "react"; import { toast } from "react-toastify"; import ReactFlow, { Background, Controls, ReactFlowProvider } from "reactflow"; import "reactflow/dist/style.css"; -import { taskStatesColorMap } from "../../constants"; -import { useWorkflows } from "../../context/workflows"; - import { TaskDetails } from "./WorkflowTaskDetails"; import { TaskLogs } from "./WorkflowTaskLogs"; import { TaskResult } from "./WorkflowTaskResult"; @@ -102,7 +101,7 @@ export const WorkflowRunTaskFlowchart = () => { }; const color = - task.state in taskStatesColorMap + (task.state as string) in taskStatesColorMap ? taskStatesColorMap[task.state] : taskStatesColorMap.default; node.data.style.nodeStyle.backgroundColor = color; @@ -127,7 +126,8 @@ export const WorkflowRunTaskFlowchart = () => { void fetchTasks(); const interval = setInterval(() => { const workflowRun = workflowRuns?.data?.find( - (run) => run.workflow_run_id === selectedWorkflowRunId, + (run: { workflow_run_id: string }) => + run.workflow_run_id === selectedWorkflowRunId, ); // Fetch all tasks data fetchTasks() diff --git a/frontend/src/features/workflows/components/WorkflowsRunsTable/index.tsx b/frontend/src/features/workflows/components/WorkflowsRunsTable/index.tsx index 37478d08..e7aef456 100644 --- a/frontend/src/features/workflows/components/WorkflowsRunsTable/index.tsx +++ b/frontend/src/features/workflows/components/WorkflowsRunsTable/index.tsx @@ -6,10 +6,9 @@ import { type GridRowId, GridActionsCellItem, } from "@mui/x-data-grid"; +import { useWorkflows } from "features/workflows/context/workflows"; import { useMemo, useCallback, useState, useEffect } from "react"; -import { useWorkflows } from "../../context/workflows"; - export const WorkflowsRunsTable = () => { const [selectionModel, setSelectionModel] = useState([]); const updateTime = 5000; // ms diff --git a/frontend/src/features/workflows/components/WorkflowsTable/index.tsx b/frontend/src/features/workflows/components/WorkflowsTable/index.tsx index d24d9755..4c6c2ba9 100644 --- a/frontend/src/features/workflows/components/WorkflowsTable/index.tsx +++ b/frontend/src/features/workflows/components/WorkflowsTable/index.tsx @@ -23,19 +23,10 @@ import { GridActionsCellItem, type GridRowId, } from "@mui/x-data-grid"; +import { useWorkflows } from "features/workflows/context/workflows"; import { useCallback, useEffect, useMemo, useState } from "react"; import { toast } from "react-toastify"; -import { useWorkflows } from "../../context/workflows"; - -// import { toast } from "react-toastify"; - -// import DeleteOutlineIcon from '@mui/icons-material/DeleteOutline'; -// import PlayCircleOutlineIcon from '@mui/icons-material/PlayCircleOutline'; -// import ZoomInIcon from '@mui/icons-material/ZoomIn'; - -// import { AgGridColumn, AgGridReact } from 'ag-grid-react'; - export const WorkflowsTable = () => { const { workflows, @@ -324,17 +315,27 @@ export const WorkflowsTable = () => { const { rowsData, totalRows } = useMemo(() => { const rowsData = Array.isArray(workflows.data) - ? workflows.data.map((workflow) => { - return { - id: workflow.id, - name: workflow.name, - createdAt: workflow.created_at, - lastModified: workflow.last_changed_at, - scheduleInterval: workflow.schedule_interval, - status: workflow.status, - paused: workflow.is_paused, - }; - }) + ? workflows.data.map( + (workflow: { + id: any; + name: any; + created_at: any; + last_changed_at: any; + schedule_interval: any; + status: any; + is_paused: any; + }) => { + return { + id: workflow.id, + name: workflow.name, + createdAt: workflow.created_at, + lastModified: workflow.last_changed_at, + scheduleInterval: workflow.schedule_interval, + status: workflow.status, + paused: workflow.is_paused, + }; + }, + ) : []; const totalRows = workflows.metadata?.total ?? 0; return { rowsData, totalRows }; diff --git a/frontend/src/features/workflows/context/index.ts b/frontend/src/features/workflows/context/index.ts new file mode 100644 index 00000000..8a3498d4 --- /dev/null +++ b/frontend/src/features/workflows/context/index.ts @@ -0,0 +1 @@ +export * from "./workflows"; diff --git a/frontend/src/features/workflows/context/workflows/index.tsx b/frontend/src/features/workflows/context/workflows.tsx similarity index 99% rename from frontend/src/features/workflows/context/workflows/index.tsx rename to frontend/src/features/workflows/context/workflows.tsx index 51a58d66..c385b177 100644 --- a/frontend/src/features/workflows/context/workflows/index.tsx +++ b/frontend/src/features/workflows/context/workflows.tsx @@ -1,21 +1,21 @@ -import { type FC, useCallback, useEffect, useMemo, useState } from "react"; -import { toast } from "react-toastify"; import { useAuthenticatedGetWorkflowRuns, - type IGetWorkflowRunsResponseInterface, useAuthenticatedGetWorkflowRunTasks, useAuthenticatedGetWorkflowRunTaskLogs, useAuthenticatedGetWorkflowRunTaskResult, - type IGetWorkflowRunTasksResponseInterface, -} from "services/requests/runs"; -import { - type IWorkflow, - type IGetWorkflowResponseInterface, useAuthenticatedDeleteWorkflowId, useAuthenticatedGetWorkflows, useAuthenticatedPostWorkflowRunId, useAuthenticatedGetWorkflowId, -} from "services/requests/workflow"; +} from "features/workflows/api"; +import { + type IWorkflow, + type IGetWorkflowResponseInterface, + type IGetWorkflowRunsResponseInterface, + type IGetWorkflowRunTasksResponseInterface, +} from "features/workflows/types"; +import { type FC, useCallback, useEffect, useMemo, useState } from "react"; +import { toast } from "react-toastify"; import { createCustomContext } from "utils"; interface IWorkflowsContext { diff --git a/frontend/src/features/workflows/index.ts b/frontend/src/features/workflows/index.ts new file mode 100644 index 00000000..9ad241fc --- /dev/null +++ b/frontend/src/features/workflows/index.ts @@ -0,0 +1,3 @@ +export * from "./api"; +export * from "./pages"; +export * from "./context"; diff --git a/frontend/src/features/workflows/types/index.ts b/frontend/src/features/workflows/types/index.ts new file mode 100644 index 00000000..600608dc --- /dev/null +++ b/frontend/src/features/workflows/types/index.ts @@ -0,0 +1,2 @@ +export * from "./runs"; +export * from "./workflow"; diff --git a/frontend/src/services/requests/runs/runs.interface.ts b/frontend/src/features/workflows/types/runs.ts similarity index 100% rename from frontend/src/services/requests/runs/runs.interface.ts rename to frontend/src/features/workflows/types/runs.ts diff --git a/frontend/src/services/requests/workflow/workflow.interface.ts b/frontend/src/features/workflows/types/workflow.ts similarity index 100% rename from frontend/src/services/requests/workflow/workflow.interface.ts rename to frontend/src/features/workflows/types/workflow.ts diff --git a/frontend/src/features/workspaces/components/workspaceSettings/RepositoriesCard.tsx b/frontend/src/features/workspaces/components/workspaceSettings/RepositoriesCard.tsx index 75b0063a..a681e143 100644 --- a/frontend/src/features/workspaces/components/workspaceSettings/RepositoriesCard.tsx +++ b/frontend/src/features/workspaces/components/workspaceSettings/RepositoriesCard.tsx @@ -28,10 +28,10 @@ import { Tooltip, } from "@mui/material"; import TextField from "@mui/material/TextField"; +import { type IPieceRepositoryMetadata } from "features/workflows/api"; import { ERepositorySource } from "interfaces/repositorySource.enum"; import { type FC, type ReactNode, useCallback, useMemo, useState } from "react"; import { toast } from "react-toastify"; -import { type IPieceRepositoryMetadata } from "services/requests/piece"; import { useWorkspaceSettings } from "../../context/workspaceSettings"; diff --git a/frontend/src/features/workspaces/components/workspaceSettings/SecretsCard.tsx b/frontend/src/features/workspaces/components/workspaceSettings/SecretsCard.tsx index 59cf59f2..54507e64 100644 --- a/frontend/src/features/workspaces/components/workspaceSettings/SecretsCard.tsx +++ b/frontend/src/features/workspaces/components/workspaceSettings/SecretsCard.tsx @@ -14,6 +14,10 @@ import { IconButton, Tooltip, } from "@mui/material"; +import { + useAuthenticatedGetRepositorySecrets, + useAuthenticatedPatchRepositorySecret, +} from "features/workflows/api"; import { useState, useImperativeHandle, @@ -24,10 +28,6 @@ import { } from "react"; import { useForm } from "react-hook-form"; import { toast } from "react-toastify"; -import { - useAuthenticatedGetRepositorySecrets, - useAuthenticatedPatchRepositorySecret, -} from "services/requests/repository"; interface SecretsCardProps { repositoryId: number | null; diff --git a/frontend/src/features/workspaces/components/workspaceSettings/StorageSecretsCard.tsx b/frontend/src/features/workspaces/components/workspaceSettings/StorageSecretsCard.tsx index 2aa8d6e5..e485cbe5 100644 --- a/frontend/src/features/workspaces/components/workspaceSettings/StorageSecretsCard.tsx +++ b/frontend/src/features/workspaces/components/workspaceSettings/StorageSecretsCard.tsx @@ -15,13 +15,13 @@ import { IconButton, Alert, } from "@mui/material"; -import { useState, useCallback, useMemo, useEffect } from "react"; -import { useForm } from "react-hook-form"; -import { toast } from "react-toastify"; import { useAuthenticatedGetRepositorySecrets, useAuthenticatedPatchRepositorySecret, -} from "services/requests/repository"; +} from "features/workflows/api"; +import { useState, useCallback, useMemo, useEffect } from "react"; +import { useForm } from "react-hook-form"; +import { toast } from "react-toastify"; import { useWorkspaceSettings } from "../../context/workspaceSettings"; diff --git a/frontend/src/features/workspaces/components/workspaceSettings/WorkspaceSecretsCard.tsx b/frontend/src/features/workspaces/components/workspaceSettings/WorkspaceSecretsCard.tsx index bef9251e..3bbf0fed 100644 --- a/frontend/src/features/workspaces/components/workspaceSettings/WorkspaceSecretsCard.tsx +++ b/frontend/src/features/workspaces/components/workspaceSettings/WorkspaceSecretsCard.tsx @@ -15,10 +15,10 @@ import { IconButton, } from "@mui/material"; import { useWorkspaces } from "context/workspaces"; +import { useAuthenticatedPatchWorkspace } from "context/workspaces/api"; import { useState, useCallback, useEffect } from "react"; import { useForm } from "react-hook-form"; import { toast } from "react-toastify"; -import { useAuthenticatedPatchWorkspace } from "services/requests/workspaces"; import { useWorkspaceSettings } from "../../context/workspaceSettings"; diff --git a/frontend/src/features/workspaces/components/workspaces/WorkspaceListItem.tsx b/frontend/src/features/workspaces/components/workspaces/WorkspaceListItem.tsx index c130a24f..a1e040b8 100644 --- a/frontend/src/features/workspaces/components/workspaces/WorkspaceListItem.tsx +++ b/frontend/src/features/workspaces/components/workspaces/WorkspaceListItem.tsx @@ -8,9 +8,9 @@ import { Button, Grid, } from "@mui/material"; +import { type IWorkspaceSummary } from "context/workspaces/types"; import { type FC } from "react"; import { useNavigate } from "react-router-dom"; -import { type IWorkspaceSummary } from "services/requests/workspaces"; export const WorkspaceListItem: FC<{ workspace: IWorkspaceSummary; diff --git a/frontend/src/features/workspaces/components/workspaces/WorkspacePendingListItem.tsx b/frontend/src/features/workspaces/components/workspaces/WorkspacePendingListItem.tsx index d7d84d40..9ae98b5b 100644 --- a/frontend/src/features/workspaces/components/workspaces/WorkspacePendingListItem.tsx +++ b/frontend/src/features/workspaces/components/workspaces/WorkspacePendingListItem.tsx @@ -9,8 +9,8 @@ import { Grid, } from "@mui/material"; import { useWorkspaces } from "context/workspaces"; +import { type IWorkspaceSummary } from "context/workspaces/types"; import { type FC } from "react"; -import { type IWorkspaceSummary } from "services/requests/workspaces"; export const WorkspacePendingListItem: FC<{ workspace: IWorkspaceSummary; diff --git a/frontend/src/features/workspaces/context/workspaceSettings.tsx b/frontend/src/features/workspaces/context/workspaceSettings.tsx index d0235c5a..ed6dd756 100644 --- a/frontend/src/features/workspaces/context/workspaceSettings.tsx +++ b/frontend/src/features/workspaces/context/workspaceSettings.tsx @@ -1,20 +1,22 @@ import { useWorkspaces } from "context/workspaces"; -import { type FC, useCallback, useState } from "react"; -import { toast } from "react-toastify"; import { - type IGetPiecesRepositoriesReleasesParams, - type IGetPiecesRepositoriesReleasesResponseInterface, - useAuthenticatedGetPieceRepositories, -} from "services/requests/piece"; -import { useAuthenticatedGetPieceRepositoriesReleases } from "services/requests/piece/getPiecesRepositoriesReleases.request"; -import { useAuthenticatedDeleteRepository } from "services/requests/repository"; + useAuthenticatedGetWorkspace, + useAuthenticatedPostPiecesRepository, +} from "context/workspaces/api"; import { type IPostWorkspaceRepositoryPayload, type IPostWorkspaceRepositoryResponseInterface, type IWorkspaceSummary, - useAuthenticatedGetWorkspace, - useAuthenticatedPostPiecesRepository, -} from "services/requests/workspaces"; +} from "context/workspaces/types"; +import { + type IGetPiecesRepositoriesReleasesParams, + type IGetPiecesRepositoriesReleasesResponseInterface, + useAuthenticatedDeleteRepository, + useAuthenticatedGetPieceRepositories, + useAuthenticatedGetPieceRepositoriesReleases, +} from "features/workflows/api"; +import { type FC, useCallback, useState } from "react"; +import { toast } from "react-toastify"; import { createCustomContext } from "utils"; interface IWorkspaceSettingsContext { diff --git a/frontend/src/routes/index.tsx b/frontend/src/routes/index.tsx index 4f74b340..4bbce5d4 100644 --- a/frontend/src/routes/index.tsx +++ b/frontend/src/routes/index.tsx @@ -1,17 +1,32 @@ -import SignInPage from "features/auth/pages/signIn/signInPage"; -import SignUpPage from "features/auth/pages/signUp/signUpPage"; -import { WorkflowsEditorPage } from "features/workflowEditor/pages"; -import { WorkflowsPage } from "features/workflows/pages"; +import { CircularProgress } from "@mui/material"; import { WorkspaceSettingsPage, WorkspacesPage, } from "features/workspaces/pages"; -import { type FC } from "react"; +import { Suspense, type FC } from "react"; import { Navigate, Route, Routes } from "react-router-dom"; +import { lazyImport } from "utils"; import { PrivateRoute } from "./privateRoute"; import { PublicRoute } from "./publicRoute"; +const { SignInPage } = lazyImport( + async () => await import("features/auth/pages/signIn/signInPage"), + "SignInPage", +); +const { SignUpPage } = lazyImport( + async () => await import("features/auth/pages/signUp/signUpPage"), + "SignUpPage", +); +const { WorkflowsEditorPage } = lazyImport( + async () => await import("features/workflowEditor/pages"), + "WorkflowsEditorPage", +); +const { WorkflowsPage } = lazyImport( + async () => await import("features/workflows/pages"), + "WorkflowsPage", +); + /** * Application router * @todo implement recover password pages @@ -20,61 +35,69 @@ import { PublicRoute } from "./publicRoute"; * @returns app router component */ export const ApplicationRoutes: FC = () => ( - - } /> + + +
+ } + > + + } /> - } - /> + } + /> - } - /> + } + /> - {/** @todo implement page */} -

Recover password

} /> - } - /> + {/** @todo implement page */} +

Recover password

} /> + } + /> - } - /> + } + /> - - } - /> + + } + /> - } - /> + } + /> - - } - /> + + } + /> - {/** @todo implement page */} -

404 not found

} /> - } - /> + {/** @todo implement page */} +

404 not found

} /> + } + /> - } /> -
+ } /> + + ); export default ApplicationRoutes; diff --git a/frontend/src/services/clients/domino.mock.ts b/frontend/src/services/clients/domino.mock.ts index eae46a11..1e9e2922 100644 --- a/frontend/src/services/clients/domino.mock.ts +++ b/frontend/src/services/clients/domino.mock.ts @@ -1,9 +1,8 @@ import MockAdapter from "axios-mock-adapter"; - import { postAuthLoginMockResponse, postAuthRegisterMockResponse, -} from "../requests/authentication"; +} from "context/authentication/api"; import { dominoApiClient } from "./domino.client"; diff --git a/frontend/src/services/requests/authentication/index.ts b/frontend/src/services/requests/authentication/index.ts deleted file mode 100644 index 747c6f43..00000000 --- a/frontend/src/services/requests/authentication/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from "./postAuthLogin.request"; -export * from "./postAuthRegister.request"; diff --git a/frontend/src/services/requests/piece/index.ts b/frontend/src/services/requests/piece/index.ts deleted file mode 100644 index 02e4af24..00000000 --- a/frontend/src/services/requests/piece/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from "./getPieceRepositories.request"; -export * from "./piece.interface"; diff --git a/frontend/src/services/requests/runs/index.ts b/frontend/src/services/requests/runs/index.ts deleted file mode 100644 index 1c75263c..00000000 --- a/frontend/src/services/requests/runs/index.ts +++ /dev/null @@ -1,5 +0,0 @@ -export * from "./getWorkflowRuns.request"; -export * from "./getWorkflowRunTasks.request"; -export * from "./getWorkflowRunTaskLogs.request"; -export * from "./getWorkflowRunTaskResult.request"; -export * from "./runs.interface"; diff --git a/frontend/src/services/requests/workflow/index.ts b/frontend/src/services/requests/workflow/index.ts deleted file mode 100644 index 8668023f..00000000 --- a/frontend/src/services/requests/workflow/index.ts +++ /dev/null @@ -1,6 +0,0 @@ -export * from "./deleteWorkflowId.request"; -export * from "./getWorkflowId.request"; -export * from "./getWorkflow.request"; -export * from "./postWorkflowRunId.request"; -export * from "./postWorkflow.request"; -export * from "./workflow.interface"; diff --git a/frontend/src/services/requests/workspaces/index.ts b/frontend/src/services/requests/workspaces/index.ts deleted file mode 100644 index 363eeffb..00000000 --- a/frontend/src/services/requests/workspaces/index.ts +++ /dev/null @@ -1,12 +0,0 @@ -export * from "./getWorkspaceId.request"; -export * from "./getWorkspaces.request"; -export * from "./postPiecesRepositories.request"; -export * from "./postWorkspaces.request"; -export * from "./deleteWorkspace.request"; -export * from "./workspaces.interface"; -export * from "./patchWorkspace.reques"; -export * from "./acceptWorkspaceInvite.request"; -export * from "./rejectWorkspaceInvite.request"; -export * from "./inviteWorkspace.request"; -export * from "./deleteUserWorkspace.request"; -export * from "./getWorkspaceMembers.request"; diff --git a/frontend/src/utils/fetchFromObject.ts b/frontend/src/utils/fetchFromObject.ts index d2471434..b3ed6533 100644 --- a/frontend/src/utils/fetchFromObject.ts +++ b/frontend/src/utils/fetchFromObject.ts @@ -3,11 +3,11 @@ export function fetchFromObject(obj: any, prop: string): any { return; } - const _index = prop.indexOf("."); - if (_index > -1) { - const newObj = obj[prop.substring(0, _index)]; + const index = prop.indexOf("."); + if (index > -1) { + const newObj = obj[prop.substring(0, index)]; - return fetchFromObject(newObj, prop.substr(_index + 1)); + return fetchFromObject(newObj, prop.substr(index + 1)); } return obj[prop]; diff --git a/frontend/src/utils/index.ts b/frontend/src/utils/index.ts index 1d0a4e0a..96b2fb48 100644 --- a/frontend/src/utils/index.ts +++ b/frontend/src/utils/index.ts @@ -1,9 +1,7 @@ -export { extractDefaultValues, extractDefaultInputValues } from "./jsonSchema"; export { createCustomContext } from "./createCustomContext.function"; export { fetchFromObject } from "./fetchFromObject"; export { yupResolver } from "./validationResolver"; export { getIdSlice, getUuidSlice, getUuid } from "./getUuidSlice"; export { generateTaskName } from "./generateTaskName"; export { getDefinition } from "./getDefinition"; -export { getFromUpstream } from "./getFromUpstream"; export { lazyImport } from "./lazyImports"; From c1de36a6e22237d5a6da0875fb8b3e8907012f7f Mon Sep 17 00:00:00 2001 From: Nathan Vieira Marcelino Date: Fri, 8 Sep 2023 12:03:31 -0300 Subject: [PATCH 229/328] docs: frontend project structure doc --- frontend/README.md | 37 +++++++++++++- frontend/docs/project-structure.md | 79 ++++++++++++++++++++++++++++++ 2 files changed, 114 insertions(+), 2 deletions(-) create mode 100644 frontend/docs/project-structure.md diff --git a/frontend/README.md b/frontend/README.md index 527c12ff..bdb60f30 100644 --- a/frontend/README.md +++ b/frontend/README.md @@ -1,8 +1,41 @@ # Domino Frontend +# A GUI for creating workflows. +### Recommended -A GUI for creating workflows. +This config allow you to ensure code style every time you save a file in frontend folder, +alternatively you can just run the command `yarn lint:fix` +- [ESlint extension](https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint) + - Add to settings.json ([Ctrl + Shift + P] to open 'Open Settings (JSON)') + ```json + { + ... + "editor.codeActionsOnSave": { + "source.fixAll.eslint": true, + "source.fixAll.prettier": true + }, + "eslint.validate": [ + "javascript", + "typescript", + "javascriptreact", + "typescriptreact" + ] + ... + } + ``` + +### How to Run + +#### Install dependencies + +```bash +yarn install +``` + +#### Run the application Running Domino frontend locally: ```bash yarn start -``` \ No newline at end of file +``` + +### [Project Structure](./docs/project-structure.md) diff --git a/frontend/docs/project-structure.md b/frontend/docs/project-structure.md new file mode 100644 index 00000000..2e7fbcf5 --- /dev/null +++ b/frontend/docs/project-structure.md @@ -0,0 +1,79 @@ +# 🗄️ Project Structure + +Most of the code lives in the `src` folder and looks like this: + +```sh +src +| ++-- @types # base types used across the application +| ++-- components # shared components used across the entire application +| ++-- config # all the global configuration, env variables etc. get exported from here and used in the app +| ++-- context # shared context used across the entire application +| ++-- features # feature based modules +| ++-- providers # all of the application providers +| ++-- routes # routes configuration +| ++-- services # re-exporting different libraries preconfigured for the application +| ++-- test # test utilities and mock server +| ++-- utils # shared utility functions +``` + +In order to scale the application in the easiest and most maintainable way, keep most of the code inside the `features` folder, which should contain different feature-based things. Every `feature` folder should contain domain specific code for a given feature. This will allow you to keep functionalities scoped to a feature and not mix its declarations with shared things. This is much easier to maintain than a flat folder structure with many files. + +A feature could have the following structure: + +```sh +src/features/awesome-feature +| ++-- api # exported API request declarations and api hooks related to a specific feature +| ++-- assets # assets folder can contain all the static files for a specific feature +| ++-- components # components scoped to a specific feature +| ++-- context # context scoped to a specific feature +| ++-- pages # route components for a specific feature pages +| ++-- types # typescript types for TS specific feature domain +| ++-- utils # utility functions for a specific feature +| ++-- index.ts # entry point for the feature, it should serve as the public API of the given feature and exports everything that should be used outside the feature +``` + +Everything from a feature should be exported from the `index.ts` file which behaves as the public API of the feature. + +You should import stuff from other features only by using: + +`import {AwesomeComponent} from "features/awesome-feature"` + +and not + +`import {AwesomeComponent} from "features/awesome-feature/components/AwesomeComponent` + +This can also be configured in the ESLint configuration to disallow the later import by the following rule: + +```js +{ + rules: { + 'no-restricted-imports': [ + 'error', + { + patterns: ['features/*/*'], + }, + ], + + // ...rest of the configuration +} +``` + +This was inspired by how [NX](https://nx.dev/) handles libraries that are isolated but available to be used by the other modules. Think of a feature as a library or a module that is self-contained but can expose different parts to other features via its entry point. From 2a2c28727debde1e7045285e1cb70a39cf0e64dc Mon Sep 17 00:00:00 2001 From: Nathan Vieira Marcelino Date: Fri, 8 Sep 2023 15:02:33 -0300 Subject: [PATCH 230/328] feat: improve lazy imports loading --- frontend/src/components/Loading/index.tsx | 19 +++++++++++++++++++ frontend/src/routes/index.tsx | 5 ++--- 2 files changed, 21 insertions(+), 3 deletions(-) create mode 100644 frontend/src/components/Loading/index.tsx diff --git a/frontend/src/components/Loading/index.tsx b/frontend/src/components/Loading/index.tsx new file mode 100644 index 00000000..4a53dc57 --- /dev/null +++ b/frontend/src/components/Loading/index.tsx @@ -0,0 +1,19 @@ +import Backdrop from "@mui/material/Backdrop"; +import CircularProgress from "@mui/material/CircularProgress"; +import React from "react"; + +const Loading: React.FC = () => { + return ( + theme.palette.primary.main, + zIndex: (theme) => theme.zIndex.drawer + 1, + }} + open={true} + > + + + ); +}; + +export default Loading; diff --git a/frontend/src/routes/index.tsx b/frontend/src/routes/index.tsx index 4bbce5d4..9c863f69 100644 --- a/frontend/src/routes/index.tsx +++ b/frontend/src/routes/index.tsx @@ -1,4 +1,4 @@ -import { CircularProgress } from "@mui/material"; +import Loading from "components/Loading"; import { WorkspaceSettingsPage, WorkspacesPage, @@ -31,14 +31,13 @@ const { WorkflowsPage } = lazyImport( * Application router * @todo implement recover password pages * @todo implement error (404, ...) pages - * @todo lazy loading with React.Lazy and Suspense * @returns app router component */ export const ApplicationRoutes: FC = () => ( - +
} > From 8080e0003602dad961fea66cec4ed86910eae41c Mon Sep 17 00:00:00 2001 From: luiz Date: Sun, 10 Sep 2023 09:53:50 +0200 Subject: [PATCH 231/328] fix display result --- docker-compose-dev.yaml | 2 +- src/domino/base_piece.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docker-compose-dev.yaml b/docker-compose-dev.yaml index 62c0c252..9b0c1541 100644 --- a/docker-compose-dev.yaml +++ b/docker-compose-dev.yaml @@ -309,7 +309,7 @@ services: - DOMINO_DB_HOST=domino_postgres - DOMINO_DB_PORT=5432 - DOMINO_DB_NAME=postgres - - DOMINO_DEFAULT_PIECES_REPOSITORY_VERSION=0.3.9 + - DOMINO_DEFAULT_PIECES_REPOSITORY_VERSION=0.3.11 - DOMINO_DEFAULT_PIECES_REPOSITORY_TOKEN=${DOMINO_DEFAULT_PIECES_REPOSITORY_TOKEN} - DOMINO_GITHUB_ACCESS_TOKEN_WORKFLOWS=${DOMINO_GITHUB_ACCESS_TOKEN_WORKFLOWS} - DOMINO_GITHUB_WORKFLOWS_REPOSITORY=${DOMINO_GITHUB_WORKFLOWS_REPOSITORY} diff --git a/src/domino/base_piece.py b/src/domino/base_piece.py index dc816807..9f5cede8 100644 --- a/src/domino/base_piece.py +++ b/src/domino/base_piece.py @@ -183,7 +183,7 @@ def format_xcom(self, output_obj: pydantic.BaseModel) -> dict: file_path=self.display_result["file_path"], file_type=self.display_result["file_type"] ) - self.display_result["file_path"] = str(self.display_result["file_path"]) + self.display_result["file_path"] = str(self.display_result.get("file_path", None)) self.display_result["file_type"] = str(self.display_result["file_type"]) xcom_obj["display_result"] = self.display_result From d2ad90a9341438f9702d1d6de05d916ac9c8bd8b Mon Sep 17 00:00:00 2001 From: luiz Date: Sun, 10 Sep 2023 10:18:48 +0200 Subject: [PATCH 232/328] no display results message --- src/domino/base_piece.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/domino/base_piece.py b/src/domino/base_piece.py index 9f5cede8..d83e4da6 100644 --- a/src/domino/base_piece.py +++ b/src/domino/base_piece.py @@ -185,7 +185,14 @@ def format_xcom(self, output_obj: pydantic.BaseModel) -> dict: ) self.display_result["file_path"] = str(self.display_result.get("file_path", None)) self.display_result["file_type"] = str(self.display_result["file_type"]) - xcom_obj["display_result"] = self.display_result + else: + raw_content = f"Piece {self.__class__.__name__} did not return a valid display_result." + base64_content = base64.b64encode(raw_content.encode("utf-8")).decode("utf-8") + self.display_result = dict() + self.display_result["file_path"] = None + self.display_result["file_type"] = "txt" + self.display_result["base64_content"] = base64_content + xcom_obj["display_result"] = self.display_result # Update XCOM with extra metadata xcom_obj.update( From 824374a642363100923c56c21aae54a32a782c2f Mon Sep 17 00:00:00 2001 From: luiz Date: Sun, 10 Sep 2023 10:47:48 +0200 Subject: [PATCH 233/328] update default version --- docker-compose-dev.yaml | 2 +- rest/core/settings.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docker-compose-dev.yaml b/docker-compose-dev.yaml index 9b0c1541..fd09fcc4 100644 --- a/docker-compose-dev.yaml +++ b/docker-compose-dev.yaml @@ -309,7 +309,7 @@ services: - DOMINO_DB_HOST=domino_postgres - DOMINO_DB_PORT=5432 - DOMINO_DB_NAME=postgres - - DOMINO_DEFAULT_PIECES_REPOSITORY_VERSION=0.3.11 + - DOMINO_DEFAULT_PIECES_REPOSITORY_VERSION=0.3.12 - DOMINO_DEFAULT_PIECES_REPOSITORY_TOKEN=${DOMINO_DEFAULT_PIECES_REPOSITORY_TOKEN} - DOMINO_GITHUB_ACCESS_TOKEN_WORKFLOWS=${DOMINO_GITHUB_ACCESS_TOKEN_WORKFLOWS} - DOMINO_GITHUB_WORKFLOWS_REPOSITORY=${DOMINO_GITHUB_WORKFLOWS_REPOSITORY} diff --git a/rest/core/settings.py b/rest/core/settings.py index 62858146..dd356d63 100644 --- a/rest/core/settings.py +++ b/rest/core/settings.py @@ -50,7 +50,7 @@ class Settings(BaseSettings): # Default domino pieces repository DOMINO_DEFAULT_PIECES_REPOSITORY = os.environ.get('DOMINO_DEFAULT_PIECES_REPOSITORY', "Tauffer-Consulting/default_domino_pieces") - DOMINO_DEFAULT_PIECES_REPOSITORY_VERSION = os.environ.get('DOMINO_DEFAULT_PIECES_REPOSITORY_VERSION', "0.3.11") + DOMINO_DEFAULT_PIECES_REPOSITORY_VERSION = os.environ.get('DOMINO_DEFAULT_PIECES_REPOSITORY_VERSION', "0.3.12") DOMINO_DEFAULT_PIECES_REPOSITORY_SOURCE = os.environ.get('DOMINO_DEFAULT_PIECES_REPOSITORY_SOURCE', "github") DOMINO_DEFAULT_PIECES_REPOSITORY_TOKEN: EmptyStrToNone = os.environ.get('DOMINO_DEFAULT_PIECES_REPOSITORY_TOKEN', "") DOMINO_DEFAULT_PIECES_REPOSITORY_URL: str = os.environ.get('DOMINO_DEFAULT_PIECES_REPOSITORY_URL', 'https://github.com/Tauffer-Consulting/default_domino_pieces') From ad51d1b3a2b7db9fd8c4f3fab8f2839b6787f2a6 Mon Sep 17 00:00:00 2001 From: luiz Date: Mon, 11 Sep 2023 13:49:59 +0200 Subject: [PATCH 234/328] deploy cli --- src/domino/cli/cli.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/domino/cli/cli.py b/src/domino/cli/cli.py index 2e5eaefa..f5bd3f9f 100644 --- a/src/domino/cli/cli.py +++ b/src/domino/cli/cli.py @@ -96,9 +96,9 @@ def get_registry_token_from_env(): ) @click.option( '--deploy-mode', - prompt='Development mode', + prompt='Deploy mode', default="local-k8s", - help='Development mode - either "local" or "remote". If local it will allow you to use hot reloading for local operators repositories' + help='Deploy mode - either "local" or "remote". If local it will allow you to use hot reloading for local operators repositories' ) @click.option( '--local-pieces-repository-path', From 25231ba3eaee957f86a35edf38f7b106fd6f381b Mon Sep 17 00:00:00 2001 From: luiz Date: Mon, 11 Sep 2023 17:39:58 +0200 Subject: [PATCH 235/328] have images ste in config file --- src/domino/cli/cli.py | 14 ++------------ src/domino/cli/utils/platform.py | 18 +++++++++++++++--- 2 files changed, 17 insertions(+), 15 deletions(-) diff --git a/src/domino/cli/cli.py b/src/domino/cli/cli.py index f5bd3f9f..1dc74b37 100644 --- a/src/domino/cli/cli.py +++ b/src/domino/cli/cli.py @@ -136,16 +136,6 @@ def cli_prepare_platform( @click.command() -@click.option( - "--domino-frontend-image", - default=None, - help="Load a local Domino frontend image to cluster." -) -@click.option( - "--domino-rest-image", - default=None, - help="Load a local Domino REST image to cluster." -) @click.option( "--run-airflow", default=True, @@ -158,9 +148,9 @@ def cli_prepare_platform( help="Allow the platform to use GPUs. It will install NVIDIA plugins.", default=False ) -def cli_create_platform(domino_frontend_image, domino_rest_image, run_airflow, use_gpu): +def cli_create_platform(run_airflow, use_gpu): """Create cluster, install services and run Domino platform.""" - platform.create_platform(domino_frontend_image, domino_rest_image, run_airflow, use_gpu) + platform.create_platform(run_airflow, use_gpu) @click.command() diff --git a/src/domino/cli/utils/platform.py b/src/domino/cli/utils/platform.py index 819c9e7e..e58b9eb0 100644 --- a/src/domino/cli/utils/platform.py +++ b/src/domino/cli/utils/platform.py @@ -70,6 +70,9 @@ def prepare_platform( config_dict['kind']['DOMINO_DEPLOY_MODE'] = deploy_mode if deploy_mode == 'local-k8s-dev': + config_dict['dev']['DOMINO_AIRFLOW_IMAGE'] = "" + config_dict['dev']['DOMINO_REST_IMAGE'] = "" + config_dict['dev']['DOMINO_FRONTEND_IMAGE'] = "" config_dict['dev']['DOMINO_LOCAL_DOMINO_PACKAGE'] = local_domino_path for local_pieces_repository in local_pieces_repository_path: # Read repo config.toml to get repo name to map it to cluster path @@ -102,7 +105,7 @@ def prepare_platform( console.print("") -def create_platform(domino_frontend_image: str = None, domino_rest_image: str = None, run_airflow: bool = True, use_gpu: bool = False) -> None: +def create_platform(run_airflow: bool = True, use_gpu: bool = False) -> None: # Load configuration values with open("config-domino-local.toml", "rb") as f: platform_config = tomli.load(f) @@ -120,7 +123,9 @@ def create_platform(domino_frontend_image: str = None, domino_rest_image: str = local_pieces_respositories = {key: value for key, value in platform_config['dev'].items() if key != "DOMINO_LOCAL_DOMINO_PACKAGE"} if platform_config['kind']['DOMINO_DEPLOY_MODE'] == 'local-k8s-dev': - #for repo_name, repo_path in platform_config['local_pieces_repositories'].items(): + domino_airflow_image = platform_config['dev'].get('DOMINO_AIRFLOW_IMAGE', None) + domino_rest_image = platform_config['dev'].get('DOMINO_REST_IMAGE', None) + domino_frontend_image = platform_config['dev'].get('DOMINO_FRONTEND_IMAGE', None) for repo_name, repo_path in local_pieces_respositories.items(): extra_mounts_local_repositories.append( dict( @@ -199,6 +204,13 @@ def create_platform(domino_frontend_image: str = None, domino_rest_image: str = subprocess.run(["kubectl", "wait", "--namespace", "ingress-nginx", "--for", "condition=ready", "pod", "--selector=app.kubernetes.io/component=controller", "--timeout=180s"]) # Load images to Kind cluster + if domino_airflow_image: + console.print(f"Loading local Domino Airflow image {domino_airflow_image} to Kind cluster...") + subprocess.run(["kind", "load", "docker-image", domino_airflow_image , "--name", cluster_name, "--nodes", f"{cluster_name}-worker"]) + domino_airflow_image = f'docker.io/library/{domino_airflow_image}' + else: + domino_airflow_image = "ghcr.io/tauffer-consulting/domino-airflow-base:latest" + if domino_frontend_image: console.print(f"Loading local frontend image {domino_frontend_image} to Kind cluster...") subprocess.run(["kind", "load", "docker-image", domino_frontend_image , "--name", cluster_name, "--nodes", f"{cluster_name}-worker"]) @@ -302,7 +314,7 @@ def create_platform(domino_frontend_image: str = None, domino_rest_image: str = "images": { "useDefaultImageForMigration": False, "airflow": { - "repository": "ghcr.io/tauffer-consulting/domino-airflow-base", + "repository": domino_airflow_image, "tag": "latest", "pullPolicy": "IfNotPresent" } From f2156869d1349a6efb4d8812a42061882dae9ae0 Mon Sep 17 00:00:00 2001 From: Nathan Vieira Marcelino Date: Fri, 8 Sep 2023 16:14:03 -0300 Subject: [PATCH 236/328] fix: aws s3 validation error --- .../workflowEditor/components/SidebarSettingsForm/index.tsx | 6 +++--- .../src/features/workflowEditor/context/types/settings.ts | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/frontend/src/features/workflowEditor/components/SidebarSettingsForm/index.tsx b/frontend/src/features/workflowEditor/components/SidebarSettingsForm/index.tsx index 391839b8..777cbf46 100644 --- a/frontend/src/features/workflowEditor/components/SidebarSettingsForm/index.tsx +++ b/frontend/src/features/workflowEditor/components/SidebarSettingsForm/index.tsx @@ -58,7 +58,7 @@ const storageSourceOptions = }, { label: "AWS S3", - value: "AWSS3", + value: "AWS S3", }, ]; @@ -84,7 +84,7 @@ export const WorkflowSettingsFormSchema: ValidationSchema = yup.object().shape({ }), storage: yup.object().shape({ storageSource: yup.lazy((value) => { - if (value === storageSourcesAWS.AWSS3) { + if (value === storageSourcesAWS.AWS_S3) { return yup .mixed() .oneOf(Object.values(storageSourcesAWS)) @@ -248,7 +248,7 @@ const SidebarSettingsForm = (props: ISidebarSettingsFormProps) => { defaultValue={defaultSettingsData.storage.storageSource} /> - {formData.storage.storageSource === storageSourcesAWS.AWSS3 ? ( + {formData.storage.storageSource === storageSourcesAWS.AWS_S3 ? ( <> Date: Fri, 8 Sep 2023 17:26:52 -0300 Subject: [PATCH 237/328] fix: Provider options in shared storage with bucket key even for Local #87 --- .../context/workflowsEditor.tsx | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/frontend/src/features/workflowEditor/context/workflowsEditor.tsx b/frontend/src/features/workflowEditor/context/workflowsEditor.tsx index 103a7786..d929d142 100644 --- a/frontend/src/features/workflowEditor/context/workflowsEditor.tsx +++ b/frontend/src/features/workflowEditor/context/workflowsEditor.tsx @@ -168,9 +168,21 @@ const WorkflowsEditorProvider: FC<{ children?: React.ReactNode }> = ({ [], ); + // eslint-disable-next-line @typescript-eslint/no-unused-vars const { storageSource, baseFolder, ...providerOptions } = workflowSettingsData.storage || {}; + const workflowSharedStorage = { + source: storageSource, + ...(baseFolder !== "" ? { base_folder: baseFolder } : {}), + ...{ mode: elementData?.storage?.storageAccessMode }, + provider_options: { + ...(providerOptions && providerOptions.bucket !== "" + ? { bucket: providerOptions.bucket } + : {}), + }, + }; + const pieceInputKwargs = Object.entries(elementData.inputs).reduce< Record >((acc, [key, value]) => { @@ -214,12 +226,7 @@ const WorkflowsEditorProvider: FC<{ children?: React.ReactNode }> = ({ }, dependencies, piece_input_kwargs: pieceInputKwargs, - workflow_shared_storage: { - source: storageSource, - base_folder: baseFolder, - mode: elementData?.storage?.storageAccessMode, - provider_options: providerOptions, - }, + workflow_shared_storage: workflowSharedStorage, container_resources: { requests: { cpu: elementData.containerResources.cpu.min, From 33fd118ea22a3b4f58c47a02a90a1234862efaf5 Mon Sep 17 00:00:00 2001 From: luiz Date: Mon, 11 Sep 2023 19:45:39 +0200 Subject: [PATCH 238/328] compose images --- docker-compose-dev.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docker-compose-dev.yaml b/docker-compose-dev.yaml index fd09fcc4..0798a293 100644 --- a/docker-compose-dev.yaml +++ b/docker-compose-dev.yaml @@ -225,7 +225,7 @@ services: # Modified Airflow Scheduler with Domino airflow-scheduler: <<: *airflow-common - # image: ghcr.io/tauffer-consulting/domino-airflow-base:latest + image: ghcr.io/tauffer-consulting/domino-airflow-base:latest build: context: . dockerfile: Dockerfile-airflow-domino-base-dev @@ -260,7 +260,7 @@ services: # Modified Airflow Worker with Domino airflow-worker: <<: *airflow-common - # image: ghcr.io/tauffer-consulting/domino-airflow-base:latest + image: ghcr.io/tauffer-consulting/domino-airflow-base:latest build: context: . dockerfile: Dockerfile-airflow-domino-base-dev From 31a3d3b91d0374041645886dc7e474c0eb783b91 Mon Sep 17 00:00:00 2001 From: Vinicius Vaz Date: Mon, 11 Sep 2023 15:39:47 -0300 Subject: [PATCH 239/328] update schemas --- .../default_pieces/storage/__init__.py | 9 +++---- .../default_pieces/storage/aws_s3.py | 20 +++++++++++----- rest/schemas/requests/workflow.py | 4 ++-- rest/services/piece_service.py | 5 ++-- rest/services/workflow_service.py | 9 +++---- src/domino/custom_operators/k8s_operator.py | 24 +++++++++++++------ src/domino/schemas/shared_storage.py | 11 ++++----- 7 files changed, 50 insertions(+), 32 deletions(-) diff --git a/rest/constants/default_pieces/storage/__init__.py b/rest/constants/default_pieces/storage/__init__.py index 453b859b..440df2ce 100644 --- a/rest/constants/default_pieces/storage/__init__.py +++ b/rest/constants/default_pieces/storage/__init__.py @@ -1,11 +1,12 @@ -from .aws_s3 import SecretsModel as AWSS3SecretsModel, AWSS3DefaultPiece -from .google_storage import SecretsModel as GoogleStorageSecretsModel, GCPStorageDefaultPiece +from .aws_s3 import AWSS3StoragePiece +#from .google_storage import SecretsModel as GoogleStorageSecretsModel, GCPStorageDefaultPiece DEFAULT_STORAGE_PIECES = [ { - "model": AWSS3DefaultPiece, - "secrets_model": AWSS3SecretsModel + "model": AWSS3StoragePiece, + # "secrets_model": AWSS3SecretsModel, + # "input_model": InputModel }, # { # "model": GCPStorageDefaultPiece, diff --git a/rest/constants/default_pieces/storage/aws_s3.py b/rest/constants/default_pieces/storage/aws_s3.py index 66e5dec9..39212649 100644 --- a/rest/constants/default_pieces/storage/aws_s3.py +++ b/rest/constants/default_pieces/storage/aws_s3.py @@ -1,13 +1,21 @@ from pydantic import BaseModel, Field - -class AWSS3DefaultPiece(BaseModel): - name: str = Field(title='Name', default='AWSS3DefaultPiece') - description: str = Field(title='Description', default='AWS s3 Storage Default Piece') - - class SecretsModel(BaseModel): AWS_ACCESS_KEY_ID: str = Field(title='AWS Access Key ID', default='') AWS_SECRET_ACCESS_KEY: str = Field(title='AWS Secret Access Key', default='') AWS_REGION_NAME: str = Field(title='AWS Region Name', default='') + +class InputModel(BaseModel): + bucket: str = Field(title='Bucket', default='') + base_folder: str = Field(title='Base Folder', default='') + + + +class AWSS3StoragePiece(BaseModel): + name: str = Field(title='Name', default='AWSS3StoragePiece') + description: str = Field(title='Description', default='AWS s3 Storage Default Piece') + + secrets_schema: dict = Field(default=SecretsModel.schema()) + input_schema: dict = Field(default=InputModel.schema()) + diff --git a/rest/schemas/requests/workflow.py b/rest/schemas/requests/workflow.py index 79656627..9113623a 100644 --- a/rest/schemas/requests/workflow.py +++ b/rest/schemas/requests/workflow.py @@ -3,7 +3,7 @@ from enum import Enum from pydantic import BaseModel, validator, Field from datetime import datetime -from constants.default_pieces.storage import AWSS3DefaultPiece +from constants.default_pieces.storage import AWSS3StoragePiece """ @@ -87,7 +87,7 @@ class Config: storage_default_piece_model_map = { 'none': None, - 'aws_s3': AWSS3DefaultPiece + 'aws_s3': AWSS3StoragePiece } class WorkflowSharedStorageSourceEnum(str, Enum): diff --git a/rest/services/piece_service.py b/rest/services/piece_service.py index 74b7007e..57663613 100644 --- a/rest/services/piece_service.py +++ b/rest/services/piece_service.py @@ -155,12 +155,11 @@ def create_default_storage_pieces(self, piece_repository_id: int = 1) -> None: pieces = [] for piece_metadata in DEFAULT_STORAGE_PIECES: model = piece_metadata.get('model')() - secrets_model = piece_metadata.get('secrets_model')() - piece = Piece( name=model.name, description=model.description, - secrets_schema=secrets_model.schema(), + secrets_schema=model.secrets_schema, + input_schema=model.input_schema, repository_id=piece_repository_id ) pieces.append(piece) diff --git a/rest/services/workflow_service.py b/rest/services/workflow_service.py index 30330c5d..9706ba0b 100644 --- a/rest/services/workflow_service.py +++ b/rest/services/workflow_service.py @@ -468,10 +468,11 @@ def _create_dag_code_from_raw_json(self, data: dict, workspace_id: int): else: input_kwargs[input_key] = input_value['value'] - workspace_storage_repository = self._get_storage_repository_from_tasks(tasks=tasks, workspace_id=workspace_id) - if workflow_shared_storage: - workflow_shared_storage['storage_repository_url'] = workspace_storage_repository.url if workspace_storage_repository else None - workflow_shared_storage['storage_repository_version'] = workspace_storage_repository.version if workspace_storage_repository else None + # workspace_storage_repository = self._get_storage_repository_from_tasks(tasks=tasks, workspace_id=workspace_id) + # if workflow_shared_storage: + # ... + #workflow_shared_storage['storage_repository_url'] = workspace_storage_repository.url if workspace_storage_repository else None + #workflow_shared_storage['storage_repository_version'] = workspace_storage_repository.version if workspace_storage_repository else None piece_db = self.piece_repository.find_by_id(piece_request.get('id')) piece_repository_db = self.piece_repository_repository.find_by_id(piece_db.repository_id) diff --git a/src/domino/custom_operators/k8s_operator.py b/src/domino/custom_operators/k8s_operator.py index 491ba612..44ec4852 100644 --- a/src/domino/custom_operators/k8s_operator.py +++ b/src/domino/custom_operators/k8s_operator.py @@ -273,8 +273,9 @@ def add_shared_storage_sidecar(self, pod: k8s.V1Pod) -> k8s.V1Pod: storage_piece_secrets = {} if self.workflow_shared_storage.source != "local": storage_piece_secrets = self._get_piece_secrets( - piece_repository_id=self.workflow_shared_storage.storage_repository_id, - piece_name=self.workflow_shared_storage.default_piece_name, + repository_url="domino-default/default_storage_repository", + repository_version="0.0.1", + piece_name=self.workflow_shared_storage.storage_piece_name, ) self.workflow_shared_storage.source = self.workflow_shared_storage.source.name sidecar_env_vars = { @@ -311,14 +312,19 @@ def add_shared_storage_sidecar(self, pod: k8s.V1Pod) -> k8s.V1Pod: return pod_cp - def _get_piece_secrets(self) -> Dict[str, Any]: + def _get_piece_secrets( + self, + repository_url: str, + repository_version: str, + piece_name: str + ) -> Dict[str, Any]: """Get piece secrets values from Domino API""" piece_repository_data = self.domino_client.get_piece_repositories_from_workspace_id( params={ "workspace_id": self.workspace_id, "filters": { - "url": self.repository_url, - "version": self.repository_version, + "url": repository_url, + "version": repository_version, }, "page": 0, "page_size": 1, @@ -326,7 +332,7 @@ def _get_piece_secrets(self) -> Dict[str, Any]: ).json() secrets_response = self.domino_client.get_piece_secrets( piece_repository_id=piece_repository_data["data"][0]["id"], - piece_name=self.piece_name + piece_name=piece_name ) if secrets_response.status_code != 200: raise Exception(f"Error getting piece secrets: {secrets_response.json()}") @@ -416,7 +422,11 @@ def _prepare_execute_environment(self, context: Context): self._update_env_var_value_from_name(name='DOMINO_RUN_PIECE_KWARGS', value=str(domino_k8s_run_op_kwargs)) # Add pieces secrets to environment variables - piece_secrets = self._get_piece_secrets() + piece_secrets = self._get_piece_secrets( + repository_url=self.repository_url, + repository_version=self.repository_version, + piece_name=self.piece_name, + ) self.env_vars.append({ "name": "DOMINO_PIECE_SECRETS", "value": str(piece_secrets), diff --git a/src/domino/schemas/shared_storage.py b/src/domino/schemas/shared_storage.py index 324a37b5..aa2d35e3 100644 --- a/src/domino/schemas/shared_storage.py +++ b/src/domino/schemas/shared_storage.py @@ -25,14 +25,15 @@ class WorkflowSharedStorage(BaseModel): description="The access mode to the storage source.", default="none" ) - default_piece_name: str = Field( + storage_piece_name: str = Field( description="The name of the default piece to be used for the storage source.", ) + class LocalSharedStorage(WorkflowSharedStorage): source = StorageSource.local - default_piece_name: str = "LocalDefaultOperator" # TODO to be implemented + storage_piece_name: str = "LocalStoragePiece" # TODO to be implemented class AwsS3SharedStorage(WorkflowSharedStorage): @@ -40,14 +41,12 @@ class AwsS3SharedStorage(WorkflowSharedStorage): bucket: str = Field( description="The name of the bucket to be used as the root of the storage source." ) - default_piece_name: str = "AWSS3DefaultPiece" + storage_piece_name: str = "AWSS3StoragePiece" base_folder: str = Field( description="The base folder to be used as the root of the storage source.", default="", ) - storage_repository_id: int = Field( - description="The id of the storage repository to be used as the root of the storage source.", - ) + shared_storage_map = { From 049ed4028622dcda1f21716189fd3d9dda132a22 Mon Sep 17 00:00:00 2001 From: Luiz Tauffer Date: Tue, 12 Sep 2023 10:02:49 +0200 Subject: [PATCH 240/328] update year --- frontend/src/features/auth/pages/signIn/signInPage.tsx | 2 +- frontend/src/features/auth/pages/signUp/signUpPage.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/frontend/src/features/auth/pages/signIn/signInPage.tsx b/frontend/src/features/auth/pages/signIn/signInPage.tsx index 7bc479c6..c9a30cf3 100644 --- a/frontend/src/features/auth/pages/signIn/signInPage.tsx +++ b/frontend/src/features/auth/pages/signIn/signInPage.tsx @@ -136,7 +136,7 @@ export const SignInPage: FC = () => { Tauffer Consulting - {" 2022."} + {" 2023."} diff --git a/frontend/src/features/auth/pages/signUp/signUpPage.tsx b/frontend/src/features/auth/pages/signUp/signUpPage.tsx index 6fe9dcba..a10f5962 100644 --- a/frontend/src/features/auth/pages/signUp/signUpPage.tsx +++ b/frontend/src/features/auth/pages/signUp/signUpPage.tsx @@ -146,7 +146,7 @@ export const SignUpPage: FC = () => { Tauffer Consulting - {" 2022."} + {" 2023."} From 07e99479e671d067652d69f44d5fbb85e2dbca99 Mon Sep 17 00:00:00 2001 From: luiz Date: Tue, 12 Sep 2023 12:44:23 +0200 Subject: [PATCH 241/328] some fixes on helm chart --- ...ent.yml => domino-database-deployment.yml} | 2 +- ...loyment.yml => domino-rest-deployment.yml} | 2 +- helm/domino/templates/ingress-api.yaml | 2 +- helm/domino/templates/ingress-frontend.yaml | 2 +- .../templates/jobs/domino-migrations.yml | 1 + helm/domino/values.yaml | 3 +- src/domino/cli/utils/platform.py | 28 +++++++++++++++---- 7 files changed, 30 insertions(+), 10 deletions(-) rename helm/domino/templates/{domino-postgres-deployment.yml => domino-database-deployment.yml} (97%) rename helm/domino/templates/{domino-backend-deployment.yml => domino-rest-deployment.yml} (98%) diff --git a/helm/domino/templates/domino-postgres-deployment.yml b/helm/domino/templates/domino-database-deployment.yml similarity index 97% rename from helm/domino/templates/domino-postgres-deployment.yml rename to helm/domino/templates/domino-database-deployment.yml index eef60df7..ea875c76 100644 --- a/helm/domino/templates/domino-postgres-deployment.yml +++ b/helm/domino/templates/domino-database-deployment.yml @@ -1,4 +1,4 @@ -# Domino Postgres resource +# Domino Database resource apiVersion: apps/v1 kind: Deployment metadata: diff --git a/helm/domino/templates/domino-backend-deployment.yml b/helm/domino/templates/domino-rest-deployment.yml similarity index 98% rename from helm/domino/templates/domino-backend-deployment.yml rename to helm/domino/templates/domino-rest-deployment.yml index 50e164d0..085128bf 100644 --- a/helm/domino/templates/domino-backend-deployment.yml +++ b/helm/domino/templates/domino-rest-deployment.yml @@ -33,7 +33,7 @@ spec: - name: AIRFLOW_WEBSERVER_HOST value: http://{{ .Release.Name }}-airflow-webserver:8080 - name: DOMINO_DEPLOY_MODE - value: local-k8s # TODO change to prod + value: {{ .Values.rest.deployMode }} - name: DOMINO_DB_HOST value: {{ .Release.Name }}-postgres-service - name: DOMINO_DB_NAME diff --git a/helm/domino/templates/ingress-api.yaml b/helm/domino/templates/ingress-api.yaml index efefd1e7..3b91b527 100644 --- a/helm/domino/templates/ingress-api.yaml +++ b/helm/domino/templates/ingress-api.yaml @@ -8,7 +8,7 @@ spec: rules: - http: paths: - - pathType: Prefix + - pathType: ImplementationSpecific path: /api(/|$)(.*) backend: service: diff --git a/helm/domino/templates/ingress-frontend.yaml b/helm/domino/templates/ingress-frontend.yaml index 15c8fcde..2431fba3 100644 --- a/helm/domino/templates/ingress-frontend.yaml +++ b/helm/domino/templates/ingress-frontend.yaml @@ -9,7 +9,7 @@ spec: rules: - http: paths: - - pathType: Prefix + - pathType: ImplementationSpecific path: /?(.*) backend: service: diff --git a/helm/domino/templates/jobs/domino-migrations.yml b/helm/domino/templates/jobs/domino-migrations.yml index 8abba15f..d11a5f42 100644 --- a/helm/domino/templates/jobs/domino-migrations.yml +++ b/helm/domino/templates/jobs/domino-migrations.yml @@ -12,6 +12,7 @@ spec: containers: - name: database-migrations image: {{ .Values.rest.image }} + imagePullPolicy: IfNotPresent command: ["/bin/bash"] args: ["run_migrations.sh"] # will sleep for 20 seconds, run migrations and create first user env: diff --git a/helm/domino/values.yaml b/helm/domino/values.yaml index c22b19fd..f6116715 100644 --- a/helm/domino/values.yaml +++ b/helm/domino/values.yaml @@ -14,12 +14,13 @@ rest: enabled: true image: ghcr.io/tauffer-consulting/domino-rest tag: latest + deployMode: local-k8s # TODO change to prod # Github workflows repository name - Same one used in airflow gitSync ssh workflowsRepository: ~ # Change this if using external Database database: - image: postgres + image: postgres:13 name: postgres user: postgres password: postgres diff --git a/src/domino/cli/utils/platform.py b/src/domino/cli/utils/platform.py index e58b9eb0..0d386e0d 100644 --- a/src/domino/cli/utils/platform.py +++ b/src/domino/cli/utils/platform.py @@ -189,11 +189,21 @@ def create_platform(run_airflow: bool = True, use_gpu: bool = False) -> None: cluster_name = platform_config["kind"]["DOMINO_KIND_CLUSTER_NAME"] - # Create Kind cluster + # Delete previous Kind cluster + console.print("") console.print(f"Removing previous Kind cluster - {cluster_name}...") - subprocess.run(["kind", "delete", "cluster", "--name", cluster_name]) + result = subprocess.run(["kind", "delete", "cluster", "--name", cluster_name], capture_output=True, text=True) + if result.returncode != 0: + error_message = result.stderr.strip() if result.stderr else result.stdout.strip() + raise Exception(f"An error occurred while deleting previous Kind cluster - {cluster_name}: {error_message}") + console.print("") + + # Create new Kind cluster console.print(f"Creating new Kind cluster - {cluster_name}...") - subprocess.run(["kind", "create", "cluster", "--name", cluster_name, "--config", "kind-cluster-config.yaml"]) + result = subprocess.run(["kind", "create", "cluster", "--name", cluster_name, "--config", "kind-cluster-config.yaml"]) + if result.returncode != 0: + error_message = result.stderr.strip() if result.stderr else result.stdout.strip() + raise Exception(f"An error occurred while creating Kind cluster - {cluster_name}: {error_message}") console.print("") console.print("Kind cluster created successfully!", style=f"bold {COLOR_PALETTE.get('success')}") @@ -201,7 +211,12 @@ def create_platform(run_airflow: bool = True, use_gpu: bool = False) -> None: console.print("") console.print("Installing NGINX controller...") subprocess.run(["kubectl", "apply", "-f", "https://raw.githubusercontent.com/kubernetes/ingress-nginx/main/deploy/static/provider/kind/deploy.yaml"], stdout=subprocess.DEVNULL) - subprocess.run(["kubectl", "wait", "--namespace", "ingress-nginx", "--for", "condition=ready", "pod", "--selector=app.kubernetes.io/component=controller", "--timeout=180s"]) + result = subprocess.run(["kubectl", "wait", "--namespace", "ingress-nginx", "--for", "condition=ready", "pod", "--selector=app.kubernetes.io/component=controller", "--timeout=180s"]) + if result.returncode != 0: + error_message = result.stderr.strip() if result.stderr else result.stdout.strip() + raise Exception("An error occurred while installing NGINX controller: {error_message}") + console.print("NGINX controller installed successfully!", style=f"bold {COLOR_PALETTE.get('success')}") + console.print("") # Load images to Kind cluster if domino_airflow_image: @@ -366,6 +381,7 @@ def create_platform(run_airflow: bool = True, use_gpu: bool = False) -> None: "-f", str(fp.name), "domino", f"{tmp_dir}/domino", + # "/media/luiz/storage2/Github/domino/helm/domino" # TODO: remove this line, only for local dev ] subprocess.run(commands) @@ -533,7 +549,9 @@ def create_platform(run_airflow: bool = True, use_gpu: bool = False) -> None: console.print("K8s resources created successfully!", style=f"bold {COLOR_PALETTE.get('success')}") console.print("You can now access the Domino frontend at: http://localhost/") - console.print("and the Backend API at: http://localhost/api/") + console.print("Domino's REST API: http://localhost/api/") + console.print("Domino's REST API Swagger: http://localhost/api/docs") + console.print("") def run_platform_compose(detached: bool = False, use_config_file: bool = False, dev: bool = False) -> None: From bd1d42c0eb17a247c5d308efa79702b8ef9f2174 Mon Sep 17 00:00:00 2001 From: luiz Date: Tue, 12 Sep 2023 13:12:13 +0200 Subject: [PATCH 242/328] fix wrong mounts --- src/domino/cli/utils/platform.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/domino/cli/utils/platform.py b/src/domino/cli/utils/platform.py index 0d386e0d..daeb9fac 100644 --- a/src/domino/cli/utils/platform.py +++ b/src/domino/cli/utils/platform.py @@ -121,11 +121,13 @@ def create_platform(run_airflow: bool = True, use_gpu: bool = False) -> None: ) extra_mounts_local_repositories = [] + if platform_config['kind']['DOMINO_DEPLOY_MODE'] == 'local-k8s-dev': + domino_airflow_image = platform_config['dev'].pop('DOMINO_AIRFLOW_IMAGE', None) + domino_rest_image = platform_config['dev'].pop('DOMINO_REST_IMAGE', None) + domino_frontend_image = platform_config['dev'].pop('DOMINO_FRONTEND_IMAGE', None) + local_pieces_respositories = {key: value for key, value in platform_config['dev'].items() if key != "DOMINO_LOCAL_DOMINO_PACKAGE"} if platform_config['kind']['DOMINO_DEPLOY_MODE'] == 'local-k8s-dev': - domino_airflow_image = platform_config['dev'].get('DOMINO_AIRFLOW_IMAGE', None) - domino_rest_image = platform_config['dev'].get('DOMINO_REST_IMAGE', None) - domino_frontend_image = platform_config['dev'].get('DOMINO_FRONTEND_IMAGE', None) for repo_name, repo_path in local_pieces_respositories.items(): extra_mounts_local_repositories.append( dict( From 7443154ff6bc3b601bbf01db57d4b8dada4cad65 Mon Sep 17 00:00:00 2001 From: luiz Date: Tue, 12 Sep 2023 18:01:13 +0200 Subject: [PATCH 243/328] dockerfiles and front deployment --- frontend/Dockerfile | 7 ++++--- frontend/Dockerfile.dev.k8s | 14 ++++++++++++++ ...{Dockerfile.compose => Dockerfile.prod.compose} | 0 .../templates/domino-frontend-deployment.yml | 6 +++--- 4 files changed, 21 insertions(+), 6 deletions(-) create mode 100644 frontend/Dockerfile.dev.k8s rename frontend/{Dockerfile.compose => Dockerfile.prod.compose} (100%) diff --git a/frontend/Dockerfile b/frontend/Dockerfile index 8f65b17b..4f950c9d 100644 --- a/frontend/Dockerfile +++ b/frontend/Dockerfile @@ -4,7 +4,7 @@ FROM node:19.2-bullseye-slim ENV REACT_APP_API_ENV=local -ENV DOMINO_DEPLOY_MODE=local-compose +ENV REACT_APP_DOMINO_DEPLOY_MODE=local-compose # ENV PATH /app/node_modules/.bin:$PATH WORKDIR /usr/src/app @@ -12,8 +12,9 @@ COPY --chown=node:node . /usr/src/app RUN mkdir -p node_modules/.cache RUN chmod -R 777 node_modules/.cache -RUN yarn install --frozen-lockfile --production +RUN yarn install +# --frozen-lockfile --production RUN yarn cache clean USER node -CMD ["yarn", "start"] +CMD ["yarn", "start:local"] diff --git a/frontend/Dockerfile.dev.k8s b/frontend/Dockerfile.dev.k8s new file mode 100644 index 00000000..ecfe78c8 --- /dev/null +++ b/frontend/Dockerfile.dev.k8s @@ -0,0 +1,14 @@ +FROM node:19.2-bullseye-slim + +ENV REACT_APP_API_ENV=dev + +WORKDIR /usr/src/app +COPY --chown=node:node . /usr/src/app +RUN mkdir -p node_modules/.cache +RUN chmod -R 777 node_modules/.cache + +RUN yarn install +RUN yarn cache clean + +USER node +CMD ["yarn", "start"] diff --git a/frontend/Dockerfile.compose b/frontend/Dockerfile.prod.compose similarity index 100% rename from frontend/Dockerfile.compose rename to frontend/Dockerfile.prod.compose diff --git a/helm/domino/templates/domino-frontend-deployment.yml b/helm/domino/templates/domino-frontend-deployment.yml index ff2d1adf..61934281 100644 --- a/helm/domino/templates/domino-frontend-deployment.yml +++ b/helm/domino/templates/domino-frontend-deployment.yml @@ -20,12 +20,12 @@ spec: image: {{ .Values.frontend.image }} imagePullPolicy: IfNotPresent ports: - - containerPort: 80 + - containerPort: 3000 #80 {{- if .Values.frontend.entrypointCommand }} command: {{ toYaml .Values.frontend.entrypointCommand | indent 12 }} args: - ["-c","yarn start:local"] + ["-c","yarn start"] {{- end }} env: - name: REACT_APP_API_URL @@ -49,7 +49,7 @@ spec: app: {{ .Release.Name }}-frontend ports: - port: 80 - #targetPort: 3000 + targetPort: 3000 #nodePort: 30030 #type: NodePort {{- end}} \ No newline at end of file From 1751de1481669f1b5391ec98a715b5f759d30dae Mon Sep 17 00:00:00 2001 From: luiz Date: Tue, 12 Sep 2023 18:19:55 +0200 Subject: [PATCH 244/328] small fix for dev mount --- src/domino/custom_operators/k8s_operator.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/domino/custom_operators/k8s_operator.py b/src/domino/custom_operators/k8s_operator.py index 44ec4852..4117e3f0 100644 --- a/src/domino/custom_operators/k8s_operator.py +++ b/src/domino/custom_operators/k8s_operator.py @@ -36,6 +36,7 @@ def __init__( self.workspace_id = workspace_id self.piece_input_kwargs = piece_input_kwargs self.workflow_shared_storage = workflow_shared_storage + self.piece_source_image = k8s_operator_kwargs["image"] # Environment variables pod_env_vars = { @@ -91,8 +92,7 @@ def _make_volumes_and_volume_mounts_dev(self): all_volumes = [] all_volume_mounts = [] - source_image = self.piece.get('source_image') - repository_raw_project_name = str(source_image).split('/')[2].split(':')[0] + repository_raw_project_name = str(self.piece_source_image).split('/')[-1].split(':')[0] persistent_volume_claim_name = 'pvc-{}'.format(str(repository_raw_project_name.lower().replace('_', '-'))) persistent_volume_name = 'pv-{}'.format(str(repository_raw_project_name.lower().replace('_', '-'))) From fd85d73f202598658459d1585e1120850aa6c49c Mon Sep 17 00:00:00 2001 From: Nathan Vieira Marcelino Date: Tue, 12 Sep 2023 15:55:38 -0300 Subject: [PATCH 245/328] fix: lint warnings --- .../context/workspaces/api/deleteUserWorkspace.ts | 6 +++--- .../src/context/workspaces/api/inviteWorkspace.ts | 6 +++--- .../src/context/workspaces/api/patchWorkspace.ts | 6 +++--- frontend/src/context/workspaces/types/workspaces.ts | 12 +++++++----- .../features/workflows/api/piece/piece.interface.ts | 4 ++-- .../workspaceSettings/RepositoriesCard.tsx | 8 ++++---- frontend/src/interfaces/repositorySource.enum.ts | 3 --- 7 files changed, 22 insertions(+), 23 deletions(-) delete mode 100644 frontend/src/interfaces/repositorySource.enum.ts diff --git a/frontend/src/context/workspaces/api/deleteUserWorkspace.ts b/frontend/src/context/workspaces/api/deleteUserWorkspace.ts index 7d2569a5..a783e657 100644 --- a/frontend/src/context/workspaces/api/deleteUserWorkspace.ts +++ b/frontend/src/context/workspaces/api/deleteUserWorkspace.ts @@ -2,7 +2,7 @@ import { type AxiosResponse } from "axios"; import { dominoApiClient } from "services/clients/domino.client"; -interface removeUserWorkspaceParams { +interface RemoveUserWorkspaceParams { workspaceId: string; userId: string; } @@ -15,7 +15,7 @@ const removeUserWorkspaceUrl = (workspaceId: string, userId: string) => * @returns workflow run result */ const removeUserWorkspace: ( - params: removeUserWorkspaceParams, + params: RemoveUserWorkspaceParams, ) => Promise = async (params) => { return await dominoApiClient.delete( removeUserWorkspaceUrl(params.workspaceId, params.userId), @@ -27,7 +27,7 @@ const removeUserWorkspace: ( * @param params `{ id: string }` */ export const useAuthenticatedRemoveUserWorkspace = () => { - const fetcher = async (params: removeUserWorkspaceParams) => + const fetcher = async (params: RemoveUserWorkspaceParams) => await removeUserWorkspace(params).then((data) => data); return fetcher; diff --git a/frontend/src/context/workspaces/api/inviteWorkspace.ts b/frontend/src/context/workspaces/api/inviteWorkspace.ts index 22aa3615..577279cc 100644 --- a/frontend/src/context/workspaces/api/inviteWorkspace.ts +++ b/frontend/src/context/workspaces/api/inviteWorkspace.ts @@ -2,7 +2,7 @@ import { type AxiosResponse } from "axios"; import { dominoApiClient } from "services/clients/domino.client"; -interface inviteWorkspaceParams { +interface InviteWorkspaceParams { workspaceId: string; userEmail: string; permission: string; @@ -16,7 +16,7 @@ const inviteWorkspaceUrl = (workspaceId: string) => * @returns workflow run result */ const inviteWorkspace: ( - params: inviteWorkspaceParams, + params: InviteWorkspaceParams, ) => Promise = async (params) => { return await dominoApiClient.post(inviteWorkspaceUrl(params.workspaceId), { user_email: params.userEmail, @@ -29,7 +29,7 @@ const inviteWorkspace: ( * @param params `{ id: string }` */ export const useAuthenticatedWorkspaceInvite = () => { - const fetcher = async (params: inviteWorkspaceParams) => + const fetcher = async (params: InviteWorkspaceParams) => await inviteWorkspace(params).then((data) => data); return fetcher; diff --git a/frontend/src/context/workspaces/api/patchWorkspace.ts b/frontend/src/context/workspaces/api/patchWorkspace.ts index 3c34bd08..7f58e942 100644 --- a/frontend/src/context/workspaces/api/patchWorkspace.ts +++ b/frontend/src/context/workspaces/api/patchWorkspace.ts @@ -3,7 +3,7 @@ import { type AxiosResponse } from "axios"; import { useWorkspaces } from "context/workspaces"; import { dominoApiClient } from "services/clients/domino.client"; -interface patchWorkspaceParams { +interface PatchWorkspaceParams { workspaceId: string; payload: { name?: string | null; @@ -18,7 +18,7 @@ const patchWorkspaceUrl = (workspaceId: string) => `/workspaces/${workspaceId}`; * @returns workflow run result */ const patchWorkspace: ( - params: patchWorkspaceParams, + params: PatchWorkspaceParams, ) => Promise = async (params) => { return await dominoApiClient.patch( patchWorkspaceUrl(params.workspaceId), @@ -38,7 +38,7 @@ export const useAuthenticatedPatchWorkspace = () => { "Impossible to run workflows without specifying a workspace", ); - const fetcher = async (params: patchWorkspaceParams) => + const fetcher = async (params: PatchWorkspaceParams) => await patchWorkspace(params).then((data) => data); return fetcher; diff --git a/frontend/src/context/workspaces/types/workspaces.ts b/frontend/src/context/workspaces/types/workspaces.ts index 7f47c5c4..1b792a4e 100644 --- a/frontend/src/context/workspaces/types/workspaces.ts +++ b/frontend/src/context/workspaces/types/workspaces.ts @@ -1,7 +1,9 @@ -import { type ERepositorySource } from "interfaces/repositorySource.enum"; +export enum repositorySource { + github = "github", +} // Workspace status enum with values (pending, accepted and rejected) -export enum EWorkspaceStatus { +export enum workspaceStatus { PENDING = "pending", ACCEPTED = "accepted", REJECTED = "rejected", @@ -18,7 +20,7 @@ export interface IWorkspaceSummary { id: string; workspace_name: string; user_permission: string; - status: EWorkspaceStatus; + status: workspaceStatus; github_access_token_filled: boolean; } @@ -42,7 +44,7 @@ export interface IGetWorkspaceUsersResponse { user_id: number; user_email: string; user_permission: string; - status: EWorkspaceStatus; + status: workspaceStatus; }, ]; metadata: IPaginationMetadata; @@ -55,7 +57,7 @@ export type IPostWorkspaceRepositoryResponseInterface = Record; export interface IPostWorkspaceRepositoryPayload { workspace_id: string; - source: ERepositorySource | string; + source: repositorySource | string; path: string; version: string; url: string; diff --git a/frontend/src/features/workflows/api/piece/piece.interface.ts b/frontend/src/features/workflows/api/piece/piece.interface.ts index e2b84ee5..ddebddcf 100644 --- a/frontend/src/features/workflows/api/piece/piece.interface.ts +++ b/frontend/src/features/workflows/api/piece/piece.interface.ts @@ -1,4 +1,4 @@ -import { type ERepositorySource } from "interfaces/repositorySource.enum"; +import { type repositorySource } from "context/workspaces/types"; interface IPaginationMetadata { page: number; @@ -38,7 +38,7 @@ export type IGetPiecesRepositoriesReleasesResponseInterface = * Get Pieces Repositories Releases request params */ export interface IGetPiecesRepositoriesReleasesParams { - source: ERepositorySource; + source: repositorySource; path: string; workspaceId?: string; } diff --git a/frontend/src/features/workspaces/components/workspaceSettings/RepositoriesCard.tsx b/frontend/src/features/workspaces/components/workspaceSettings/RepositoriesCard.tsx index a681e143..21b71262 100644 --- a/frontend/src/features/workspaces/components/workspaceSettings/RepositoriesCard.tsx +++ b/frontend/src/features/workspaces/components/workspaceSettings/RepositoriesCard.tsx @@ -28,8 +28,8 @@ import { Tooltip, } from "@mui/material"; import TextField from "@mui/material/TextField"; +import { repositorySource } from "context/workspaces/types"; import { type IPieceRepositoryMetadata } from "features/workflows/api"; -import { ERepositorySource } from "interfaces/repositorySource.enum"; import { type FC, type ReactNode, useCallback, useMemo, useState } from "react"; import { toast } from "react-toastify"; @@ -118,7 +118,7 @@ export const RepositoriesCard: FC = () => { setIsStepLoading(true); handleFetchRepoReleases({ path, - source: source as ERepositorySource, + source: source as repositorySource, }) .then((data) => { setAvailableVersions(data.splice(0, 10)); @@ -213,7 +213,7 @@ export const RepositoriesCard: FC = () => { InputProps={{ ...(!!url && { startAdornment: - source === ERepositorySource.github ? ( + source === repositorySource.github ? ( ) : ( @@ -279,7 +279,7 @@ export const RepositoriesCard: FC = () => { - {repo.source === ERepositorySource.github ? ( + {repo.source === repositorySource.github ? ( ) : ( diff --git a/frontend/src/interfaces/repositorySource.enum.ts b/frontend/src/interfaces/repositorySource.enum.ts deleted file mode 100644 index 04e66a3f..00000000 --- a/frontend/src/interfaces/repositorySource.enum.ts +++ /dev/null @@ -1,3 +0,0 @@ -export enum ERepositorySource { - github = "github", -} From 19b358d8eb4a72b10389dba016d0332d81be0e1c Mon Sep 17 00:00:00 2001 From: Nathan Vieira Marcelino Date: Tue, 12 Sep 2023 17:35:53 -0300 Subject: [PATCH 246/328] fix: remove dockerfile prod flag on dev container --- frontend/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/Dockerfile b/frontend/Dockerfile index 8f65b17b..e565ccc0 100644 --- a/frontend/Dockerfile +++ b/frontend/Dockerfile @@ -12,7 +12,7 @@ COPY --chown=node:node . /usr/src/app RUN mkdir -p node_modules/.cache RUN chmod -R 777 node_modules/.cache -RUN yarn install --frozen-lockfile --production +RUN yarn install --frozen-lockfile RUN yarn cache clean USER node From 5b5b918ecec3b8cce856ef95f45b43fceb930fae Mon Sep 17 00:00:00 2001 From: luiz Date: Wed, 13 Sep 2023 15:12:46 +0200 Subject: [PATCH 247/328] dockerfiles --- frontend/Dockerfile | 3 +-- frontend/Dockerfile.dev.k8s | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/frontend/Dockerfile b/frontend/Dockerfile index 4f950c9d..60d4691c 100644 --- a/frontend/Dockerfile +++ b/frontend/Dockerfile @@ -12,8 +12,7 @@ COPY --chown=node:node . /usr/src/app RUN mkdir -p node_modules/.cache RUN chmod -R 777 node_modules/.cache -RUN yarn install -# --frozen-lockfile --production +RUN yarn install --frozen-lockfile RUN yarn cache clean USER node diff --git a/frontend/Dockerfile.dev.k8s b/frontend/Dockerfile.dev.k8s index ecfe78c8..2c977000 100644 --- a/frontend/Dockerfile.dev.k8s +++ b/frontend/Dockerfile.dev.k8s @@ -7,7 +7,7 @@ COPY --chown=node:node . /usr/src/app RUN mkdir -p node_modules/.cache RUN chmod -R 777 node_modules/.cache -RUN yarn install +RUN yarn install --frozen-lockfile RUN yarn cache clean USER node From 98d1cf35ef57c1dc5499c4716d2fa89b140e0dd6 Mon Sep 17 00:00:00 2001 From: Nathan Vieira Marcelino Date: Wed, 13 Sep 2023 14:27:21 -0300 Subject: [PATCH 248/328] fix: lint issues --- frontend/.eslintignore | 6 ++++++ frontend/.eslintrc.json | 7 ++++++- frontend/src/features/workflows/types/runs.ts | 8 ++++---- frontend/src/features/workflows/types/workflow.ts | 4 ++-- 4 files changed, 18 insertions(+), 7 deletions(-) diff --git a/frontend/.eslintignore b/frontend/.eslintignore index e69de29b..d782ae72 100644 --- a/frontend/.eslintignore +++ b/frontend/.eslintignore @@ -0,0 +1,6 @@ +# Third party +**/node_modules + +# Build products +build/ +coverage/ diff --git a/frontend/.eslintrc.json b/frontend/.eslintrc.json index f9ed79c3..ce150ce6 100644 --- a/frontend/.eslintrc.json +++ b/frontend/.eslintrc.json @@ -17,6 +17,11 @@ "react", "prettier" ], + "settings": { + "react": { + "version": "detect" + } + }, "rules": { "no-restricted-imports": [ "error", @@ -105,7 +110,7 @@ }, { "selector": "enum", - "format":[ + "format": [ "camelCase" ] } diff --git a/frontend/src/features/workflows/types/runs.ts b/frontend/src/features/workflows/types/runs.ts index 29d5707a..bd0b2306 100644 --- a/frontend/src/features/workflows/types/runs.ts +++ b/frontend/src/features/workflows/types/runs.ts @@ -5,14 +5,14 @@ interface IPaginationMetadata { total: number; } -enum RunState { +enum runState { success = "success", failed = "failed", running = "running", queued = "queued", } -enum TaskState { +enum taskState { success = "success", running = "running", failed = "failed", @@ -34,7 +34,7 @@ export interface IWorkflowRuns { start_date: string; end_date: string; execution_date: string; - state: RunState; + state: runState; } export interface IWorkflowRunTasks { @@ -47,7 +47,7 @@ export interface IWorkflowRunTasks { docker_image: string; task_id: string; try_number: number; - state: TaskState; + state: taskState; } export interface IGetWorkflowRunsResponseInterface { diff --git a/frontend/src/features/workflows/types/workflow.ts b/frontend/src/features/workflows/types/workflow.ts index 15ab0ea2..0065ac5e 100644 --- a/frontend/src/features/workflows/types/workflow.ts +++ b/frontend/src/features/workflows/types/workflow.ts @@ -9,7 +9,7 @@ export interface IWorkflowElement { position: { x: number; y: number }; } -enum WorkflowStatus { +enum workflowStatus { creating = "creating", failed = "failed", active = "active", @@ -27,7 +27,7 @@ export interface IWorkflow { workspace_id: number; is_paused: boolean; is_active: boolean; - status: WorkflowStatus; + status: workflowStatus; is_subdag: boolean; last_pickled: string; schedule_interval: string; From a6091fbb644a3bfea935191ed03e050bac3b3637 Mon Sep 17 00:00:00 2001 From: Nathan Vieira Marcelino Date: Wed, 13 Sep 2023 14:40:47 -0300 Subject: [PATCH 249/328] chore: use components with Pascal style --- .../ContainerResourceForm.tsx} | 0 .../PieceForm/PieceFormItem}/arrayInput.tsx | 2 +- .../PieceForm/PieceFormItem}/disableCheckboxOptions.ts | 0 .../PieceForm/PieceFormItem}/index.tsx | 2 +- .../PieceForm/PieceFormItem}/objectInput.tsx | 2 +- .../PieceForm/PieceFormItem}/selectUpstreamInput.tsx | 2 +- .../pieceForm => SidebarForm/PieceForm}/index.tsx | 2 +- .../PieceForm}/upstreamOptions.ts | 0 .../pieceForm => SidebarForm/PieceForm}/validation.ts | 0 .../storageForm.tsx => SidebarForm/StorageForm.tsx} | 0 .../sidebarForm => SidebarForm}/index.tsx | 8 ++++---- .../features/workflowEditor/components/WorkflowEditor.tsx | 6 +++--- .../components/WorkflowEditorPanel/index.tsx | 8 +++++--- 13 files changed, 17 insertions(+), 15 deletions(-) rename frontend/src/features/workflowEditor/components/{WorkflowEditorPanel/sidebarForm/containerResourceForm.tsx => SidebarForm/ContainerResourceForm.tsx} (100%) rename frontend/src/features/workflowEditor/components/{WorkflowEditorPanel/sidebarForm/pieceForm/pieceFormItem => SidebarForm/PieceForm/PieceFormItem}/arrayInput.tsx (99%) rename frontend/src/features/workflowEditor/components/{WorkflowEditorPanel/sidebarForm/pieceForm/pieceFormItem => SidebarForm/PieceForm/PieceFormItem}/disableCheckboxOptions.ts (100%) rename frontend/src/features/workflowEditor/components/{WorkflowEditorPanel/sidebarForm/pieceForm/pieceFormItem => SidebarForm/PieceForm/PieceFormItem}/index.tsx (98%) rename frontend/src/features/workflowEditor/components/{WorkflowEditorPanel/sidebarForm/pieceForm/pieceFormItem => SidebarForm/PieceForm/PieceFormItem}/objectInput.tsx (98%) rename frontend/src/features/workflowEditor/components/{WorkflowEditorPanel/sidebarForm/pieceForm/pieceFormItem => SidebarForm/PieceForm/PieceFormItem}/selectUpstreamInput.tsx (97%) rename frontend/src/features/workflowEditor/components/{WorkflowEditorPanel/sidebarForm/pieceForm => SidebarForm/PieceForm}/index.tsx (97%) rename frontend/src/features/workflowEditor/components/{WorkflowEditorPanel/sidebarForm/pieceForm => SidebarForm/PieceForm}/upstreamOptions.ts (100%) rename frontend/src/features/workflowEditor/components/{WorkflowEditorPanel/sidebarForm/pieceForm => SidebarForm/PieceForm}/validation.ts (100%) rename frontend/src/features/workflowEditor/components/{WorkflowEditorPanel/sidebarForm/storageForm.tsx => SidebarForm/StorageForm.tsx} (100%) rename frontend/src/features/workflowEditor/components/{WorkflowEditorPanel/sidebarForm => SidebarForm}/index.tsx (97%) diff --git a/frontend/src/features/workflowEditor/components/WorkflowEditorPanel/sidebarForm/containerResourceForm.tsx b/frontend/src/features/workflowEditor/components/SidebarForm/ContainerResourceForm.tsx similarity index 100% rename from frontend/src/features/workflowEditor/components/WorkflowEditorPanel/sidebarForm/containerResourceForm.tsx rename to frontend/src/features/workflowEditor/components/SidebarForm/ContainerResourceForm.tsx diff --git a/frontend/src/features/workflowEditor/components/WorkflowEditorPanel/sidebarForm/pieceForm/pieceFormItem/arrayInput.tsx b/frontend/src/features/workflowEditor/components/SidebarForm/PieceForm/PieceFormItem/arrayInput.tsx similarity index 99% rename from frontend/src/features/workflowEditor/components/WorkflowEditorPanel/sidebarForm/pieceForm/pieceFormItem/arrayInput.tsx rename to frontend/src/features/workflowEditor/components/SidebarForm/PieceForm/PieceFormItem/arrayInput.tsx index 459c5a37..8fe7b247 100644 --- a/frontend/src/features/workflowEditor/components/WorkflowEditorPanel/sidebarForm/pieceForm/pieceFormItem/arrayInput.tsx +++ b/frontend/src/features/workflowEditor/components/SidebarForm/PieceForm/PieceFormItem/arrayInput.tsx @@ -20,7 +20,7 @@ import { useWatch, } from "react-hook-form"; -import { type ArrayOption } from "../../pieceForm/upstreamOptions"; +import { type ArrayOption } from "../upstreamOptions"; import { disableCheckboxOptions } from "./disableCheckboxOptions"; import ObjectInputComponent from "./objectInput"; diff --git a/frontend/src/features/workflowEditor/components/WorkflowEditorPanel/sidebarForm/pieceForm/pieceFormItem/disableCheckboxOptions.ts b/frontend/src/features/workflowEditor/components/SidebarForm/PieceForm/PieceFormItem/disableCheckboxOptions.ts similarity index 100% rename from frontend/src/features/workflowEditor/components/WorkflowEditorPanel/sidebarForm/pieceForm/pieceFormItem/disableCheckboxOptions.ts rename to frontend/src/features/workflowEditor/components/SidebarForm/PieceForm/PieceFormItem/disableCheckboxOptions.ts diff --git a/frontend/src/features/workflowEditor/components/WorkflowEditorPanel/sidebarForm/pieceForm/pieceFormItem/index.tsx b/frontend/src/features/workflowEditor/components/SidebarForm/PieceForm/PieceFormItem/index.tsx similarity index 98% rename from frontend/src/features/workflowEditor/components/WorkflowEditorPanel/sidebarForm/pieceForm/pieceFormItem/index.tsx rename to frontend/src/features/workflowEditor/components/SidebarForm/PieceForm/PieceFormItem/index.tsx index c34d8423..8dfff74c 100644 --- a/frontend/src/features/workflowEditor/components/WorkflowEditorPanel/sidebarForm/pieceForm/pieceFormItem/index.tsx +++ b/frontend/src/features/workflowEditor/components/SidebarForm/PieceForm/PieceFormItem/index.tsx @@ -9,7 +9,7 @@ import { type IWorkflowPieceData } from "features/workflowEditor/context/types"; import React, { useMemo } from "react"; import { type Control, useWatch } from "react-hook-form"; -import { type ArrayOption, type Option } from "../../pieceForm/upstreamOptions"; +import { type ArrayOption, type Option } from "../upstreamOptions"; import ArrayInput from "./arrayInput"; import { disableCheckboxOptions } from "./disableCheckboxOptions"; diff --git a/frontend/src/features/workflowEditor/components/WorkflowEditorPanel/sidebarForm/pieceForm/pieceFormItem/objectInput.tsx b/frontend/src/features/workflowEditor/components/SidebarForm/PieceForm/PieceFormItem/objectInput.tsx similarity index 98% rename from frontend/src/features/workflowEditor/components/WorkflowEditorPanel/sidebarForm/pieceForm/pieceFormItem/objectInput.tsx rename to frontend/src/features/workflowEditor/components/SidebarForm/PieceForm/PieceFormItem/objectInput.tsx index b95410c5..2b2b83ad 100644 --- a/frontend/src/features/workflowEditor/components/WorkflowEditorPanel/sidebarForm/pieceForm/pieceFormItem/objectInput.tsx +++ b/frontend/src/features/workflowEditor/components/SidebarForm/PieceForm/PieceFormItem/objectInput.tsx @@ -6,7 +6,7 @@ import React, { useCallback, useMemo, useState } from "react"; import { useWatch } from "react-hook-form"; import { getDefinition } from "utils"; -import { type Option } from "../../pieceForm/upstreamOptions"; +import { type Option } from "../upstreamOptions"; import { disableCheckboxOptions } from "./disableCheckboxOptions"; import SelectUpstreamInput from "./selectUpstreamInput"; diff --git a/frontend/src/features/workflowEditor/components/WorkflowEditorPanel/sidebarForm/pieceForm/pieceFormItem/selectUpstreamInput.tsx b/frontend/src/features/workflowEditor/components/SidebarForm/PieceForm/PieceFormItem/selectUpstreamInput.tsx similarity index 97% rename from frontend/src/features/workflowEditor/components/WorkflowEditorPanel/sidebarForm/pieceForm/pieceFormItem/selectUpstreamInput.tsx rename to frontend/src/features/workflowEditor/components/SidebarForm/PieceForm/PieceFormItem/selectUpstreamInput.tsx index ce95d429..23b17da3 100644 --- a/frontend/src/features/workflowEditor/components/WorkflowEditorPanel/sidebarForm/pieceForm/pieceFormItem/selectUpstreamInput.tsx +++ b/frontend/src/features/workflowEditor/components/SidebarForm/PieceForm/PieceFormItem/selectUpstreamInput.tsx @@ -11,7 +11,7 @@ import React, { useCallback } from "react"; import { Controller, useFormContext } from "react-hook-form"; import { fetchFromObject } from "utils"; -import { type Option } from "../../pieceForm/upstreamOptions"; +import { type Option } from "../upstreamOptions"; type ObjectName = `inputs.${string}.value.${number}.upstreamValue.${string}`; type Name = `inputs.${string}`; diff --git a/frontend/src/features/workflowEditor/components/WorkflowEditorPanel/sidebarForm/pieceForm/index.tsx b/frontend/src/features/workflowEditor/components/SidebarForm/PieceForm/index.tsx similarity index 97% rename from frontend/src/features/workflowEditor/components/WorkflowEditorPanel/sidebarForm/pieceForm/index.tsx rename to frontend/src/features/workflowEditor/components/SidebarForm/PieceForm/index.tsx index 5f308cb2..4ab53ed6 100644 --- a/frontend/src/features/workflowEditor/components/WorkflowEditorPanel/sidebarForm/pieceForm/index.tsx +++ b/frontend/src/features/workflowEditor/components/SidebarForm/PieceForm/index.tsx @@ -3,7 +3,7 @@ import { type IWorkflowPieceData } from "features/workflowEditor/context/types"; import React, { useCallback, useEffect, useMemo, useState } from "react"; import { useFormContext } from "react-hook-form"; -import PieceFormItem from "./pieceFormItem"; +import PieceFormItem from "./PieceFormItem"; import { type UpstreamOptions, getUpstreamOptions } from "./upstreamOptions"; interface PieceFormProps { diff --git a/frontend/src/features/workflowEditor/components/WorkflowEditorPanel/sidebarForm/pieceForm/upstreamOptions.ts b/frontend/src/features/workflowEditor/components/SidebarForm/PieceForm/upstreamOptions.ts similarity index 100% rename from frontend/src/features/workflowEditor/components/WorkflowEditorPanel/sidebarForm/pieceForm/upstreamOptions.ts rename to frontend/src/features/workflowEditor/components/SidebarForm/PieceForm/upstreamOptions.ts diff --git a/frontend/src/features/workflowEditor/components/WorkflowEditorPanel/sidebarForm/pieceForm/validation.ts b/frontend/src/features/workflowEditor/components/SidebarForm/PieceForm/validation.ts similarity index 100% rename from frontend/src/features/workflowEditor/components/WorkflowEditorPanel/sidebarForm/pieceForm/validation.ts rename to frontend/src/features/workflowEditor/components/SidebarForm/PieceForm/validation.ts diff --git a/frontend/src/features/workflowEditor/components/WorkflowEditorPanel/sidebarForm/storageForm.tsx b/frontend/src/features/workflowEditor/components/SidebarForm/StorageForm.tsx similarity index 100% rename from frontend/src/features/workflowEditor/components/WorkflowEditorPanel/sidebarForm/storageForm.tsx rename to frontend/src/features/workflowEditor/components/SidebarForm/StorageForm.tsx diff --git a/frontend/src/features/workflowEditor/components/WorkflowEditorPanel/sidebarForm/index.tsx b/frontend/src/features/workflowEditor/components/SidebarForm/index.tsx similarity index 97% rename from frontend/src/features/workflowEditor/components/WorkflowEditorPanel/sidebarForm/index.tsx rename to frontend/src/features/workflowEditor/components/SidebarForm/index.tsx index e20d7a12..c47d304b 100644 --- a/frontend/src/features/workflowEditor/components/WorkflowEditorPanel/sidebarForm/index.tsx +++ b/frontend/src/features/workflowEditor/components/SidebarForm/index.tsx @@ -16,10 +16,10 @@ import * as yup from "yup"; import ContainerResourceForm, { ContainerResourceFormSchema, -} from "./containerResourceForm"; -import PieceForm from "./pieceForm"; -import { createInputsSchemaValidation } from "./pieceForm/validation"; -import StorageForm, { storageFormSchema } from "./storageForm"; +} from "./ContainerResourceForm"; +import PieceForm from "./PieceForm"; +import { createInputsSchemaValidation } from "./PieceForm/validation"; +import StorageForm, { storageFormSchema } from "./StorageForm"; interface ISidebarPieceFormProps { formId: string; diff --git a/frontend/src/features/workflowEditor/components/WorkflowEditor.tsx b/frontend/src/features/workflowEditor/components/WorkflowEditor.tsx index dea74956..129cff99 100644 --- a/frontend/src/features/workflowEditor/components/WorkflowEditor.tsx +++ b/frontend/src/features/workflowEditor/components/WorkflowEditor.tsx @@ -12,13 +12,13 @@ import { yupResolver } from "utils"; import * as yup from "yup"; import { PermanentDrawerRightWorkflows } from "./DrawerMenu"; +import { ContainerResourceFormSchema } from "./SidebarForm/ContainerResourceForm"; +import { createInputsSchemaValidation } from "./SidebarForm/PieceForm/validation"; +import { storageFormSchema } from "./SidebarForm/StorageForm"; import SidebarSettingsForm, { WorkflowSettingsFormSchema, } from "./SidebarSettingsForm"; import WorkflowEditorPanelComponent from "./WorkflowEditorPanel"; -import { ContainerResourceFormSchema } from "./WorkflowEditorPanel/sidebarForm/containerResourceForm"; -import { createInputsSchemaValidation } from "./WorkflowEditorPanel/sidebarForm/pieceForm/validation"; -import { storageFormSchema } from "./WorkflowEditorPanel/sidebarForm/storageForm"; /** * Create workflow tab // TODO refactor/simplify inner files diff --git a/frontend/src/features/workflowEditor/components/WorkflowEditorPanel/index.tsx b/frontend/src/features/workflowEditor/components/WorkflowEditorPanel/index.tsx index d8e36fed..655e784c 100644 --- a/frontend/src/features/workflowEditor/components/WorkflowEditorPanel/index.tsx +++ b/frontend/src/features/workflowEditor/components/WorkflowEditorPanel/index.tsx @@ -27,7 +27,7 @@ import ReactFlow, { } from "reactflow"; import { v4 as uuidv4 } from "uuid"; -import SidebarForm from "./sidebarForm"; +import SidebarForm from "../SidebarForm"; /** * @todo When change the workspace should we clear the forage ? * @todo Solve any types @@ -125,8 +125,10 @@ const WorkflowEditorPanelComponent = ({ nodesWithErros }: Props) => { ); // Drag and Drop functions - // @ts-expect-error: Unreachable code error - const onDragOver = (event) => { + const onDragOver = (event: { + preventDefault: () => void; + dataTransfer: { dropEffect: string }; + }) => { event.preventDefault(); event.dataTransfer.dropEffect = "move"; }; From 961852f6e6f486522fec82161d8003604005dcdd Mon Sep 17 00:00:00 2001 From: Nathan Vieira Marcelino Date: Wed, 13 Sep 2023 20:39:24 -0300 Subject: [PATCH 250/328] lint: allow unused vars if starts with underscore --- frontend/.eslintrc.json | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/frontend/.eslintrc.json b/frontend/.eslintrc.json index ce150ce6..409c6007 100644 --- a/frontend/.eslintrc.json +++ b/frontend/.eslintrc.json @@ -61,7 +61,11 @@ "react/react-in-jsx-scope": "off", "jsx-a11y/anchor-is-valid": "off", "@typescript-eslint/no-unused-vars": [ - "error" + "error", + { + "argsIgnorePattern": "^_", + "varsIgnorePattern": "^_" + } ], "@typescript-eslint/explicit-function-return-type": [ "off" @@ -93,7 +97,11 @@ "snake_case", "PascalCase", "UPPER_CASE" - ] + ], + "filter":{ + "regex": "^_", + "match":false + } }, { "selector": "function", From daa96142cd509a6ede3134eaf00575a6c1fc2d6d Mon Sep 17 00:00:00 2001 From: Nathan Vieira Marcelino Date: Wed, 13 Sep 2023 20:40:19 -0300 Subject: [PATCH 251/328] fix: improve react-scripts speed --- frontend/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/package.json b/frontend/package.json index 260c17b0..14d4e57d 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -51,7 +51,7 @@ "yup": "^1.2.0" }, "scripts": { - "start": "cross-env REACT_APP_API_ENV=dev react-scripts start", + "start": "cross-env REACT_APP_API_ENV=dev DISABLE_ESLINT_PLUGIN=true react-scripts start", "start:local": "cross-env NODE_OPTIONS=--openssl-legacy-provider REACT_APP_API_ENV=local react-scripts start", "start:mock": "cross-env NODE_OPTIONS=--openssl-legacy-provider REACT_APP_API_ENV=local REACT_APP_USE_MOCK=true react-scripts start", "build": "cross-env react-scripts build", From 72e16b0ba83749b5f680aeec290ba80595b5b3db Mon Sep 17 00:00:00 2001 From: Nathan Vieira Marcelino Date: Thu, 14 Sep 2023 22:34:58 -0300 Subject: [PATCH 252/328] feat: create default react-workflow --- frontend/src/components/CustomEdge/index.tsx | 41 +++ frontend/src/components/CustomNode/Handle.tsx | 79 +++++ frontend/src/components/CustomNode/index.tsx | 319 ++++++++++-------- frontend/src/components/ReactFlow/index.tsx | 121 +++++++ 4 files changed, 428 insertions(+), 132 deletions(-) create mode 100644 frontend/src/components/CustomEdge/index.tsx create mode 100644 frontend/src/components/CustomNode/Handle.tsx create mode 100644 frontend/src/components/ReactFlow/index.tsx diff --git a/frontend/src/components/CustomEdge/index.tsx b/frontend/src/components/CustomEdge/index.tsx new file mode 100644 index 00000000..79a57d20 --- /dev/null +++ b/frontend/src/components/CustomEdge/index.tsx @@ -0,0 +1,41 @@ +import { + BaseEdge, + type EdgeProps, + getSmoothStepPath, + MarkerType, +} from "reactflow"; + +export default function CustomEdge({ + id, + sourceX, + sourceY, + targetX, + targetY, + sourcePosition, + targetPosition, +}: EdgeProps) { + const [edgePath, labelX, labelY] = getSmoothStepPath({ + sourceX, + sourceY, + sourcePosition, + targetX, + targetY, + targetPosition, + }); + + return ( + + ); +} diff --git a/frontend/src/components/CustomNode/Handle.tsx b/frontend/src/components/CustomNode/Handle.tsx new file mode 100644 index 00000000..c433a466 --- /dev/null +++ b/frontend/src/components/CustomNode/Handle.tsx @@ -0,0 +1,79 @@ +import theme from "providers/theme.config"; +import React, { type CSSProperties, useMemo } from "react"; +import { Handle, Position, type HandleProps } from "reactflow"; + +const targetStyle: React.CSSProperties = { + width: 10, + height: 10, + borderRadius: "16px", + backgroundColor: "transparent", + transition: "ease 100ms", +}; + +const sourceStyle: React.CSSProperties = { + width: 10, + height: 10, + borderRadius: "16px", + backgroundColor: "transparent", + transition: "ease 100ms", +}; + +interface CustomHandleProps extends HandleProps { + hovered: boolean; +} + +const CustomHandle: React.FC = ({ + hovered, + ...props +}: CustomHandleProps) => { + const styles = useMemo(() => { + if (!hovered) { + return { + border: 0, + borderRadius: "16px", + backgroundColor: "transparent", + transition: "ease 100ms", + }; + } + + if (props.type === "source" && props.position === Position.Right) { + return { + ...sourceStyle, + right: "8px", + borderLeft: "10px solid", + borderLeftColor: theme.palette.grey[400], + borderTop: "10px solid transparent", + borderBottom: "10px solid transparent", + float: "left", + } satisfies CSSProperties; + } + if (props.type === "source" && props.position === Position.Bottom) { + return { + ...sourceStyle, + bottom: "-16px", + } satisfies CSSProperties; + } + if (props.type === "target" && props.position === Position.Top) { + return { + ...targetStyle, + top: "-16px", + } satisfies CSSProperties; + } + if (props.type === "target" && props.position === Position.Left) { + return { + ...targetStyle, + left: "-16px", + borderLeft: "10px solid", + borderLeftColor: theme.palette.grey[600], + borderTop: "10px solid transparent", + borderBottom: "10px solid transparent", + float: "left", + } satisfies CSSProperties; + } + return {} satisfies CSSProperties; + }, [props.type, props.position, hovered]); + + return ; +}; + +export default CustomHandle; diff --git a/frontend/src/components/CustomNode/index.tsx b/frontend/src/components/CustomNode/index.tsx index 3df35d07..41c4cf12 100644 --- a/frontend/src/components/CustomNode/index.tsx +++ b/frontend/src/components/CustomNode/index.tsx @@ -1,8 +1,12 @@ /* eslint-disable no-prototype-builtins */ -import { memo } from "react"; -import { Handle, Position } from "reactflow"; +import { Paper, Typography } from "@mui/material"; +import theme from "providers/theme.config"; +import React, { memo, useMemo, useState } from "react"; +import { Position, type NodeProps } from "reactflow"; import { getUuidSlice } from "utils"; +import CustomHandle from "./Handle"; + interface IStyleData { iconClassName: string; iconStyle: object; @@ -23,137 +27,188 @@ export interface INodeData { error: boolean; } -/** - * @todo make it work - */ -const CustomNode = memo((data: any) => { - const extendedData = data.data; - - const dominoReactflowClassTypeMap: any = { - source: "input", - default: "default", - sink: "output", - }; - let extendedClassExt = ""; - if ( - extendedData?.style.nodeType === undefined || - !["default", "source", "sink"].includes(extendedData?.style.nodeType) - ) { - extendedClassExt = "default"; - } else { - extendedClassExt = - dominoReactflowClassTypeMap[extendedData?.style.nodeType]; - } - const extendedClass = `react-flow__node-${extendedClassExt}`; - // Handle render definition - const nodeTypeRenderHandleMap: any = { - input: { - renderTargetHandle: false, - renderSourceHandle: true, - }, - output: { - renderTargetHandle: true, - renderSourceHandle: false, - }, - default: { - renderTargetHandle: true, - renderSourceHandle: true, - }, - }; - - let targetHandlePosition = Position.Top; - let sourceHandlePosition = Position.Bottom; - if (extendedData?.handleOriantation === "horizontal") { - targetHandlePosition = Position.Left; - sourceHandlePosition = Position.Right; - } - - // // Icon - const useIcon = !!extendedData?.style?.useIcon; - const iconId = - useIcon && extendedData?.style?.hasOwnProperty("iconId") - ? extendedData?.style?.iconId - : ""; - const iconClass = - useIcon && extendedData?.style?.hasOwnProperty("iconClassName") - ? extendedData.style.iconClassName - : "fas fa-eye"; - const iconStyle = - useIcon && extendedData?.style?.hasOwnProperty("iconStyle") - ? extendedData.style.iconStyle - : {}; - - // // Style - let customStyle: any = { - display: "flex", - flexDirection: "row-reverse", - justifyContent: useIcon ? "left" : "center", - alignItems: "center", - }; - if (extendedData?.style.hasOwnProperty("nodeStyle")) { - customStyle = Object.assign(customStyle, extendedData.style.nodeStyle); - } - - if (extendedData?.error) { - customStyle = Object.assign(customStyle, { - backgroundColor: "#f44336", - color: "#e6e6e6", - }); - } - - return ( -
- {nodeTypeRenderHandleMap[extendedClassExt].renderSourceHandle ? ( - - ) : ( - "" - )} -
- {extendedData?.style?.label - ? extendedData?.style?.label - : extendedData?.name} -

- {getUuidSlice(data.id)} -

+interface CustomNodeProps extends NodeProps { + data: INodeData; +} + +const CustomNode = memo( + ({ id, data: extendedData, selected }: CustomNodeProps) => { + const [hovered, setHovered] = useState(false); + + const extendedClassExt = useMemo(() => { + const dominoReactflowClassTypeMap: any = { + source: "input", + default: "default", + sink: "output", + }; + if ( + extendedData?.style.nodeType === undefined || + !["default", "source", "sink"].includes(extendedData?.style.nodeType) + ) { + return "default"; + } else { + return dominoReactflowClassTypeMap[extendedData?.style.nodeType]; + } + }, [extendedData]); + + const extendedClass = useMemo(() => { + return `react-flow__node-${extendedClassExt}`; + }, [extendedClassExt]); + + const nodeTypeRenderHandleMap = useMemo( + () => + ({ + input: { + renderTargetHandle: false, + renderSourceHandle: true, + }, + output: { + renderTargetHandle: true, + renderSourceHandle: false, + }, + default: { + renderTargetHandle: true, + renderSourceHandle: true, + }, + }) as any, + [], + ); + + const { targetHandlePosition, sourceHandlePosition } = useMemo(() => { + return extendedData?.handleOriantation === "horizontal" + ? { + targetHandlePosition: Position.Left, + sourceHandlePosition: Position.Right, + } + : { + targetHandlePosition: Position.Top, + sourceHandlePosition: Position.Bottom, + }; + }, [extendedData]); + + const { useIcon, iconId, iconClass, iconStyle } = useMemo(() => { + const useIcon = !!extendedData?.style?.useIcon; + const iconId = + useIcon && extendedData?.style?.hasOwnProperty("iconId") + ? extendedData?.style?.iconId + : ""; + const iconClass = + useIcon && extendedData?.style?.hasOwnProperty("iconClassName") + ? extendedData.style.iconClassName + : "fas fa-eye"; + let iconStyle: React.CSSProperties = { + position: "absolute", + left: "4px", + }; + + if (useIcon && extendedData?.style?.hasOwnProperty("iconStyle")) { + iconStyle = { ...iconStyle, ...extendedData.style.iconStyle }; + } + + return { + useIcon, + iconId, + iconClass, + iconStyle, + }; + }, [extendedData]); + + const customStyle = useMemo(() => { + let style: React.CSSProperties = { + display: "flex", + flexDirection: "row", + justifyContent: "center", + alignItems: "center", + + position: "relative", + + height: 60, + lineHeight: "60px", + border: selected ? "2px" : "", + borderStyle: selected ? "solid" : "", + borderColor: selected ? theme.palette.info.dark : "", + borderRadius: selected ? "3px" : "", + }; + + if (extendedData?.style.hasOwnProperty("nodeStyle")) { + console.log( + "extendedData.style.nodeStyle", + extendedData.style.nodeStyle, + ); + style = Object.assign(style, extendedData.style.nodeStyle); + } + + if (extendedData?.error) { + style = Object.assign(style, { + backgroundColor: theme.palette.error.light, + color: theme.palette.background.paper, + }); + } + + return style; + }, [selected, extendedData]); + + return ( +
{ + setHovered(true); + }} + onMouseLeave={() => { + setHovered(false); + }} + > + {nodeTypeRenderHandleMap[extendedClassExt].renderTargetHandle ? ( + + ) : null} + + {useIcon ? ( + + + + ) : null} +
+ + {extendedData?.style?.label + ? extendedData?.style?.label + : extendedData?.name} + + + {getUuidSlice(id)} + +
+
+ {nodeTypeRenderHandleMap[extendedClassExt].renderSourceHandle ? ( + + ) : null}
- {useIcon ? ( -
- - - -
- ) : ( - "" - )} - {nodeTypeRenderHandleMap[extendedClassExt].renderTargetHandle ? ( - - ) : ( - "" - )} -
- ); -}); + ); + }, +); CustomNode.displayName = "CustomNode"; diff --git a/frontend/src/components/ReactFlow/index.tsx b/frontend/src/components/ReactFlow/index.tsx new file mode 100644 index 00000000..6a80e635 --- /dev/null +++ b/frontend/src/components/ReactFlow/index.tsx @@ -0,0 +1,121 @@ +import CustomEdge from "components/CustomEdge"; +import CustomNode from "components/CustomNode"; +import theme from "providers/theme.config"; +import React, { + type DragEventHandler, + useCallback, + useRef, + type DragEvent, +} from "react"; +import ReactFlow, { + addEdge, + Background, + Controls, + ReactFlowProvider, + type Connection, + type Edge, + useNodesState, + useEdgesState, + type NodeMouseHandler, + type OnNodesDelete, + type OnEdgesDelete, + type Node, + type ReactFlowInstance, +} from "reactflow"; + +// Load CustomNode +const NODE_TYPES = { + CustomNode, +}; + +const EDGE_TYPES = { + CustomEdge, +}; +type OnInit = + | ((instance: ReactFlowInstance) => { + nodes: Node[]; + edges: Edge[]; + }) + | (( + instance: ReactFlowInstance, + ) => Promise<{ nodes: Node[]; edges: Edge[] }>); + +type Props = + | { + editable: true; + onNodesDelete: OnNodesDelete; + onEdgesDelete: OnEdgesDelete; + onDrop: DragEventHandler; + onInit: OnInit; + + onNodeDoubleClick?: NodeMouseHandler; + } + | { + editable: false; + onNodeDoubleClick?: NodeMouseHandler; + }; + +const WorkflowPanel: React.FC = (props: Props) => { + const reactFlowWrapper = useRef(null); + const [nodes, _setNodes, onNodesChange] = useNodesState([]); + const [edges, setEdges, onEdgesChange] = useEdgesState([]); + + const onNodesDelete = useCallback( + props.editable ? props.onNodesDelete : () => {}, + [], + ); + + const onEdgesDelete = useCallback( + props.editable ? props.onEdgesDelete : () => {}, + [], + ); + + const onNodeDoubleClick = useCallback( + props.editable && props.onNodeDoubleClick + ? props.onNodeDoubleClick + : () => {}, + [], + ); + + const onDragOver = (event: DragEvent) => { + event.preventDefault(); + event.dataTransfer.dropEffect = "move"; + }; + + const onDrop = useCallback(props.editable ? props.onDrop : () => {}, []); + + const onConnect = useCallback((connection: Connection) => { + setEdges((prevEdges: Edge[]) => addEdge(connection, prevEdges)); + }, []); + + return ( + +
+ + + + +
+
+ ); +}; + +export default WorkflowPanel; From 782c13de5e4714ecfeb39392081e78cee2808088 Mon Sep 17 00:00:00 2001 From: Nathan Vieira Marcelino Date: Fri, 15 Sep 2023 11:04:35 -0300 Subject: [PATCH 253/328] fix: lint errors --- .../features/workflowEditor/components/DrawerMenu/index.tsx | 2 +- .../workflowEditor/components/DrawerMenu/sidebarAddNode.tsx | 4 ++-- .../workflowEditor/components/DrawerMenu/sidebarNode.tsx | 2 +- .../SidebarForm/PieceForm/PieceFormItem/arrayInput.tsx | 1 - .../SidebarForm/PieceForm/PieceFormItem/objectInput.tsx | 2 +- .../src/features/workflowEditor/components/WorkflowEditor.tsx | 1 - .../workspaces/components/workspaceSettings/SecretsCard.tsx | 4 ++-- .../components/workspaceSettings/StorageSecretsCard.tsx | 4 ++-- 8 files changed, 9 insertions(+), 11 deletions(-) diff --git a/frontend/src/features/workflowEditor/components/DrawerMenu/index.tsx b/frontend/src/features/workflowEditor/components/DrawerMenu/index.tsx index e1bc7979..23ce64b5 100644 --- a/frontend/src/features/workflowEditor/components/DrawerMenu/index.tsx +++ b/frontend/src/features/workflowEditor/components/DrawerMenu/index.tsx @@ -28,7 +28,7 @@ interface PermanentDrawerRightWorkflowsProps { export const PermanentDrawerRightWorkflows: FC< PermanentDrawerRightWorkflowsProps -> = ({ isOpen, handleClose }) => { +> = () => { const theme = useTheme(); const [openDrawer, setOpenDrawer] = useState(true); diff --git a/frontend/src/features/workflowEditor/components/DrawerMenu/sidebarAddNode.tsx b/frontend/src/features/workflowEditor/components/DrawerMenu/sidebarAddNode.tsx index b567eb5b..d98e21f0 100644 --- a/frontend/src/features/workflowEditor/components/DrawerMenu/sidebarAddNode.tsx +++ b/frontend/src/features/workflowEditor/components/DrawerMenu/sidebarAddNode.tsx @@ -10,7 +10,7 @@ import { Typography, } from "@mui/material"; import { useWorkflowsEditor } from "features/workflowEditor/context"; -import { type FC, type SyntheticEvent, useState } from "react"; +import { type FC, useState } from "react"; import PiecesSidebarNode from "./sidebarNode"; @@ -86,7 +86,7 @@ const SidebarAddNode: FC = () => { TransitionProps={{ unmountOnExit: true }} expanded={expandedRepos.includes(repo.id)} key={repo.id} - onChange={(event: SyntheticEvent, expanded: boolean) => { + onChange={() => { if (loadingPieces) return; setLoadingPieces(repo.id); diff --git a/frontend/src/features/workflowEditor/components/DrawerMenu/sidebarNode.tsx b/frontend/src/features/workflowEditor/components/DrawerMenu/sidebarNode.tsx index 65d61a05..bfdc8e53 100644 --- a/frontend/src/features/workflowEditor/components/DrawerMenu/sidebarNode.tsx +++ b/frontend/src/features/workflowEditor/components/DrawerMenu/sidebarNode.tsx @@ -18,7 +18,7 @@ const PiecesSidebarNode: FC<{ piece: Piece }> = ({ piece }) => { }; // Help popover - const handlePopoverOpen = (event: React.MouseEvent) => { + const handlePopoverOpen = () => { setPopoverOpen(true); }; diff --git a/frontend/src/features/workflowEditor/components/SidebarForm/PieceForm/PieceFormItem/arrayInput.tsx b/frontend/src/features/workflowEditor/components/SidebarForm/PieceForm/PieceFormItem/arrayInput.tsx index 8fe7b247..7328cc54 100644 --- a/frontend/src/features/workflowEditor/components/SidebarForm/PieceForm/PieceFormItem/arrayInput.tsx +++ b/frontend/src/features/workflowEditor/components/SidebarForm/PieceForm/PieceFormItem/arrayInput.tsx @@ -36,7 +36,6 @@ interface ArrayInputItemProps { } const ArrayInput: React.FC = ({ - formId, inputKey, schema, upstreamOptions, diff --git a/frontend/src/features/workflowEditor/components/SidebarForm/PieceForm/PieceFormItem/objectInput.tsx b/frontend/src/features/workflowEditor/components/SidebarForm/PieceForm/PieceFormItem/objectInput.tsx index 2b2b83ad..e52c2af8 100644 --- a/frontend/src/features/workflowEditor/components/SidebarForm/PieceForm/PieceFormItem/objectInput.tsx +++ b/frontend/src/features/workflowEditor/components/SidebarForm/PieceForm/PieceFormItem/objectInput.tsx @@ -75,7 +75,7 @@ const ObjectInputComponent: React.FC = ({ return ( <> - {Object.entries(defaultValues).map(([key, value]) => { + {Object.entries(defaultValues).map(([key]) => { const fromUpstream = isFromUpstream(key); const disableUpstream = disableCheckboxOptions(itensSchema[key] as any); return ( diff --git a/frontend/src/features/workflowEditor/components/WorkflowEditor.tsx b/frontend/src/features/workflowEditor/components/WorkflowEditor.tsx index 129cff99..83e9a9fb 100644 --- a/frontend/src/features/workflowEditor/components/WorkflowEditor.tsx +++ b/frontend/src/features/workflowEditor/components/WorkflowEditor.tsx @@ -94,7 +94,6 @@ export const WorkflowsEditorComponent: React.FC = () => { const data = await workflowsEditorBodyFromFlowchart(); - // TODO fill workspace id correctly await handleCreateWorkflow({ workspace_id: workspace?.id, ...data }); toast.success("Workflow created successfully."); diff --git a/frontend/src/features/workspaces/components/workspaceSettings/SecretsCard.tsx b/frontend/src/features/workspaces/components/workspaceSettings/SecretsCard.tsx index 54507e64..815cfde0 100644 --- a/frontend/src/features/workspaces/components/workspaceSettings/SecretsCard.tsx +++ b/frontend/src/features/workspaces/components/workspaceSettings/SecretsCard.tsx @@ -78,7 +78,7 @@ const SecretsCard = (props: SecretsCardProps, ref: Ref) => { secretId: selectedSecretId as string, payload, }) - .then((response) => { + .then(() => { toast.success("Secret updated."); void refreshSecrets(); resetField(selectedSecretId?.toString(), { keepTouched: false }); @@ -108,7 +108,7 @@ const SecretsCard = (props: SecretsCardProps, ref: Ref) => { secretId: selectedSecretId as string, payload, }) - .then((response) => { + .then(() => { toast.success("Secret updated"); void refreshSecrets(); setCurrrentEdittingSecretId(null); diff --git a/frontend/src/features/workspaces/components/workspaceSettings/StorageSecretsCard.tsx b/frontend/src/features/workspaces/components/workspaceSettings/StorageSecretsCard.tsx index e485cbe5..9c168b4c 100644 --- a/frontend/src/features/workspaces/components/workspaceSettings/StorageSecretsCard.tsx +++ b/frontend/src/features/workspaces/components/workspaceSettings/StorageSecretsCard.tsx @@ -80,7 +80,7 @@ const StorageSecretsCard = () => { secretId: selectedSecretId as string, payload, }) - .then((response) => { + .then((_response) => { toast.success("Secret updated."); void refreshSecrets(); resetField(selectedSecretId?.toString(), { keepTouched: false }); @@ -110,7 +110,7 @@ const StorageSecretsCard = () => { secretId: selectedSecretId as string, payload, }) - .then((response) => { + .then((_response) => { toast.success("Secret updated"); void refreshSecrets(); setCurrrentEdittingSecretId(null); From 6a09e582baaec4f5bef45ca8177aed9a13cd6ddb Mon Sep 17 00:00:00 2001 From: Nathan Vieira Marcelino Date: Fri, 15 Sep 2023 13:03:19 -0300 Subject: [PATCH 254/328] chore: use separated react-workflow --- frontend/src/@types/global.d.ts | 1 + frontend/src/@types/utils/index.d.ts | 12 ++ frontend/src/components/ReactFlow/index.tsx | 86 +++++++++++-- .../components/WorkflowEditorPanel/index.tsx | 120 ++---------------- 4 files changed, 99 insertions(+), 120 deletions(-) create mode 100644 frontend/src/@types/utils/index.d.ts diff --git a/frontend/src/@types/global.d.ts b/frontend/src/@types/global.d.ts index 8ba9778e..cf982313 100644 --- a/frontend/src/@types/global.d.ts +++ b/frontend/src/@types/global.d.ts @@ -1,2 +1,3 @@ /* eslint-disable @typescript-eslint/triple-slash-reference */ /// +/// diff --git a/frontend/src/@types/utils/index.d.ts b/frontend/src/@types/utils/index.d.ts new file mode 100644 index 00000000..cea52507 --- /dev/null +++ b/frontend/src/@types/utils/index.d.ts @@ -0,0 +1,12 @@ +declare global { + type FunctionOrPromiseReturnType = T extends ( + instance: ReactFlowInstance, + ) => infer R + ? R + : T extends ( + instance: ReactFlowInstance, + ) => Promise + ? R + : never; +} +export {}; diff --git a/frontend/src/components/ReactFlow/index.tsx b/frontend/src/components/ReactFlow/index.tsx index 6a80e635..a3dd0630 100644 --- a/frontend/src/components/ReactFlow/index.tsx +++ b/frontend/src/components/ReactFlow/index.tsx @@ -1,12 +1,7 @@ import CustomEdge from "components/CustomEdge"; -import CustomNode from "components/CustomNode"; +import CustomNode, { type INodeData } from "components/CustomNode"; import theme from "providers/theme.config"; -import React, { - type DragEventHandler, - useCallback, - useRef, - type DragEvent, -} from "react"; +import React, { useCallback, type DragEvent, useState, useRef } from "react"; import ReactFlow, { addEdge, Background, @@ -21,6 +16,7 @@ import ReactFlow, { type OnEdgesDelete, type Node, type ReactFlowInstance, + type XYPosition, } from "reactflow"; // Load CustomNode @@ -40,26 +36,57 @@ type OnInit = instance: ReactFlowInstance, ) => Promise<{ nodes: Node[]; edges: Edge[] }>); +type OnDrop = + | (( + event: DragEvent, + position: XYPosition, + ) => Node) + | (( + event: DragEvent, + position: XYPosition, + ) => Promise>); + type Props = | { editable: true; onNodesDelete: OnNodesDelete; onEdgesDelete: OnEdgesDelete; - onDrop: DragEventHandler; + onDrop: OnDrop; onInit: OnInit; onNodeDoubleClick?: NodeMouseHandler; } | { editable: false; + onInit: OnInit; onNodeDoubleClick?: NodeMouseHandler; }; const WorkflowPanel: React.FC = (props: Props) => { - const reactFlowWrapper = useRef(null); - const [nodes, _setNodes, onNodesChange] = useNodesState([]); + const reactFlowWrapper = useRef(null); + const [instance, setInstance] = useState(null); + const [nodes, setNodes, onNodesChange] = useNodesState([]); const [edges, setEdges, onEdgesChange] = useEdgesState([]); + const onInit = useCallback(async (instance: ReactFlowInstance) => { + setInstance(instance); + const result = props.onInit(instance); + if (result instanceof Promise) { + result + .then(({ nodes, edges }) => { + setNodes(nodes); + setEdges(edges); + }) + .catch((error) => { + console.error("Error from Promise-returning function:", error); + }); + } else { + const { nodes, edges } = result; + setNodes(nodes); + setEdges(edges); + } + }, []); + const onNodesDelete = useCallback( props.editable ? props.onNodesDelete : () => {}, [], @@ -82,7 +109,37 @@ const WorkflowPanel: React.FC = (props: Props) => { event.dataTransfer.dropEffect = "move"; }; - const onDrop = useCallback(props.editable ? props.onDrop : () => {}, []); + const onDrop = useCallback( + async (event: DragEvent) => { + event.preventDefault(); + if (reactFlowWrapper?.current === null) { + return; + } + const reactFlowBounds = reactFlowWrapper.current.getBoundingClientRect(); + // @ts-expect-error: Unreachable code error + const position = instance.project({ + x: event.clientX - reactFlowBounds.left, + y: event.clientY - reactFlowBounds.top, + }); + + if (props.editable) { + const result = props.onDrop(event, position); + if (result instanceof Promise) { + result + .then((node) => { + setNodes((ns: Node[]) => ns.concat(node)); + }) + .catch((error) => { + console.error("Error from Promise-returning function:", error); + }); + } else { + const node = result; + setNodes((ns: Node[]) => ns.concat(node)); + } + } + }, + [instance, setNodes], + ); const onConnect = useCallback((connection: Connection) => { setEdges((prevEdges: Edge[]) => addEdge(connection, prevEdges)); @@ -93,14 +150,15 @@ const WorkflowPanel: React.FC = (props: Props) => {
= (props: Props) => { onDragOver={onDragOver} > - +
diff --git a/frontend/src/features/workflowEditor/components/WorkflowEditorPanel/index.tsx b/frontend/src/features/workflowEditor/components/WorkflowEditorPanel/index.tsx index 655e784c..95fe6d10 100644 --- a/frontend/src/features/workflowEditor/components/WorkflowEditorPanel/index.tsx +++ b/frontend/src/features/workflowEditor/components/WorkflowEditorPanel/index.tsx @@ -1,4 +1,5 @@ -import CustomNode, { type INodeData } from "components/CustomNode"; +import { type INodeData } from "components/CustomNode"; +import WorkflowPanel from "components/ReactFlow"; import { useWorkflowsEditor } from "features/workflowEditor/context"; import { type IWorkflowPieceData, @@ -9,22 +10,8 @@ import { extractDefaultInputValues, extractDefaultValues, } from "features/workflowEditor/utils"; -import React, { useCallback, useEffect, useRef, useState } from "react"; -import ReactFlow, { - addEdge, - Background, - Controls, - ReactFlowProvider, - type NodeChange, - type EdgeChange, - applyNodeChanges, - applyEdgeChanges, - type Connection, - type Edge, - MarkerType, - // removeElements, - type Node, -} from "reactflow"; +import React, { type DragEvent, useCallback, useEffect, useState } from "react"; +import { type XYPosition, type Edge } from "reactflow"; import { v4 as uuidv4 } from "uuid"; import SidebarForm from "../SidebarForm"; @@ -33,11 +20,6 @@ import SidebarForm from "../SidebarForm"; * @todo Solve any types */ -// Load CustomNode -const nodeTypes = { - CustomNode, -}; - // @ts-expect-error: Unreachable code error const getId = (module_name) => { return `${module_name}_${uuidv4()}`; @@ -53,13 +35,10 @@ const WorkflowEditorPanelComponent = ({ nodesWithErros }: Props) => { const [formTitle, setFormTitle] = useState(""); const [drawerState, setDrawerState] = useState(false); const [reactFlowInstance, setReactFlowInstance] = useState(null); - const reactFlowWrapper = useRef(null); const { nodeDirection, - edges, setEdges, - nodes, setNodes, fetchForagePieceById, fetchForageWorkflowNodes, @@ -114,38 +93,15 @@ const WorkflowEditorPanelComponent = ({ nodesWithErros }: Props) => { const workflowNodes = await fetchForageWorkflowNodes(); const workflowEdges = await fetchForageWorkflowEdges(); - if (workflowNodes.length > 0) { - setNodes(workflowNodes); - } - if (workflowEdges.length > 0) { - setEdges(workflowEdges); - } + return { nodes: workflowNodes, edges: workflowEdges }; }, [setNodes, setEdges, fetchForageWorkflowNodes, fetchForageWorkflowEdges], ); - // Drag and Drop functions - const onDragOver = (event: { - preventDefault: () => void; - dataTransfer: { dropEffect: string }; - }) => { - event.preventDefault(); - event.dataTransfer.dropEffect = "move"; - }; - const onDrop = useCallback( - async (event: any) => { + async (event: DragEvent, position: XYPosition) => { event.preventDefault(); - - // @ts-expect-error: Unreachable code error - const reactFlowBounds = reactFlowWrapper.current.getBoundingClientRect(); const nodeData = event.dataTransfer.getData("application/reactflow"); - // @ts-expect-error: Unreachable code error - const position = reactFlowInstance.project({ - x: event.clientX - reactFlowBounds.left, - y: event.clientY - reactFlowBounds.top, - }); - const { ...data } = JSON.parse(nodeData); const newNodeData: INodeData = { @@ -162,7 +118,6 @@ const WorkflowEditorPanelComponent = ({ nodesWithErros }: Props) => { data: newNodeData, }; - setNodes((ns: Node[]) => ns.concat(newNode)); const piece = await fetchForagePieceById(data.id); const defaultInputs = extractDefaultInputValues( piece as unknown as Piece, @@ -185,6 +140,7 @@ const WorkflowEditorPanelComponent = ({ nodesWithErros }: Props) => { }; await setForageWorkflowPiecesData(newNode.id, defaultWorkflowPieceData); + return newNode; }, [ fetchForagePieceById, @@ -209,41 +165,6 @@ const WorkflowEditorPanelComponent = ({ nodesWithErros }: Props) => { setDrawerState(open); }; - const onNodesChange = useCallback( - (changes: NodeChange[]) => { - setNodes((nds: Node[]) => applyNodeChanges(changes, nds)); - }, - [setNodes], - ); - - const onEdgesChange = useCallback( - (changes: EdgeChange[]) => { - setEdges((eds: Edge[]) => applyEdgeChanges(changes, eds)); - }, - [setEdges], - ); - - // Connecting elements - const onConnect = useCallback( - (connection: Connection) => { - setEdges((prevEdges: Edge[]) => { - const newEdges = addEdge(connection, prevEdges); - newEdges.forEach((edge: Edge) => { - edge.markerEnd = { - type: MarkerType.ArrowClosed, - width: 30, - height: 30, - color: "#6a6a6e", - }; - edge.animated = false; - }); - - return newEdges; - }); - }, - [setEdges], - ); - const setNodeErrors = useCallback( (nodeIds: string[]) => { setNodes((nds) => @@ -277,31 +198,18 @@ const WorkflowEditorPanelComponent = ({ nodesWithErros }: Props) => { }, [nodesWithErros, setNodeErrors]); return ( - -
- +
+ - - - + />
+ { open={drawerState} title={formTitle} /> - + ); }; From ee2e66bba6336af68db0f9a330cd6a9b0d0929a2 Mon Sep 17 00:00:00 2001 From: Nathan Vieira Marcelino Date: Tue, 19 Sep 2023 13:30:22 -0300 Subject: [PATCH 255/328] feat: add workflow auto-layout --- frontend/package.json | 2 + frontend/src/components/CustomNode/Handle.tsx | 4 - frontend/src/components/CustomNode/index.tsx | 31 +- frontend/src/components/ReactFlow/index.tsx | 315 +++++++++----- .../components/DrawerMenu/sidebarAddNode.tsx | 18 +- .../components/WorkflowEditor.tsx | 409 +++++++++++++----- .../components/WorkflowEditorPanel/index.tsx | 224 ---------- .../features/workflowEditor/context/index.tsx | 23 +- .../context/reactWorkflowPersistence.tsx | 65 +++ .../workflowEditor/context/workflowEdges.tsx | 63 --- .../workflowEditor/context/workflowNodes.tsx | 79 ---- .../context/workflowsEditor.tsx | 73 ++-- .../WorkflowsRunTasksFlowchart/index.tsx | 13 - frontend/src/utils/useAutoSave.ts | 18 + frontend/yarn.lock | 10 + 15 files changed, 657 insertions(+), 690 deletions(-) delete mode 100644 frontend/src/features/workflowEditor/components/WorkflowEditorPanel/index.tsx create mode 100644 frontend/src/features/workflowEditor/context/reactWorkflowPersistence.tsx delete mode 100644 frontend/src/features/workflowEditor/context/workflowEdges.tsx delete mode 100644 frontend/src/features/workflowEditor/context/workflowNodes.tsx create mode 100644 frontend/src/utils/useAutoSave.ts diff --git a/frontend/package.json b/frontend/package.json index 14d4e57d..617a518c 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -32,6 +32,7 @@ "axios-mock-adapter": "^1.21.2", "cross-env": "^7.0.3", "dayjs": "^1.11.7", + "elkjs": "^0.8.2", "localforage": "^1.10.0", "material-ui-dropzone": "^3.5.0", "prop-types": "^15.8.1", @@ -48,6 +49,7 @@ "swr": "^2.0.0", "typescript": "*", "uuid": "^9.0.0", + "web-worker": "^1.2.0", "yup": "^1.2.0" }, "scripts": { diff --git a/frontend/src/components/CustomNode/Handle.tsx b/frontend/src/components/CustomNode/Handle.tsx index c433a466..80e2f2f7 100644 --- a/frontend/src/components/CustomNode/Handle.tsx +++ b/frontend/src/components/CustomNode/Handle.tsx @@ -39,7 +39,6 @@ const CustomHandle: React.FC = ({ if (props.type === "source" && props.position === Position.Right) { return { ...sourceStyle, - right: "8px", borderLeft: "10px solid", borderLeftColor: theme.palette.grey[400], borderTop: "10px solid transparent", @@ -50,19 +49,16 @@ const CustomHandle: React.FC = ({ if (props.type === "source" && props.position === Position.Bottom) { return { ...sourceStyle, - bottom: "-16px", } satisfies CSSProperties; } if (props.type === "target" && props.position === Position.Top) { return { ...targetStyle, - top: "-16px", } satisfies CSSProperties; } if (props.type === "target" && props.position === Position.Left) { return { ...targetStyle, - left: "-16px", borderLeft: "10px solid", borderLeftColor: theme.palette.grey[600], borderTop: "10px solid transparent", diff --git a/frontend/src/components/CustomNode/index.tsx b/frontend/src/components/CustomNode/index.tsx index 41c4cf12..9506af61 100644 --- a/frontend/src/components/CustomNode/index.tsx +++ b/frontend/src/components/CustomNode/index.tsx @@ -23,7 +23,6 @@ interface IStyleData { export interface INodeData { name: string; style: IStyleData; - handleOriantation: "horizontal" | "vertical"; error: boolean; } @@ -75,15 +74,22 @@ const CustomNode = memo( ); const { targetHandlePosition, sourceHandlePosition } = useMemo(() => { - return extendedData?.handleOriantation === "horizontal" - ? { - targetHandlePosition: Position.Left, - sourceHandlePosition: Position.Right, - } - : { - targetHandlePosition: Position.Top, - sourceHandlePosition: Position.Bottom, - }; + // TODO: deal with orientation + + // return extendedData?.handleOriantation === "horizontal" + // ? { + // targetHandlePosition: Position.Left, + // sourceHandlePosition: Position.Right, + // } + // : { + // targetHandlePosition: Position.Top, + // sourceHandlePosition: Position.Bottom, + // }; + + return { + targetHandlePosition: Position.Left, + sourceHandlePosition: Position.Right, + }; }, [extendedData]); const { useIcon, iconId, iconClass, iconStyle } = useMemo(() => { @@ -131,10 +137,6 @@ const CustomNode = memo( }; if (extendedData?.style.hasOwnProperty("nodeStyle")) { - console.log( - "extendedData.style.nodeStyle", - extendedData.style.nodeStyle, - ); style = Object.assign(style, extendedData.style.nodeStyle); } @@ -150,7 +152,6 @@ const CustomNode = memo( return (
{ setHovered(true); }} diff --git a/frontend/src/components/ReactFlow/index.tsx b/frontend/src/components/ReactFlow/index.tsx index a3dd0630..06b1956d 100644 --- a/frontend/src/components/ReactFlow/index.tsx +++ b/frontend/src/components/ReactFlow/index.tsx @@ -1,8 +1,18 @@ import CustomEdge from "components/CustomEdge"; import CustomNode, { type INodeData } from "components/CustomNode"; +import Elk from "elkjs"; import theme from "providers/theme.config"; -import React, { useCallback, type DragEvent, useState, useRef } from "react"; +import React, { + useCallback, + type DragEvent, + useState, + useRef, + forwardRef, + useImperativeHandle, + type ForwardedRef, +} from "react"; import ReactFlow, { + MiniMap, addEdge, Background, Controls, @@ -61,119 +71,204 @@ type Props = onInit: OnInit; onNodeDoubleClick?: NodeMouseHandler; }; +export interface WorkflowPanelRef { + nodes: Node[]; + edges: Edge[]; + setNodes: React.Dispatch< + React.SetStateAction>> + >; + setEdges: React.Dispatch>>>; + autoLayout: () => void; +} +const WorkflowPanel = forwardRef( + (props: Props, ref: ForwardedRef) => { + const reactFlowWrapper = useRef(null); + const [instance, setInstance] = useState(null); + const [nodes, setNodes, onNodesChange] = useNodesState([]); + const [edges, setEdges, onEdgesChange] = useEdgesState([]); -const WorkflowPanel: React.FC = (props: Props) => { - const reactFlowWrapper = useRef(null); - const [instance, setInstance] = useState(null); - const [nodes, setNodes, onNodesChange] = useNodesState([]); - const [edges, setEdges, onEdgesChange] = useEdgesState([]); - - const onInit = useCallback(async (instance: ReactFlowInstance) => { - setInstance(instance); - const result = props.onInit(instance); - if (result instanceof Promise) { - result - .then(({ nodes, edges }) => { - setNodes(nodes); - setEdges(edges); - }) - .catch((error) => { - console.error("Error from Promise-returning function:", error); - }); - } else { - const { nodes, edges } = result; - setNodes(nodes); - setEdges(edges); - } - }, []); - - const onNodesDelete = useCallback( - props.editable ? props.onNodesDelete : () => {}, - [], - ); - - const onEdgesDelete = useCallback( - props.editable ? props.onEdgesDelete : () => {}, - [], - ); - - const onNodeDoubleClick = useCallback( - props.editable && props.onNodeDoubleClick - ? props.onNodeDoubleClick - : () => {}, - [], - ); - - const onDragOver = (event: DragEvent) => { - event.preventDefault(); - event.dataTransfer.dropEffect = "move"; - }; - - const onDrop = useCallback( - async (event: DragEvent) => { - event.preventDefault(); - if (reactFlowWrapper?.current === null) { - return; + const onInit = useCallback(async (instance: ReactFlowInstance) => { + setInstance(instance); + const result = props.onInit(instance); + if (result instanceof Promise) { + result + .then(({ nodes, edges }) => { + setNodes(nodes); + setEdges(edges); + }) + .catch((error) => { + console.error("Error from Promise-returning function:", error); + }); + } else { + const { nodes, edges } = result; + setNodes(nodes); + setEdges(edges); } - const reactFlowBounds = reactFlowWrapper.current.getBoundingClientRect(); - // @ts-expect-error: Unreachable code error - const position = instance.project({ - x: event.clientX - reactFlowBounds.left, - y: event.clientY - reactFlowBounds.top, - }); - - if (props.editable) { - const result = props.onDrop(event, position); - if (result instanceof Promise) { - result - .then((node) => { - setNodes((ns: Node[]) => ns.concat(node)); - }) - .catch((error) => { - console.error("Error from Promise-returning function:", error); - }); - } else { - const node = result; - setNodes((ns: Node[]) => ns.concat(node)); + }, []); + + const onNodesDelete = useCallback( + props.editable ? props.onNodesDelete : () => {}, + [], + ); + + const onEdgesDelete = useCallback( + props.editable ? props.onEdgesDelete : () => {}, + [], + ); + + const onNodeDoubleClick = useCallback( + props.editable && props.onNodeDoubleClick + ? props.onNodeDoubleClick + : () => {}, + [], + ); + + const onDragOver = (event: DragEvent) => { + event.preventDefault(); + event.dataTransfer.dropEffect = "move"; + }; + + const onDrop = useCallback( + async (event: DragEvent) => { + event.preventDefault(); + if (reactFlowWrapper?.current === null) { + return; + } + const reactFlowBounds = + reactFlowWrapper.current.getBoundingClientRect(); + // @ts-expect-error: Unreachable code error + const position = instance.project({ + x: event.clientX - reactFlowBounds.left, + y: event.clientY - reactFlowBounds.top, + }); + + if (props.editable) { + const result = props.onDrop(event, position); + if (result instanceof Promise) { + result + .then((node) => { + setNodes((ns: Node[]) => ns.concat(node)); + }) + .catch((error) => { + console.error("Error from Promise-returning function:", error); + }); + } else { + const node = result; + setNodes((ns: Node[]) => ns.concat(node)); + } } + }, + [instance, setNodes], + ); + + const onConnect = useCallback((connection: Connection) => { + setEdges((prevEdges: Edge[]) => addEdge(connection, prevEdges)); + }, []); + + const autoLayout = useCallback(async () => { + const elkGraph = { + id: "root", + children: nodes.map((node) => ({ + id: node.id, + width: 230, + height: 140, + })), + edges: edges.map((edge) => ({ + id: edge.id, + sources: [edge.source], + targets: [edge.target], + })), + }; + + const elk = new Elk(); + + try { + const elkLayout = await elk.layout(elkGraph); + + console.log(elkLayout); + + if (elkLayout?.children && elkLayout.edges) { + const updatedNodes = elkLayout.children.map((elkNode) => { + const node = nodes.find((node) => node.id === elkNode.id); + if ( + node && + elkNode.x !== undefined && + elkNode.width !== undefined && + elkNode.y !== undefined && + elkNode.height !== undefined + ) { + return { + ...node, + position: { + x: elkNode.x - elkNode.width / 2, + y: elkNode.y - elkNode.height / 2, + }, + }; + } + return node; + }); + + const updatedEdges = elkLayout.edges.map((elkEdge) => ({ + ...edges.find((edge) => edge.id === elkEdge.id), + sourcePosition: "right", + targetPosition: "left", + })); + + setNodes(updatedNodes as Node[]); + setEdges(updatedEdges as Edge[]); + } + } catch (error) { + console.error("Error during layout:", error); } - }, - [instance, setNodes], - ); - - const onConnect = useCallback((connection: Connection) => { - setEdges((prevEdges: Edge[]) => addEdge(connection, prevEdges)); - }, []); - - return ( - -
- { + return { + edges, + nodes, + setEdges, + setNodes, + autoLayout, + }; + }, + [edges, nodes, setEdges, setNodes], + ); + + return ( + +
- - - -
-
- ); -}; + + + + + +
+
+ ); + }, +); + +WorkflowPanel.displayName = "WorkflowPanel"; export default WorkflowPanel; diff --git a/frontend/src/features/workflowEditor/components/DrawerMenu/sidebarAddNode.tsx b/frontend/src/features/workflowEditor/components/DrawerMenu/sidebarAddNode.tsx index d98e21f0..9cb7be94 100644 --- a/frontend/src/features/workflowEditor/components/DrawerMenu/sidebarAddNode.tsx +++ b/frontend/src/features/workflowEditor/components/DrawerMenu/sidebarAddNode.tsx @@ -10,7 +10,7 @@ import { Typography, } from "@mui/material"; import { useWorkflowsEditor } from "features/workflowEditor/context"; -import { type FC, useState } from "react"; +import { type FC, useState, useCallback } from "react"; import PiecesSidebarNode from "./sidebarNode"; @@ -20,17 +20,17 @@ import PiecesSidebarNode from "./sidebarNode"; * @todo improve loading/error/empty states */ const SidebarAddNode: FC = () => { - const { - repositories, - repositoriesLoading, - repositoryPieces, - nodeDirection, - toggleNodeDirection, - } = useWorkflowsEditor(); - + const { repositories, repositoriesLoading, repositoryPieces } = + useWorkflowsEditor(); + const [nodeDirection, setNodeDirection] = useState<"horizontal" | "vertical">( + "horizontal", + ); const [piecesMap, setPiecesMap] = useState>({}); const [expandedRepos, setExpandedRepos] = useState([]); + const toggleNodeDirection = useCallback(() => { + setNodeDirection((nd) => (nd === "horizontal" ? "vertical" : "horizontal")); + }, []); /** controls if an accordion is loading Pieces */ const [loadingPieces, setLoadingPieces] = useState(false); diff --git a/frontend/src/features/workflowEditor/components/WorkflowEditor.tsx b/frontend/src/features/workflowEditor/components/WorkflowEditor.tsx index 83e9a9fb..339679bd 100644 --- a/frontend/src/features/workflowEditor/components/WorkflowEditor.tsx +++ b/frontend/src/features/workflowEditor/components/WorkflowEditor.tsx @@ -2,84 +2,139 @@ import { Settings as SettingsSuggestIcon } from "@mui/icons-material"; import ClearIcon from "@mui/icons-material/Clear"; import DownloadIcon from "@mui/icons-material/Download"; import SaveIcon from "@mui/icons-material/Save"; -import { Button, Grid, Paper, Backdrop, CircularProgress } from "@mui/material"; +import { Button, Grid, Paper } from "@mui/material"; import { AxiosError } from "axios"; +import { type INodeData } from "components/CustomNode"; +import Loading from "components/Loading"; +import WorkflowPanel, { type WorkflowPanelRef } from "components/ReactFlow"; import { useWorkspaces } from "context/workspaces"; import { useWorkflowsEditor } from "features/workflowEditor/context"; -import { useCallback, useState } from "react"; +import { type DragEvent, useCallback, useRef, useState } from "react"; import { toast } from "react-toastify"; +import { type Edge, type Node, type XYPosition } from "reactflow"; import { yupResolver } from "utils"; +import { useAutoSave } from "utils/useAutoSave"; +import { v4 as uuidv4 } from "uuid"; import * as yup from "yup"; +import { type IWorkflowPieceData, storageAccessModes } from "../context/types"; +import { containerResourcesSchema } from "../schemas/containerResourcesSchemas"; +import { extractDefaultInputValues, extractDefaultValues } from "../utils"; + import { PermanentDrawerRightWorkflows } from "./DrawerMenu"; +import SidebarPieceForm from "./SidebarForm"; import { ContainerResourceFormSchema } from "./SidebarForm/ContainerResourceForm"; import { createInputsSchemaValidation } from "./SidebarForm/PieceForm/validation"; import { storageFormSchema } from "./SidebarForm/StorageForm"; import SidebarSettingsForm, { WorkflowSettingsFormSchema, } from "./SidebarSettingsForm"; -import WorkflowEditorPanelComponent from "./WorkflowEditorPanel"; + /** * Create workflow tab // TODO refactor/simplify inner files // TODO handle runtime errors // TODO make it look good - // TODO remove all '// @ts-ignore: Unreachable code error"' */ +const getId = (module_name: string) => { + return `${module_name}_${uuidv4()}`; +}; + export const WorkflowsEditorComponent: React.FC = () => { - const [drawerState, setDrawerState] = useState(false); - const [backdropIsOpen, setBackdropIsOpen] = useState(false); + const workflowPanelRef = useRef(null); + const [sidebarSettingsDrawer, setSidebarSettingsDrawer] = useState(false); + const [sidebarPieceDrawer, setSidebarPieceDrawer] = useState(false); + const [formId, setFormId] = useState(""); + const [formTitle, setFormTitle] = useState(""); + const [formSchema, setFormSchema] = useState({}); const [menuOpen, setMenuOpen] = useState(false); + const [loading, setBackdropIsOpen] = useState(false); + const { workspace } = useWorkspaces(); + const saveDataToLocalForage = useCallback(async () => { + if (workflowPanelRef?.current) { + await Promise.allSettled([ + setWorkflowEdges(workflowPanelRef.current.edges ?? []), + setWorkflowNodes(workflowPanelRef.current.nodes ?? []), + ]); + } + }, [workflowPanelRef.current]); + + useAutoSave(saveDataToLocalForage, 3000); + const { clearForageData, workflowsEditorBodyFromFlowchart, fetchWorkflowForage, - setNodes, - setEdges, handleCreateWorkflow, + fetchForagePieceById, + fetchForageWorkflowNodes, + fetchForageWorkflowEdges, + setForageWorkflowPieces, + getForageWorkflowPieces, + removeForageWorkflowPiecesById, + removeForageWorkflowPieceDataById, + fetchWorkflowPieceById, + setForageWorkflowPiecesData, + clearDownstreamDataById, + setWorkflowEdges, + setWorkflowNodes, } = useWorkflowsEditor(); const validateWorkflowSettings = useCallback(async (payload: any) => { const resolver = yupResolver(WorkflowSettingsFormSchema); const validatedData = await resolver(payload.workflowSettingsData); if (!Object.keys(validatedData.errors).length) { - setNodesWithErros([]); + // do something } else { throw new Error("Please review your workflow settings."); } }, []); - const validateWorkflowPiecesData = useCallback(async (payload: any) => { - const validationSchema = yup.object().shape( - Object.entries(payload.workflowPieces).reduce((acc, [key, value]) => { - return { - [key]: yup.object({ - storage: storageFormSchema, - containerResources: ContainerResourceFormSchema, - inputs: createInputsSchemaValidation((value as any).input_schema), - }), - ...acc, - }; - }, {}), - ) as any; + const validateWorkflowPiecesData = useCallback( + async (payload: any) => { + const validationSchema = yup.object().shape( + Object.entries(payload.workflowPieces).reduce((acc, [key, value]) => { + return { + [key]: yup.object({ + storage: storageFormSchema, + containerResources: ContainerResourceFormSchema, + inputs: createInputsSchemaValidation((value as any).input_schema), + }), + ...acc, + }; + }, {}), + ) as any; - const resolver = yupResolver(validationSchema); + const resolver = yupResolver(validationSchema); - const validatedData = await resolver(payload.workflowPiecesData); + const validatedData = await resolver(payload.workflowPiecesData); - if (!Object.keys(validatedData.errors).length) { - setNodesWithErros([]); - } else { - const nodeIds = Object.keys(validatedData.errors); - setNodesWithErros(nodeIds); + if (!Object.keys(validatedData.errors).length) { + workflowPanelRef?.current?.setNodes((nodes) => + nodes.map((n) => { + n = { ...n, data: { ...n.data, error: false } }; + return n; + }), + ); + } else { + const nodeIds = Object.keys(validatedData.errors); + workflowPanelRef?.current?.setNodes((nodes) => [ + ...nodes.map((n) => { + if (nodeIds.includes(n.id)) { + n = { ...n, data: { ...n.data, error: true } }; + } - throw new Error("Please review the errors on your workflow."); - } - }, []); + return n; + }), + ]); - const [nodesWithErros, setNodesWithErros] = useState([]); + throw new Error("Please review the errors on your workflow."); + } + }, + [workflowPanelRef], + ); const handleSaveWorkflow = useCallback(async () => { try { @@ -118,114 +173,228 @@ export const WorkflowsEditorComponent: React.FC = () => { workspace?.id, ]); - // @ts-expect-error: Unreachable code error - const toggleDrawer = (open) => (event) => { + const handleClear = useCallback(async () => { + await clearForageData(); + workflowPanelRef.current?.setEdges([]); + workflowPanelRef.current?.setNodes([]); + }, [clearForageData]); + + const onNodesDelete = useCallback( + async (nodes: any) => { + for (const node of nodes) { + await removeForageWorkflowPiecesById(node.id); + await removeForageWorkflowPieceDataById(node.id); + } + }, + [removeForageWorkflowPieceDataById, removeForageWorkflowPiecesById], + ); + + const onEdgesDelete = useCallback( + async (edges: Edge[]) => { + for (const edge of edges) { + await clearDownstreamDataById(edge.source); + } + }, + [clearDownstreamDataById], + ); + + // Node double click open drawer with forms + const onNodeDoubleClick = useCallback( + async (_e: any, node: Node) => { + const pieceNode = await fetchWorkflowPieceById(node.id); + setFormSchema(pieceNode?.input_schema); + setFormId(node.id); + setFormTitle(() => { + return pieceNode?.name ? pieceNode.name : ""; + }); + setSidebarPieceDrawer(true); + }, + [fetchWorkflowPieceById], + ); + + const onLoad = useCallback(async () => { + // // Fetch old state from forage to avoid loosing flowchart when refreshing/leaving page + const workflowNodes = await fetchForageWorkflowNodes(); + const workflowEdges = await fetchForageWorkflowEdges(); + + return { nodes: workflowNodes, edges: workflowEdges }; + }, [fetchForageWorkflowNodes, fetchForageWorkflowEdges]); + + const onDrop = useCallback( + async (event: DragEvent, position: XYPosition) => { + event.preventDefault(); + const nodeData = event.dataTransfer.getData("application/reactflow"); + const { ...data } = JSON.parse(nodeData); + + const newNodeData: INodeData = { + name: data.name, + style: data.style, + error: false, + }; + + const newNode = { + id: getId(data.id), + type: "CustomNode", + position, + data: newNodeData, + }; + + const piece = await fetchForagePieceById(data.id); + const defaultInputs = extractDefaultInputValues( + piece as unknown as Piece, + ); + const defaultContainerResources = extractDefaultValues( + containerResourcesSchema as any, + ); + + const currentWorkflowPieces = await getForageWorkflowPieces(); + const newWorkflowPieces = { + ...currentWorkflowPieces, + [newNode.id]: piece, + }; + await setForageWorkflowPieces(newWorkflowPieces); + + const defaultWorkflowPieceData: IWorkflowPieceData = { + storage: { storageAccessMode: storageAccessModes.ReadWrite }, + containerResources: defaultContainerResources, + inputs: defaultInputs, + }; + + await setForageWorkflowPiecesData(newNode.id, defaultWorkflowPieceData); + return newNode; + }, + [ + fetchForagePieceById, + setForageWorkflowPieces, + getForageWorkflowPieces, + setForageWorkflowPiecesData, + ], + ); + + // Left drawers controls + const toggleSidebarPieceDrawer = (open: boolean) => (event: any) => { if ( event.type === "keydown" && (event.key === "Tab" || event.key === "Shift") ) { return; } - setDrawerState(open); + setSidebarPieceDrawer(open); }; - // Open Config Workflow Form - const handleConfigWorkflow = useCallback(() => { - setDrawerState(true); - }, []); - - const handleClear = useCallback(async () => { - setNodes([]); - setEdges([]); - await clearForageData(); - }, [setNodes, setEdges, clearForageData]); + const toggleSidebarSettingsDrawer = (open: boolean) => (event: any) => { + if ( + event.type === "keydown" && + (event.key === "Tab" || event.key === "Shift") + ) { + return; + } + console.log("here"); + setSidebarSettingsDrawer(open); + }; return ( <> -
- - - - + {loading && } + + - - - - - - - - - - - - - + + + + + + + + + + + + + + - - - + + + + + { setMenuOpen(!menuOpen); }} /> - -
+ + + ); }; diff --git a/frontend/src/features/workflowEditor/components/WorkflowEditorPanel/index.tsx b/frontend/src/features/workflowEditor/components/WorkflowEditorPanel/index.tsx deleted file mode 100644 index 95fe6d10..00000000 --- a/frontend/src/features/workflowEditor/components/WorkflowEditorPanel/index.tsx +++ /dev/null @@ -1,224 +0,0 @@ -import { type INodeData } from "components/CustomNode"; -import WorkflowPanel from "components/ReactFlow"; -import { useWorkflowsEditor } from "features/workflowEditor/context"; -import { - type IWorkflowPieceData, - storageAccessModes, -} from "features/workflowEditor/context/types"; -import { containerResourcesSchema } from "features/workflowEditor/schemas/containerResourcesSchemas"; -import { - extractDefaultInputValues, - extractDefaultValues, -} from "features/workflowEditor/utils"; -import React, { type DragEvent, useCallback, useEffect, useState } from "react"; -import { type XYPosition, type Edge } from "reactflow"; -import { v4 as uuidv4 } from "uuid"; - -import SidebarForm from "../SidebarForm"; -/** - * @todo When change the workspace should we clear the forage ? - * @todo Solve any types - */ - -// @ts-expect-error: Unreachable code error -const getId = (module_name) => { - return `${module_name}_${uuidv4()}`; -}; - -interface Props { - nodesWithErros: string[]; -} - -const WorkflowEditorPanelComponent = ({ nodesWithErros }: Props) => { - const [formSchema, setFormSchema] = useState({}); - const [formId, setFormId] = useState(""); - const [formTitle, setFormTitle] = useState(""); - const [drawerState, setDrawerState] = useState(false); - const [reactFlowInstance, setReactFlowInstance] = useState(null); - - const { - nodeDirection, - setEdges, - setNodes, - fetchForagePieceById, - fetchForageWorkflowNodes, - fetchForageWorkflowEdges, - setForageWorkflowPieces, - getForageWorkflowPieces, - removeForageWorkflowPiecesById, - removeForageWorkflowPieceDataById, - fetchWorkflowPieceById, - setForageWorkflowPiecesData, - clearDownstreamDataById, - } = useWorkflowsEditor(); - - // Removing flowchart elements - const onNodesDelete = useCallback( - async (nodes: any) => { - for (const node of nodes) { - await removeForageWorkflowPiecesById(node.id); - await removeForageWorkflowPieceDataById(node.id); - } - }, - [removeForageWorkflowPieceDataById, removeForageWorkflowPiecesById], - ); - - const onEdgesDelete = useCallback( - async (edges: Edge[]) => { - for (const edge of edges) { - await clearDownstreamDataById(edge.source); - } - }, - [clearDownstreamDataById], - ); - - // Node double click open drawer with forms - const onNodeDoubleClick = useCallback( - async (event: any, node: any) => { - const pieceNode = await fetchWorkflowPieceById(node.id); - setFormSchema(pieceNode?.input_schema); - setFormId(node.id); - setFormTitle(() => { - return pieceNode?.name ? pieceNode?.name : ""; - }); - setDrawerState(true); - }, - [fetchWorkflowPieceById], - ); - - const onLoad = useCallback( - async (_reactFlowInstance: any) => { - setReactFlowInstance(_reactFlowInstance); - // // Fetch old state from forage to avoid loosing flowchart when refreshing/leaving page - const workflowNodes = await fetchForageWorkflowNodes(); - const workflowEdges = await fetchForageWorkflowEdges(); - - return { nodes: workflowNodes, edges: workflowEdges }; - }, - [setNodes, setEdges, fetchForageWorkflowNodes, fetchForageWorkflowEdges], - ); - - const onDrop = useCallback( - async (event: DragEvent, position: XYPosition) => { - event.preventDefault(); - const nodeData = event.dataTransfer.getData("application/reactflow"); - const { ...data } = JSON.parse(nodeData); - - const newNodeData: INodeData = { - name: data.name, - style: data.style, - handleOriantation: nodeDirection, - error: false, - }; - - const newNode = { - id: getId(data.id), - type: "CustomNode", - position, - data: newNodeData, - }; - - const piece = await fetchForagePieceById(data.id); - const defaultInputs = extractDefaultInputValues( - piece as unknown as Piece, - ); - const defaultContainerResources = extractDefaultValues( - containerResourcesSchema as any, - ); - - const currentWorkflowPieces = await getForageWorkflowPieces(); - const newWorkflowPieces = { - ...currentWorkflowPieces, - [newNode.id]: piece, - }; - await setForageWorkflowPieces(newWorkflowPieces); - - const defaultWorkflowPieceData: IWorkflowPieceData = { - storage: { storageAccessMode: storageAccessModes.ReadWrite }, - containerResources: defaultContainerResources, - inputs: defaultInputs, - }; - - await setForageWorkflowPiecesData(newNode.id, defaultWorkflowPieceData); - return newNode; - }, - [ - fetchForagePieceById, - nodeDirection, - reactFlowInstance, - setNodes, - setForageWorkflowPieces, - getForageWorkflowPieces, - setForageWorkflowPiecesData, - ], - ); - - // Left drawer controls - // @ts-expect-error: Unreachable code error - const toggleDrawer = (open) => (event) => { - if ( - event.type === "keydown" && - (event.key === "Tab" || event.key === "Shift") - ) { - return; - } - setDrawerState(open); - }; - - const setNodeErrors = useCallback( - (nodeIds: string[]) => { - setNodes((nds) => - nds.map((n) => { - if (nodeIds.includes(n.id)) { - n = { - ...n, - data: { - ...n.data, - error: true, - }, - }; - } else { - n = { - ...n, - data: { - ...n.data, - error: false, - }, - }; - } - return n; - }), - ); - }, - [setNodes], - ); - - useEffect(() => { - setNodeErrors(nodesWithErros); - }, [nodesWithErros, setNodeErrors]); - - return ( - <> -
- -
- - - - ); -}; - -export default WorkflowEditorPanelComponent; diff --git a/frontend/src/features/workflowEditor/context/index.tsx b/frontend/src/features/workflowEditor/context/index.tsx index b9767278..4844df27 100644 --- a/frontend/src/features/workflowEditor/context/index.tsx +++ b/frontend/src/features/workflowEditor/context/index.tsx @@ -1,6 +1,5 @@ import PiecesProvider from "./pieces"; -import WorkflowsEdgesProvider from "./workflowEdges"; -import WorkflowsNodesProvider from "./workflowNodes"; +import ReactWorkflowPersistenceProvider from "./reactWorkflowPersistence"; import WorkflowPiecesProvider from "./workflowPieces"; import WorkflowPiecesDataProvider from "./workflowPiecesData"; import WorkflowsEditorProviderItem, { @@ -16,17 +15,15 @@ const WorkflowsEditorProviderWrapper: React.FC<{ return ( - - - - - - {children} - - - - - + + + + + {children} + + + + ); diff --git a/frontend/src/features/workflowEditor/context/reactWorkflowPersistence.tsx b/frontend/src/features/workflowEditor/context/reactWorkflowPersistence.tsx new file mode 100644 index 00000000..3f12d1ba --- /dev/null +++ b/frontend/src/features/workflowEditor/context/reactWorkflowPersistence.tsx @@ -0,0 +1,65 @@ +import { type IWorkflowElement } from "features/workflows/types"; +import React, { useCallback } from "react"; +import { type Node, type Edge } from "reactflow"; +import localForage from "services/config/localForage.config"; +import { createCustomContext } from "utils"; + +export interface IReactWorkflowPersistenceContext { + setWorkflowEdges: (edges: Edge[]) => Promise; + setWorkflowNodes: (edges: Node[]) => Promise; + fetchForageWorkflowEdges: () => Promise; + fetchForageWorkflowNodes: () => Promise; + clearReactWorkflowPersistence: () => Promise; +} + +export const [ReactWorkflowPersistenceContext, useReactWorkflowPersistence] = + createCustomContext( + "ReactWorkflowPersistence Context", + ); + +const ReactWorkflowPersistenceProvider: React.FC<{ + children: React.ReactNode; +}> = ({ children }) => { + const setWorkflowEdges = useCallback(async (edges: Edge[]) => { + await localForage.setItem("workflowEdges", edges); + }, []); + const setWorkflowNodes = useCallback(async (nodes: Node[]) => { + await localForage.setItem("workflowNodes", nodes); + }, []); + + const fetchForageWorkflowEdges = useCallback(async () => { + let workflowEdges = await localForage.getItem("workflowEdges"); + if (!workflowEdges || workflowEdges.length === 0) { + workflowEdges = []; + } + return workflowEdges; + }, []); + const fetchForageWorkflowNodes = useCallback(async () => { + let workflowEdges = await localForage.getItem("workflowNodes"); + if (!workflowEdges || workflowEdges.length === 0) { + workflowEdges = []; + } + return workflowEdges; + }, []); + + const clearReactWorkflowPersistence = useCallback(async () => { + await localForage.setItem("workflowEdges", []); + await localForage.setItem("workflowNodes", []); + }, []); + + const value: IReactWorkflowPersistenceContext = { + setWorkflowEdges, + setWorkflowNodes, + fetchForageWorkflowEdges, + fetchForageWorkflowNodes, + clearReactWorkflowPersistence, + }; + + return ( + + {children} + + ); +}; + +export default ReactWorkflowPersistenceProvider; diff --git a/frontend/src/features/workflowEditor/context/workflowEdges.tsx b/frontend/src/features/workflowEditor/context/workflowEdges.tsx deleted file mode 100644 index 19ea543d..00000000 --- a/frontend/src/features/workflowEditor/context/workflowEdges.tsx +++ /dev/null @@ -1,63 +0,0 @@ -import React, { useCallback, useEffect, useState } from "react"; -import { type Edge } from "reactflow"; -import localForage from "services/config/localForage.config"; -import { createCustomContext } from "utils"; - -export interface IWorkflowsEdgesContext { - edges: Edge[]; - setEdges: React.Dispatch>; - fetchForageWorkflowEdges: () => Promise; -} - -export const [WorkflowsEdgesContext, useWorkflowsEdges] = - createCustomContext("WorkflowsEdges Context"); - -const WorkflowsEdgesProvider: React.FC<{ children: React.ReactNode }> = ({ - children, -}) => { - const [edges, setEdges] = useState([]); - const [loadingEdges, setLoadingEdges] = useState(true); - - const setForageWorkflowEdges = useCallback(async (edges: Edge[]) => { - await localForage.setItem("workflowEdges", edges); - }, []); - - const fetchForageWorkflowEdges = useCallback(async () => { - let workflowEdges = await localForage.getItem("workflowEdges"); - if (!workflowEdges || workflowEdges.length === 0) { - workflowEdges = []; - } - return workflowEdges; - }, []); - - useEffect(() => { - void (async () => { - const forageEdges = await fetchForageWorkflowEdges(); - await setForageWorkflowEdges(forageEdges); - setLoadingEdges(false); - })(); - }, []); - - useEffect(() => { - void (async () => { - if (loadingEdges) { - return; - } - await setForageWorkflowEdges(edges); - })(); - }, [edges, setForageWorkflowEdges, loadingEdges]); - - const value: IWorkflowsEdgesContext = { - edges, - fetchForageWorkflowEdges: async () => await fetchForageWorkflowEdges(), - setEdges, - }; - - return ( - - {children} - - ); -}; - -export default WorkflowsEdgesProvider; diff --git a/frontend/src/features/workflowEditor/context/workflowNodes.tsx b/frontend/src/features/workflowEditor/context/workflowNodes.tsx deleted file mode 100644 index e027e973..00000000 --- a/frontend/src/features/workflowEditor/context/workflowNodes.tsx +++ /dev/null @@ -1,79 +0,0 @@ -import { type IWorkflowElement } from "features/workflows/types"; -import React, { useCallback, useEffect, useState } from "react"; -import { type Node } from "reactflow"; -import localForage from "services/config/localForage.config"; -import { createCustomContext } from "utils"; - -export interface IWorkflowsNodesContext { - nodes: IWorkflowElement[] | Node[]; - setNodes: React.Dispatch>; - fetchForageWorkflowNodes: () => Promise; - nodeDirection: "horizontal" | "vertical"; - toggleNodeDirection: () => void; -} - -export const [WorkflowsNodesContext, useWorkflowsNodes] = - createCustomContext("WorkflowsNodes Context"); - -const WorkflowsNodesProvider: React.FC<{ children: React.ReactNode }> = ({ - children, -}) => { - const [nodeDirection, setNodeDirection] = useState<"horizontal" | "vertical">( - "horizontal", - ); - const [nodes, setNodes] = useState([]); - const [loadingNodes, setLoadingNodes] = useState(true); - - const setForageWorkflowNodes = useCallback( - async (nodes: IWorkflowElement[]) => { - await localForage.setItem("workflowNodes", nodes); - }, - [], - ); - - const fetchForageWorkflowNodes = useCallback(async () => { - let workflowNodes = await localForage.getItem("workflowNodes"); - if (!workflowNodes || workflowNodes.length === 0) { - workflowNodes = []; - } - return workflowNodes; - }, []); - - useEffect(() => { - void (async () => { - const forageNodes = await fetchForageWorkflowNodes(); - await setForageWorkflowNodes(forageNodes); - setLoadingNodes(false); - })(); - }, []); - - // Update nodes in forage if nodes array is updated - useEffect(() => { - void (async () => { - if (loadingNodes) { - return; - } - await setForageWorkflowNodes(nodes); - })(); - }, [nodes, setForageWorkflowNodes, loadingNodes]); - - const value = { - nodes, - setNodes, - fetchForageWorkflowNodes: async () => await fetchForageWorkflowNodes(), - nodeDirection, - toggleNodeDirection: () => { - setNodeDirection((current: any) => - current === "vertical" ? "horizontal" : "vertical", - ); - }, - }; - - return ( - - {children} - - ); -}; - -export default WorkflowsNodesProvider; diff --git a/frontend/src/features/workflowEditor/context/workflowsEditor.tsx b/frontend/src/features/workflowEditor/context/workflowsEditor.tsx index d929d142..713fb351 100644 --- a/frontend/src/features/workflowEditor/context/workflowsEditor.tsx +++ b/frontend/src/features/workflowEditor/context/workflowsEditor.tsx @@ -8,15 +8,11 @@ import React, { type FC, useCallback } from "react"; import { createCustomContext, generateTaskName, getIdSlice } from "utils"; import { usesPieces, type IPiecesContext } from "./pieces"; -import { type CreateWorkflowRequest, type TasksDataModel } from "./types"; -import { - useWorkflowsEdges, - type IWorkflowsEdgesContext, -} from "./workflowEdges"; import { - useWorkflowsNodes, - type IWorkflowsNodesContext, -} from "./workflowNodes"; + useReactWorkflowPersistence, + type IReactWorkflowPersistenceContext, +} from "./reactWorkflowPersistence"; +import { type CreateWorkflowRequest, type TasksDataModel } from "./types"; import { useWorkflowPiece, type IWorkflowPieceContext } from "./workflowPieces"; import { useWorkflowPiecesData, @@ -29,9 +25,8 @@ import { interface IWorkflowsEditorContext extends IPiecesContext, - IWorkflowsEdgesContext, + IReactWorkflowPersistenceContext, IWorkflowSettingsContext, - IWorkflowsNodesContext, IWorkflowPieceContext, IWorkflowPiecesDataContext { fetchWorkflowForage: () => any; // TODO add type @@ -62,15 +57,13 @@ const WorkflowsEditorProvider: FC<{ children?: React.ReactNode }> = ({ handleSearch, } = usesPieces(); - const { edges, fetchForageWorkflowEdges, setEdges } = useWorkflowsEdges(); - const { - nodes, - nodeDirection, + setWorkflowEdges, + setWorkflowNodes, + fetchForageWorkflowEdges, fetchForageWorkflowNodes, - setNodes, - toggleNodeDirection, - } = useWorkflowsNodes(); + clearReactWorkflowPersistence, + } = useReactWorkflowPersistence(); const { setForageWorkflowPieces, @@ -257,11 +250,13 @@ const WorkflowsEditorProvider: FC<{ children?: React.ReactNode }> = ({ const clearForageData = useCallback(async () => { await Promise.allSettled([ + clearReactWorkflowPersistence(), clearForageWorkflowPieces(), clearForageWorkflowPiecesData(), clearWorkflowSettingsData(), ]); }, [ + clearReactWorkflowPersistence, clearForageWorkflowPieces, clearForageWorkflowPiecesData, clearWorkflowSettingsData, @@ -269,44 +264,42 @@ const WorkflowsEditorProvider: FC<{ children?: React.ReactNode }> = ({ const value: IWorkflowsEditorContext = { repositories, - repositoriesError: !!repositoriesError, - repositoriesLoading, repositoryPieces, - search, - edges, - setEdges, - nodes, - setNodes, - handleSearch, + repositoriesError, + repositoriesLoading, fetchRepoById, fetchForagePieceById, - handleCreateWorkflow, + search, + handleSearch, + + setWorkflowEdges, + setWorkflowNodes, fetchForageWorkflowEdges, fetchForageWorkflowNodes, - fetchWorkflowForage, - workflowsEditorBodyFromFlowchart, + clearReactWorkflowPersistence, - nodeDirection, setForageWorkflowPieces, + setForageWorkflowPiecesOutputSchema, + fetchWorkflowPieceById, getForageWorkflowPieces, removeForageWorkflowPiecesById, - removeForageWorkflowPieceDataById, - fetchWorkflowPieceById, - - toggleNodeDirection, + clearForageWorkflowPieces, + setForageWorkflowPiecesData, fetchForageWorkflowPiecesData, fetchForageWorkflowPiecesDataById, - setForageWorkflowPiecesData, - setForageWorkflowPiecesOutputSchema, - - clearForageData, - clearDownstreamDataById, + removeForageWorkflowPieceDataById, clearForageWorkflowPiecesData, - clearForageWorkflowPieces, - fetchWorkflowSettingsData, + clearDownstreamDataById, + setWorkflowSettingsData, + fetchWorkflowSettingsData, clearWorkflowSettingsData, + + handleCreateWorkflow, + fetchWorkflowForage, + workflowsEditorBodyFromFlowchart, + clearForageData, }; return ( diff --git a/frontend/src/features/workflows/components/WorkflowsRunTasksFlowchart/index.tsx b/frontend/src/features/workflows/components/WorkflowsRunTasksFlowchart/index.tsx index f74856d8..707fa20b 100644 --- a/frontend/src/features/workflows/components/WorkflowsRunTasksFlowchart/index.tsx +++ b/frontend/src/features/workflows/components/WorkflowsRunTasksFlowchart/index.tsx @@ -190,19 +190,6 @@ export const WorkflowRunTaskFlowchart = () => { setSelectedNodeTaskData(taskData); setSelectedNodeId(node.id); - const updatedNodes = nodes.map((n) => { - if (n.id === node.id) { - n.data.style.nodeStyle.border = "3px solid #110d0e"; - n.data.style.nodeStyle.borderRadius = "3px"; - } else { - n.data.style.nodeStyle.border = "none"; - } - n.data = { - ...n.data, - }; - return n; - }); - setNodes(updatedNodes); // Fetch logs for the task and display them const taskTryNumber = taskData?.try_number; const taskId = taskData?.task_id; diff --git a/frontend/src/utils/useAutoSave.ts b/frontend/src/utils/useAutoSave.ts new file mode 100644 index 00000000..b32042d4 --- /dev/null +++ b/frontend/src/utils/useAutoSave.ts @@ -0,0 +1,18 @@ +import { useEffect } from "react"; + +type SaveFunction = (() => void) | (() => Promise); + +/** + * @param saveFunction this function will be called when the interval arrive, make sure to save your data in a properly location + * @param interval in milliseconds + */ +export const useAutoSave = (saveFunction: SaveFunction, interval: number) => { + useEffect(() => { + const intervalId = setInterval(() => { + void saveFunction(); + }, interval); + return () => { + clearInterval(intervalId); + }; + }, []); +}; diff --git a/frontend/yarn.lock b/frontend/yarn.lock index 3f2c1236..0515d987 100644 --- a/frontend/yarn.lock +++ b/frontend/yarn.lock @@ -5069,6 +5069,11 @@ electron-to-chromium@^1.4.477: resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.506.tgz#59f64a211102db4c3ebae2f39cc0e8e1b12b3a07" integrity sha512-xxGct4GPAKSRlrLBtJxJFYy74W11zX6PO9GyHgl/U+2s3Dp0ZEwAklDfNHXOWcvH7zWMpsmgbR0ggEuaYAVvHA== +elkjs@^0.8.2: + version "0.8.2" + resolved "https://registry.yarnpkg.com/elkjs/-/elkjs-0.8.2.tgz#c37763c5a3e24e042e318455e0147c912a7c248e" + integrity sha512-L6uRgvZTH+4OF5NE/MBbzQx/WYpru1xCBE9respNj6qznEewGUIfhzmm7horWWxbNO2M0WckQypGctR8lH79xQ== + emittery@^0.10.2: version "0.10.2" resolved "https://registry.yarnpkg.com/emittery/-/emittery-0.10.2.tgz#902eec8aedb8c41938c46e9385e9db7e03182933" @@ -11399,6 +11404,11 @@ web-namespaces@^2.0.0: resolved "https://registry.yarnpkg.com/web-namespaces/-/web-namespaces-2.0.1.tgz#1010ff7c650eccb2592cebeeaf9a1b253fd40692" integrity sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ== +web-worker@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/web-worker/-/web-worker-1.2.0.tgz#5d85a04a7fbc1e7db58f66595d7a3ac7c9c180da" + integrity sha512-PgF341avzqyx60neE9DD+XS26MMNMoUQRz9NOZwW32nPQrF6p77f1htcnjBSEV8BGMKZ16choqUG4hyI0Hx7mA== + webidl-conversions@^3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871" From 8f5dd801bf74fb89ed9ee042c2b5642df5f82ead Mon Sep 17 00:00:00 2001 From: luiz Date: Tue, 19 Sep 2023 19:14:03 +0200 Subject: [PATCH 256/328] install helms separately --- helm/domino/Chart.yaml | 10 +- .../templates/domino-rest-deployment.yml | 2 +- src/domino/cli/cli.py | 7 + src/domino/cli/utils/platform.py | 147 +++++++++++------- 4 files changed, 102 insertions(+), 64 deletions(-) diff --git a/helm/domino/Chart.yaml b/helm/domino/Chart.yaml index 9748904b..50d02039 100644 --- a/helm/domino/Chart.yaml +++ b/helm/domino/Chart.yaml @@ -7,8 +7,8 @@ appVersion: 0.1.5 home: https://github.com/Tauffer-Consulting/domino sources: - https://github.com/Tauffer-Consulting/domino -dependencies: - - name: airflow - version: 1.9.0 - repository: https://airflow.apache.org/ - condition: airflow.enabled +# dependencies: +# - name: airflow +# version: 1.9.0 +# repository: https://airflow.apache.org/ +# condition: airflow.enabled diff --git a/helm/domino/templates/domino-rest-deployment.yml b/helm/domino/templates/domino-rest-deployment.yml index 085128bf..2853de67 100644 --- a/helm/domino/templates/domino-rest-deployment.yml +++ b/helm/domino/templates/domino-rest-deployment.yml @@ -31,7 +31,7 @@ spec: env: # TODO use load balancer instead of service ip for airflow webserver ? - name: AIRFLOW_WEBSERVER_HOST - value: http://{{ .Release.Name }}-airflow-webserver:8080 + value: http://airflow-webserver:8080 - name: DOMINO_DEPLOY_MODE value: {{ .Values.rest.deployMode }} - name: DOMINO_DB_HOST diff --git a/src/domino/cli/cli.py b/src/domino/cli/cli.py index 1dc74b37..a4b574a9 100644 --- a/src/domino/cli/cli.py +++ b/src/domino/cli/cli.py @@ -153,6 +153,12 @@ def cli_create_platform(run_airflow, use_gpu): platform.create_platform(run_airflow, use_gpu) +@click.command() +def cli_destroy_platform(): + """Destroy Kind cluster.""" + platform.destroy_platform() + + @click.command() @click.option( "--d", @@ -198,6 +204,7 @@ def cli_platform(ctx): cli_platform.add_command(cli_prepare_platform, name="prepare") cli_platform.add_command(cli_create_platform, name="create") +cli_platform.add_command(cli_destroy_platform, name="destroy") cli_platform.add_command(cli_run_platform_compose, name="run-compose") diff --git a/src/domino/cli/utils/platform.py b/src/domino/cli/utils/platform.py index daeb9fac..d490d6ac 100644 --- a/src/domino/cli/utils/platform.py +++ b/src/domino/cli/utils/platform.py @@ -320,72 +320,89 @@ def create_platform(run_airflow: bool = True, use_gpu: bool = False) -> None: airflow_values_override_config = { **domino_values_override_config, - "airflow": { - "enabled": True if run_airflow else False, - "env": [ - { - "name": "DOMINO_DEPLOY_MODE", - "value": platform_config['kind']["DOMINO_DEPLOY_MODE"] - }, - ], - "images": { - "useDefaultImageForMigration": False, - "airflow": { - "repository": domino_airflow_image, - "tag": "latest", - "pullPolicy": "IfNotPresent" - } + # "airflow": { + # "enabled": True if run_airflow else False, + "env": [ + { + "name": "DOMINO_DEPLOY_MODE", + "value": platform_config['kind']["DOMINO_DEPLOY_MODE"] }, - "extraSecrets": { - "airflow-ssh-secret": { - "data": airflow_ssh_config_parsed - } + ], + "images": { + "useDefaultImageForMigration": False, + "airflow": { + "repository": domino_airflow_image, + "tag": "latest", + "pullPolicy": "IfNotPresent" + } + }, + "extraSecrets": { + "airflow-ssh-secret": { + "data": airflow_ssh_config_parsed + } + }, + "config": { + "api": { + "auth_backend": "airflow.api.auth.backend.basic_auth" }, - "dags": { - "gitSync": { - "enabled": True, - "wait": 60, - "repo": f"ssh://git@github.com/{platform_config['github']['DOMINO_GITHUB_WORKFLOWS_REPOSITORY']}.git", - "branch": "main", - "subPath": "workflows", - "sshKeySecret": "airflow-ssh-secret" - } + }, + "dags": { + "gitSync": { + "enabled": True, + "wait": 60, + "repo": f"ssh://git@github.com/{platform_config['github']['DOMINO_GITHUB_WORKFLOWS_REPOSITORY']}.git", + "branch": "main", + "subPath": "workflows", + "sshKeySecret": "airflow-ssh-secret" }, - **workers, - **scheduler, - } + }, + **workers, + **scheduler, + # } } # Write yaml to temp file and install domino airflow subprocess.run(["helm", "repo", "add", "domino", DOMINO_HELM_REPOSITORY]) subprocess.run(["helm", "repo", "add", "apache-airflow", "https://airflow.apache.org/"]) # ref: https://github.com/helm/helm/issues/8036 subprocess.run(["helm", "repo", "update"]) - with TemporaryDirectory() as tmp_dir: - console.print("Downloading Domino Helm chart...") - subprocess.run([ - "helm", - "pull", - DOMINO_HELM_PATH, - "--version", - DOMINO_HELM_VERSION, - "--untar", - "-d", - tmp_dir - ]) - if run_airflow: - console.print("Installing dependencies...") - subprocess.run(["helm", "dependency", "build"], cwd=f"{tmp_dir}/domino") - with NamedTemporaryFile(suffix='.yaml', mode="w") as fp: - yaml.dump(airflow_values_override_config, fp) - console.print('Installing Domino...') - commands = [ - "helm", "install", - "-f", str(fp.name), - "domino", - f"{tmp_dir}/domino", - # "/media/luiz/storage2/Github/domino/helm/domino" # TODO: remove this line, only for local dev - ] - subprocess.run(commands) + # with TemporaryDirectory() as tmp_dir: + # console.print("Downloading Domino Helm chart...") + # subprocess.run([ + # "helm", + # "pull", + # DOMINO_HELM_PATH, + # "--version", + # DOMINO_HELM_VERSION, + # "--untar", + # "-d", + # tmp_dir + # ]) + # if run_airflow: + # console.print("Installing dependencies...") + # subprocess.run(["helm", "dependency", "build"], cwd=f"{tmp_dir}/domino") + # with NamedTemporaryFile(suffix='.yaml', mode="w") as fp: + with open("values-airflow.yaml", "w") as fp: + yaml.dump(airflow_values_override_config, fp) + console.print('Installing Apache Airflow...') + commands = [ + "helm", "install", + "-f", "values-airflow.yaml", + "airflow", + "apache-airflow/airflow", + "--version", " 1.9.0", + # "/media/luiz/storage2/Github/domino/helm/domino/charts/airflow-1.9.0.tgz" # TODO: remove this line, only for local dev + ] + subprocess.run(commands) + console.print('Installing Domino...') + commands = [ + "helm", "install", + # "-f", str(fp.name), + "-f", "values-airflow.yaml", + "domino", + # f"{tmp_dir}/domino", + "/media/luiz/storage2/Github/domino/helm/domino" # TODO: remove this line, only for local dev + ] + subprocess.run(commands) # For each path create a pv and pvc if platform_config['kind']['DOMINO_DEPLOY_MODE'] == 'local-k8s-dev': @@ -549,13 +566,27 @@ def create_platform(run_airflow: bool = True, use_gpu: bool = False) -> None: console.print("") console.print("K8s resources created successfully!", style=f"bold {COLOR_PALETTE.get('success')}") - console.print("You can now access the Domino frontend at: http://localhost/") console.print("Domino's REST API: http://localhost/api/") console.print("Domino's REST API Swagger: http://localhost/api/docs") console.print("") +def destroy_platform() -> None: + # Delete Kind cluster + with open("config-domino-local.toml", "rb") as f: + platform_config = tomli.load(f) + cluster_name = platform_config["kind"]["DOMINO_KIND_CLUSTER_NAME"] + console.print(f"Removing Kind cluster - {cluster_name}...") + result = subprocess.run(["kind", "delete", "cluster", "--name", cluster_name], capture_output=True, text=True) + if result.returncode != 0: + error_message = result.stderr.strip() if result.stderr else result.stdout.strip() + raise Exception(f"An error occurred while deleting Kind cluster - {cluster_name}: {error_message}") + console.print("") + console.print("Kind cluster removed successfully!", style=f"bold {COLOR_PALETTE.get('success')}") + console.print("") + + def run_platform_compose(detached: bool = False, use_config_file: bool = False, dev: bool = False) -> None: if use_config_file: console.print("Using config file...") From e242cb78c89c9ac4bfc54452d4dfc8140cd7f958 Mon Sep 17 00:00:00 2001 From: luiz Date: Tue, 19 Sep 2023 23:05:17 +0200 Subject: [PATCH 257/328] remove dependency, some fixes on cli --- helm/domino/Chart.yaml | 5 -- helm/domino/values.yaml | 63 ++++++++++----------- src/domino/cli/utils/platform.py | 46 +++++++-------- src/domino/custom_operators/k8s_operator.py | 4 +- 4 files changed, 55 insertions(+), 63 deletions(-) diff --git a/helm/domino/Chart.yaml b/helm/domino/Chart.yaml index 50d02039..84a24ca7 100644 --- a/helm/domino/Chart.yaml +++ b/helm/domino/Chart.yaml @@ -7,8 +7,3 @@ appVersion: 0.1.5 home: https://github.com/Tauffer-Consulting/domino sources: - https://github.com/Tauffer-Consulting/domino -# dependencies: -# - name: airflow -# version: 1.9.0 -# repository: https://airflow.apache.org/ -# condition: airflow.enabled diff --git a/helm/domino/values.yaml b/helm/domino/values.yaml index f6116715..e11b1d88 100644 --- a/helm/domino/values.yaml +++ b/helm/domino/values.yaml @@ -24,35 +24,34 @@ database: name: postgres user: postgres password: postgres - -# Airflow services override -airflow: - enabled: true - env: [{ "name": DOMINO_DEPLOY_MODE, "value": prod }] - images: - useDefaultImageForMigration: false - airflow: - repository: ghcr.io/tauffer-consulting/domino-airflow-base - tag: latest - pullPolicy: IfNotPresent - - extraSecrets: - airflow-ssh-secret: - # github ssh private deploy key for workflow repository - data: | - gitSshKey: default-substitute-this-for-your-own-key - - config: - api: - auth_backends: airflow.api.auth.backend.basic_auth - - # Git sync - dags: - gitSync: - enabled: true - wait: 60 # interval between git sync attempts in seconds - # Github workflows reposiory ssh path - repo: ~ - branch: main - subPath: "workflows" - sshKeySecret: airflow-ssh-secret +# # Airflow services override +# airflow: +# enabled: true +# env: [{ "name": DOMINO_DEPLOY_MODE, "value": prod }] +# images: +# useDefaultImageForMigration: false +# airflow: +# repository: ghcr.io/tauffer-consulting/domino-airflow-base +# tag: latest +# pullPolicy: IfNotPresent + +# extraSecrets: +# airflow-ssh-secret: +# # github ssh private deploy key for workflow repository +# data: | +# gitSshKey: default-substitute-this-for-your-own-key + +# config: +# api: +# auth_backends: airflow.api.auth.backend.basic_auth + +# # Git sync +# dags: +# gitSync: +# enabled: true +# wait: 60 # interval between git sync attempts in seconds +# # Github workflows reposiory ssh path +# repo: ~ +# branch: main +# subPath: "workflows" +# sshKeySecret: airflow-ssh-secret diff --git a/src/domino/cli/utils/platform.py b/src/domino/cli/utils/platform.py index d490d6ac..c1bc8257 100644 --- a/src/domino/cli/utils/platform.py +++ b/src/domino/cli/utils/platform.py @@ -266,6 +266,20 @@ def create_platform(run_airflow: bool = True, use_gpu: bool = False) -> None: token_pieces = platform_config["github"]["DOMINO_DEFAULT_PIECES_REPOSITORY_TOKEN"] token_workflows = platform_config["github"]["DOMINO_GITHUB_ACCESS_TOKEN_WORKFLOWS"] + domino_values_override_config = { + "github_access_token_pieces": token_pieces, + "github_access_token_workflows": token_workflows, + "frontend": { + "enabled": True, + "image": domino_frontend_image, + }, + "rest": { + "enabled": True, + "image": domino_rest_image, + "workflowsRepository": platform_config['github']['DOMINO_GITHUB_WORKFLOWS_REPOSITORY'], + }, + } + # Create temporary airflow values with user provided arguments airflow_ssh_config = dict( gitSshKey=f"{platform_config['github']['DOMINO_GITHUB_WORKFLOWS_SSH_PRIVATE_KEY']}", @@ -304,24 +318,7 @@ def create_platform(run_airflow: bool = True, use_gpu: bool = False) -> None: } } - domino_values_override_config = { - "github_access_token_pieces": token_pieces, - "github_access_token_workflows": token_workflows, - "frontend": { - "enabled": True, - "image": domino_frontend_image, - }, - "rest": { - "enabled": True, - "image": domino_rest_image, - "workflowsRepository": platform_config['github']['DOMINO_GITHUB_WORKFLOWS_REPOSITORY'], - }, - } - airflow_values_override_config = { - **domino_values_override_config, - # "airflow": { - # "enabled": True if run_airflow else False, "env": [ { "name": "DOMINO_DEPLOY_MODE", @@ -358,7 +355,6 @@ def create_platform(run_airflow: bool = True, use_gpu: bool = False) -> None: }, **workers, **scheduler, - # } } # Write yaml to temp file and install domino airflow @@ -381,23 +377,27 @@ def create_platform(run_airflow: bool = True, use_gpu: bool = False) -> None: # console.print("Installing dependencies...") # subprocess.run(["helm", "dependency", "build"], cwd=f"{tmp_dir}/domino") # with NamedTemporaryFile(suffix='.yaml', mode="w") as fp: - with open("values-airflow.yaml", "w") as fp: - yaml.dump(airflow_values_override_config, fp) + console.print('Installing Apache Airflow...') + with open("values-override-airflow.yaml", "w") as fp: + yaml.dump(airflow_values_override_config, fp) commands = [ "helm", "install", - "-f", "values-airflow.yaml", + # "-f", str(fp.name), + "-f", "values-override-airflow.yaml", "airflow", "apache-airflow/airflow", "--version", " 1.9.0", - # "/media/luiz/storage2/Github/domino/helm/domino/charts/airflow-1.9.0.tgz" # TODO: remove this line, only for local dev ] subprocess.run(commands) + console.print('Installing Domino...') + with open("values-override-domino.yaml", "w") as fp: + yaml.dump(domino_values_override_config, fp) commands = [ "helm", "install", # "-f", str(fp.name), - "-f", "values-airflow.yaml", + "-f", "values-override-domino.yaml", "domino", # f"{tmp_dir}/domino", "/media/luiz/storage2/Github/domino/helm/domino" # TODO: remove this line, only for local dev diff --git a/src/domino/custom_operators/k8s_operator.py b/src/domino/custom_operators/k8s_operator.py index 4117e3f0..006ac451 100644 --- a/src/domino/custom_operators/k8s_operator.py +++ b/src/domino/custom_operators/k8s_operator.py @@ -94,10 +94,8 @@ def _make_volumes_and_volume_mounts_dev(self): repository_raw_project_name = str(self.piece_source_image).split('/')[-1].split(':')[0] persistent_volume_claim_name = 'pvc-{}'.format(str(repository_raw_project_name.lower().replace('_', '-'))) - persistent_volume_name = 'pv-{}'.format(str(repository_raw_project_name.lower().replace('_', '-'))) - persistent_volume_claim_name = 'pvc-{}'.format(str(repository_raw_project_name.lower().replace('_', '-'))) - + pvc_exists = False try: k8s_client.read_namespaced_persistent_volume_claim(name=persistent_volume_claim_name, namespace='default') From 96e0f0e697bbf1044993e6207057f2f726fb87e6 Mon Sep 17 00:00:00 2001 From: Nathan Vieira Marcelino Date: Tue, 19 Sep 2023 19:21:30 -0300 Subject: [PATCH 258/328] chore: use new workflow planel --- .../{ReactFlow => WorkflowPanel}/index.tsx | 92 +++++--- .../components/WorkflowEditor.tsx | 2 +- .../WorkflowsRunTasksFlowchart/index.tsx | 222 +++++++++--------- 3 files changed, 162 insertions(+), 154 deletions(-) rename frontend/src/components/{ReactFlow => WorkflowPanel}/index.tsx (77%) diff --git a/frontend/src/components/ReactFlow/index.tsx b/frontend/src/components/WorkflowPanel/index.tsx similarity index 77% rename from frontend/src/components/ReactFlow/index.tsx rename to frontend/src/components/WorkflowPanel/index.tsx index 06b1956d..16d3ff58 100644 --- a/frontend/src/components/ReactFlow/index.tsx +++ b/frontend/src/components/WorkflowPanel/index.tsx @@ -28,6 +28,7 @@ import ReactFlow, { type ReactFlowInstance, type XYPosition, } from "reactflow"; +import "reactflow/dist/style.css"; // Load CustomNode const NODE_TYPES = { @@ -62,13 +63,13 @@ type Props = onNodesDelete: OnNodesDelete; onEdgesDelete: OnEdgesDelete; onDrop: OnDrop; - onInit: OnInit; + onInit?: OnInit; onNodeDoubleClick?: NodeMouseHandler; } | { editable: false; - onInit: OnInit; + onInit?: OnInit; onNodeDoubleClick?: NodeMouseHandler; }; export interface WorkflowPanelRef { @@ -89,20 +90,22 @@ const WorkflowPanel = forwardRef( const onInit = useCallback(async (instance: ReactFlowInstance) => { setInstance(instance); - const result = props.onInit(instance); - if (result instanceof Promise) { - result - .then(({ nodes, edges }) => { - setNodes(nodes); - setEdges(edges); - }) - .catch((error) => { - console.error("Error from Promise-returning function:", error); - }); - } else { - const { nodes, edges } = result; - setNodes(nodes); - setEdges(edges); + if (props.onInit) { + const result = props.onInit(instance); + if (result instanceof Promise) { + result + .then(({ nodes, edges }) => { + setNodes(nodes); + setEdges(edges); + }) + .catch((error) => { + console.error("Error from Promise-returning function:", error); + }); + } else { + const { nodes, edges } = result; + setNodes(nodes); + setEdges(edges); + } } }, []); @@ -243,26 +246,43 @@ const WorkflowPanel = forwardRef( ref={reactFlowWrapper} style={{ height: "100%", width: "100%" }} > - - - - - + {props.editable ? ( + + + + + + ) : ( + + + + + + )}
); diff --git a/frontend/src/features/workflowEditor/components/WorkflowEditor.tsx b/frontend/src/features/workflowEditor/components/WorkflowEditor.tsx index 339679bd..3585793a 100644 --- a/frontend/src/features/workflowEditor/components/WorkflowEditor.tsx +++ b/frontend/src/features/workflowEditor/components/WorkflowEditor.tsx @@ -6,7 +6,7 @@ import { Button, Grid, Paper } from "@mui/material"; import { AxiosError } from "axios"; import { type INodeData } from "components/CustomNode"; import Loading from "components/Loading"; -import WorkflowPanel, { type WorkflowPanelRef } from "components/ReactFlow"; +import WorkflowPanel, { type WorkflowPanelRef } from "components/WorkflowPanel"; import { useWorkspaces } from "context/workspaces"; import { useWorkflowsEditor } from "features/workflowEditor/context"; import { type DragEvent, useCallback, useRef, useState } from "react"; diff --git a/frontend/src/features/workflows/components/WorkflowsRunTasksFlowchart/index.tsx b/frontend/src/features/workflows/components/WorkflowsRunTasksFlowchart/index.tsx index 707fa20b..cb3c20bf 100644 --- a/frontend/src/features/workflows/components/WorkflowsRunTasksFlowchart/index.tsx +++ b/frontend/src/features/workflows/components/WorkflowsRunTasksFlowchart/index.tsx @@ -1,20 +1,21 @@ -import { Button, Card, Grid, ButtonGroup, CardContent } from "@mui/material"; -import CustomNode from "components/CustomNode"; +import { + Button, + Card, + Grid, + ButtonGroup, + CardContent, + Paper, +} from "@mui/material"; +import WorkflowPanel, { type WorkflowPanelRef } from "components/WorkflowPanel"; import { taskStatesColorMap } from "features/workflows/constants"; import { useWorkflows } from "features/workflows/context/workflows"; -import { useCallback, useRef, useState, useEffect } from "react"; +import { useCallback, useState, useEffect, useRef } from "react"; import { toast } from "react-toastify"; -import ReactFlow, { Background, Controls, ReactFlowProvider } from "reactflow"; -import "reactflow/dist/style.css"; import { TaskDetails } from "./WorkflowTaskDetails"; import { TaskLogs } from "./WorkflowTaskLogs"; import { TaskResult } from "./WorkflowTaskResult"; -const nodeTypes = { - CustomNode, -}; - const buttonSX = { width: "100%", margin: "4px", @@ -42,9 +43,6 @@ const buttonSXActive = { }; export const WorkflowRunTaskFlowchart = () => { - const reactFlowWrapper = useRef(null); - const [nodes, setNodes] = useState([]); - const [edges, setEdges] = useState([]); const [nodeIdTaskMapping, setNodeIdTaskMapping] = useState({}); const [selectedButton, setSelectedButton] = useState("details"); const [selectedNodeTaskData, setSelectedNodeTaskData] = useState(null); @@ -56,6 +54,8 @@ export const WorkflowRunTaskFlowchart = () => { }); const updateTime = 5000; // in ms + const workflowPanelRef = useRef(null); + const { selectedWorkflow, handleFetchWorkflowRunTasks, @@ -114,12 +114,14 @@ export const WorkflowRunTaskFlowchart = () => { : []; nodes.push(...responseNodesData); } - setNodes(nodes); + workflowPanelRef.current?.setNodes(nodes); setNodeIdTaskMapping(nodeIdTaskMap); - setEdges(selectedWorkflow?.ui_schema?.edges ?? []); + workflowPanelRef.current?.setEdges( + selectedWorkflow?.ui_schema?.edges ?? [], + ); return nodeIdTaskMap; - }, [handleFetchWorkflowRunTasks, setNodes, setEdges, selectedWorkflow]); + }, [handleFetchWorkflowRunTasks, workflowPanelRef, selectedWorkflow]); useEffect(() => { if (selectedWorkflowRunId) { @@ -212,7 +214,6 @@ export const WorkflowRunTaskFlowchart = () => { }, [ nodeIdTaskMapping, - nodes, handleFetchWorkflowRunTaskLogs, handleFetchWorkflowRunTaskResult, ], @@ -223,110 +224,97 @@ export const WorkflowRunTaskFlowchart = () => { }, []); return ( - - - - -
- - - - -
-
-
- - - - - - + + + + + + + + + + + + + + - - - - - - {selectedNodeTaskData === null ? ( - "" - ) : selectedButton === "details" ? ( - - ) : selectedButton === "logs" ? ( - - ) : selectedButton === "result" ? ( - - ) : ( - "" - )} - + Details + + + + + + + {selectedNodeTaskData === null ? ( + "" + ) : selectedButton === "details" ? ( + + ) : selectedButton === "logs" ? ( + + ) : selectedButton === "result" ? ( + + ) : ( + "" + )} - - - +
+ + -
+ ); }; From cd8c501be84f7a3e6f2d99c6c19ffe38994b6fa4 Mon Sep 17 00:00:00 2001 From: Nathan Vieira Marcelino Date: Wed, 20 Sep 2023 14:11:48 -0300 Subject: [PATCH 259/328] chore: change icon --- .../src/features/workflowEditor/components/WorkflowEditor.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/frontend/src/features/workflowEditor/components/WorkflowEditor.tsx b/frontend/src/features/workflowEditor/components/WorkflowEditor.tsx index 3585793a..586519c5 100644 --- a/frontend/src/features/workflowEditor/components/WorkflowEditor.tsx +++ b/frontend/src/features/workflowEditor/components/WorkflowEditor.tsx @@ -1,4 +1,5 @@ import { Settings as SettingsSuggestIcon } from "@mui/icons-material"; +import AutoFixHighIcon from "@mui/icons-material/AutoFixHigh"; import ClearIcon from "@mui/icons-material/Clear"; import DownloadIcon from "@mui/icons-material/Download"; import SaveIcon from "@mui/icons-material/Save"; @@ -357,7 +358,7 @@ export const WorkflowsEditorComponent: React.FC = () => { + + + + + ); +}; diff --git a/frontend/src/features/workflowEditor/components/WorkflowEditor.tsx b/frontend/src/features/workflowEditor/components/WorkflowEditor.tsx index 44aa1aba..c71dfc51 100644 --- a/frontend/src/features/workflowEditor/components/WorkflowEditor.tsx +++ b/frontend/src/features/workflowEditor/components/WorkflowEditor.tsx @@ -299,7 +299,6 @@ export const WorkflowsEditorComponent: React.FC = () => { {loading && } { + const { id } = useParams<{ id: string }>(); + const workflowPanelRef = useRef(null); + const { selectedWorkflow } = useWorkflows(); + const [loading, _setLoading] = useState(selectedWorkflow?.id !== id); + + if (loading) { + return ; + } + + return ( + + + +

RUN DO WORKFLOW = {id}

+
+
+ + + {}} + /> + + + + +

Workflow run detail

+
+
+
+ ); +}; diff --git a/frontend/src/features/workflows/components/WorkflowDetail/skeleton.tsx b/frontend/src/features/workflows/components/WorkflowDetail/skeleton.tsx new file mode 100644 index 00000000..48c082d8 --- /dev/null +++ b/frontend/src/features/workflows/components/WorkflowDetail/skeleton.tsx @@ -0,0 +1,24 @@ +import { Card, Grid, Skeleton } from "@mui/material"; +import React from "react"; + +export const WorkflowDetailSkeleton: React.FC = () => { + return ( + + + + + + + + + + + + + + + + + + ); +}; diff --git a/frontend/src/features/workflows/components/Workflows.tsx b/frontend/src/features/workflows/components/Workflows.tsx deleted file mode 100644 index 1e9b2fb3..00000000 --- a/frontend/src/features/workflows/components/Workflows.tsx +++ /dev/null @@ -1,153 +0,0 @@ -import LoopIcon from "@mui/icons-material/Loop"; -import NavigateNextIcon from "@mui/icons-material/NavigateNext"; -import TabContext from "@mui/lab/TabContext"; -import { Button, Grid, Typography, Breadcrumbs, Link } from "@mui/material"; -import { useWorkflows } from "features/workflows/context/workflows"; -import React, { useState, useMemo } from "react"; - -import { WorkflowsRunsTable } from "./WorkflowsRunsTable"; -import { WorkflowRunTaskFlowchart } from "./WorkflowsRunTasksFlowchart"; -import { WorkflowsTable } from "./WorkflowsTable"; - -/** - * @todo continue refactor of SummaryWorkflows - */ -export const WorkflowsComponent: React.FC = () => { - const [value, setValue] = useState("1"); - - const { - selectedWorkflow, - selectedWorkflowRunId, - handleRefreshWorkflows, - workflowRuns, - } = useWorkflows(); - - const breadcrumbs = useMemo(() => { - let executionDate = null; - if (workflowRuns.data && selectedWorkflowRunId) { - executionDate = workflowRuns?.data?.find( - (run: { workflow_run_id: any }) => - run.workflow_run_id === selectedWorkflowRunId, - )?.execution_date; - executionDate = executionDate - ? new Date(executionDate).toLocaleString() - : ""; - } - const tabsBreadcrumbs = [ - { - setValue("1"); - }} - > - - {/* - - */} - Workflows - - , - { - setValue("2"); - }} - > - - {selectedWorkflow?.name} runs - - , - { - setValue("3"); - }} - > - - {executionDate} - - , - ]; - switch (true) { - case selectedWorkflow !== null && selectedWorkflowRunId !== null: - // change to tab 3 (tasks) - setValue("3"); - return [tabsBreadcrumbs.slice(0, 3)]; - case selectedWorkflow && !selectedWorkflowRunId: - // change to tab 2 (runs) - setValue("2"); - return [tabsBreadcrumbs.slice(0, 2)]; - default: - // change to tab 1 (workflows) - setValue("1"); - return [tabsBreadcrumbs.slice(0, 1)]; - } - }, [selectedWorkflow, selectedWorkflowRunId, workflowRuns]); - - return ( - - - } - > - {breadcrumbs} - - - - - - - - {value === "1" ? ( - - ) : value === "2" ? ( - - ) : value === "3" ? ( - - ) : ( - "" - )} - - - - ); -}; diff --git a/frontend/src/features/workflows/components/WorkflowsList/Actions.tsx b/frontend/src/features/workflows/components/WorkflowsList/Actions.tsx new file mode 100644 index 00000000..1634f12f --- /dev/null +++ b/frontend/src/features/workflows/components/WorkflowsList/Actions.tsx @@ -0,0 +1,79 @@ +import DeleteOutlineIcon from "@mui/icons-material/DeleteOutline"; +import PauseCircleOutlineIcon from "@mui/icons-material/PauseCircleOutline"; +import PlayCircleOutlineIcon from "@mui/icons-material/PlayCircleOutline"; +import { IconButton } from "@mui/material"; +import { type CommonProps } from "@mui/material/OverridableComponent"; +import { NewFeatureDialog } from "components/NewFeatureDialog"; +import { type IWorkflow } from "features/workflows/types"; +import theme from "providers/theme.config"; +import React, { useState } from "react"; + +import { ConfirmDeleteModal } from "./ConfirmDeleteModal"; + +interface Props extends CommonProps { + id: IWorkflow["id"]; + deleteFn: () => void; + runFn: () => void; + pauseFn: () => void; +} + +const Actions: React.FC = ({ runFn, deleteFn, className }) => { + const [deleteModalOpen, setDeleteModalOpen] = useState(false); + const [newFeatureModal, setNewFeatureModal] = useState(false); + + return ( + <> + + + + { + setNewFeatureModal(true); + }} + > + + + { + setDeleteModalOpen(true); + }} + > + + + { + setNewFeatureModal(false); + }} + /> + + Are you sure you want to delete this workflow? This action{" "} + cannot be undone. + + } + confirmCb={() => { + deleteFn(); + setDeleteModalOpen(false); + }} + cancelCb={() => { + setDeleteModalOpen(false); + }} + confirmText="Delete" + /> + + ); +}; + +export default Actions; diff --git a/frontend/src/features/workflows/components/WorkflowsList/ConfirmDeleteModal.tsx b/frontend/src/features/workflows/components/WorkflowsList/ConfirmDeleteModal.tsx new file mode 100644 index 00000000..f883b0df --- /dev/null +++ b/frontend/src/features/workflows/components/WorkflowsList/ConfirmDeleteModal.tsx @@ -0,0 +1,69 @@ +import { + Button, + Dialog, + DialogActions, + DialogContent, + DialogContentText, + DialogTitle, + Grid, +} from "@mui/material"; +import React, { useCallback } from "react"; + +interface Props { + isOpen: boolean; + title: string; + content: React.ReactElement; + confirmCb: () => void; + cancelCb: () => void; + + confirmText?: string; + cancelText?: string; +} + +export const ConfirmDeleteModal: React.FC = ({ + isOpen, + title, + content, + confirmCb, + cancelCb, + confirmText, + cancelText, +}) => { + const cancel = useCallback(() => { + cancelCb(); + }, [cancelCb]); + + const confirm = useCallback(() => { + confirmCb(); + }, [confirmCb]); + + return ( + + {title} + + + {content} + + + + + + + + + + + + + + ); +}; diff --git a/frontend/src/features/workflows/components/WorkflowsList/Status.tsx b/frontend/src/features/workflows/components/WorkflowsList/Status.tsx new file mode 100644 index 00000000..52c7c127 --- /dev/null +++ b/frontend/src/features/workflows/components/WorkflowsList/Status.tsx @@ -0,0 +1,45 @@ +import CheckCircleOutlineIcon from "@mui/icons-material/CheckCircleOutline"; +import HelpOutlineIcon from "@mui/icons-material/HelpOutline"; +import HighlightOffIcon from "@mui/icons-material/HighlightOff"; +import { CircularProgress, Tooltip } from "@mui/material"; +import theme from "providers/theme.config"; +import React from "react"; +// import { Container } from './styles'; + +interface Props { + status: "creating" | "failed" | "active"; +} + +export const Status: React.FC = ({ status }) => { + if (status === "creating") { + return ( + + + + ); + } else if (status === "failed") { + return ( + + + + ); + } else if (status === "active") { + return ( + + + + ); + } + return ( + // eslint-disable-next-line @typescript-eslint/restrict-template-expressions + + + + ); +}; diff --git a/frontend/src/features/workflows/components/WorkflowsList/index.tsx b/frontend/src/features/workflows/components/WorkflowsList/index.tsx new file mode 100644 index 00000000..07bd8c6d --- /dev/null +++ b/frontend/src/features/workflows/components/WorkflowsList/index.tsx @@ -0,0 +1,207 @@ +import { Paper } from "@mui/material"; +import { + DataGrid, + type GridColumns, + type GridEventListener, +} from "@mui/x-data-grid"; +import { AxiosError } from "axios"; +import { useWorkflows } from "features/workflows/context"; +import { type IWorkflow } from "features/workflows/types"; +import React, { useCallback, useEffect, useMemo } from "react"; +import { useNavigate } from "react-router-dom"; +import { toast } from "react-toastify"; + +import Actions from "./Actions"; +import { Status } from "./Status"; + +/** + * @todo Trigger run. [x] + * @todo Delete workflow. [x] + * @todo Cancel run. [] + * @todo Pause run. [] + */ + +export const WorkflowList: React.FC = () => { + const { + workflows, + tablePage, + setTablePage, + handleRunWorkflow, + handleDeleteWorkflow, + handleRefreshWorkflows, + } = useWorkflows(); + const navigate = useNavigate(); + + const deleteWorkflow = useCallback(async (id: IWorkflow["id"]) => { + try { + await handleDeleteWorkflow(String(id)); + handleRefreshWorkflows(); + toast.success("Workflow deleted."); + } catch (e) { + if (e instanceof AxiosError) { + if (e?.response?.status === 403) { + toast.error("You are not allowed to delete this workflow."); + } else if (e?.response?.status === 404) { + toast.error("Workflow not found."); + } else if (e?.response?.status === 409) { + toast.error("Workflow is not in a valid state. "); + } else { + console.error(e); + toast.error("Something went wrong."); + } + } else { + console.error(e); + } + } + }, []); + const runWorkflow = useCallback(async (id: IWorkflow["id"]) => { + try { + await handleRunWorkflow(String(id)); + toast.info("Workflow started"); + } catch (e) { + if (e instanceof AxiosError) { + if (e?.response?.status === 403) { + toast.error("You are not allowed to run this workflow."); + } else if (e?.response?.status === 404) { + toast.error("Workflow not found."); + } else if (e?.response?.status === 409) { + toast.error("Workflow is not in a valid state. "); + } else { + console.error(e); + toast.error("Something went wrong when starting the workflow."); + } + } else { + console.error(e); + } + } + }, []); + const pauseWorkflow = useCallback((id: IWorkflow["id"]) => { + console.log(id); + }, []); + + const { rows, totalRows } = useMemo( + () => ({ + rows: workflows.data ?? [], + totalRows: workflows.metadata?.total ?? 0, + }), + [workflows], + ); + + const columns = useMemo>( + () => [ + { + field: "id", + headerName: "ID", + width: 80, + headerAlign: "center", + align: "center", + sortable: false, + }, + { + field: "status", + headerName: "Status", + renderCell: (params) => , + flex: 0.5, + align: "center", + headerAlign: "center", + sortable: false, + }, + { field: "name", headerName: "Workflow Name", flex: 2 }, + { + field: "created_at", + headerName: "Created At", + flex: 1, + align: "center", + + valueFormatter: ({ value }) => new Date(value).toLocaleString(), + headerAlign: "center", + }, + { + field: "last_changed_at", + headerName: "Last Modified", + flex: 1, + align: "center", + valueFormatter: ({ value }) => new Date(value).toLocaleString(), + headerAlign: "center", + }, + { + field: "schedule_interval", + headerName: "Schedule Interval", + flex: 1, + align: "center", + headerAlign: "center", + sortable: false, + }, + { + field: "actions", + headerName: "Actions", + flex: 1, + renderCell: ({ row }) => ( + { + void deleteWorkflow(row.id); + }} + runFn={() => { + void runWorkflow(row.id); + }} + pauseFn={() => { + pauseWorkflow(row.id); + }} + /> + ), + headerAlign: "center", + align: "center", + sortable: false, + }, + ], + [], + ); + + const handleRowClick = useCallback>( + (row, event) => { + const isActionButtonClick = + event.target instanceof Element && + event.target.classList.contains(".action-button"); + if (!isActionButtonClick) { + // Handle row click logic only if it's not an action button click + navigate(`/workflows/${row.id}`); + } + }, + [navigate], + ); + + useEffect(() => { + handleRefreshWorkflows(); + }, []); + + return ( + <> + + + + + ); +}; diff --git a/frontend/src/features/workflows/components/WorkflowsRunTasksFlowchart/WorkflowTaskDetails.tsx b/frontend/src/features/workflows/components/WorkflowsRunTasksFlowchart/WorkflowTaskDetails.tsx deleted file mode 100644 index 6e8f01b4..00000000 --- a/frontend/src/features/workflows/components/WorkflowsRunTasksFlowchart/WorkflowTaskDetails.tsx +++ /dev/null @@ -1,109 +0,0 @@ -import CalendarMonthIcon from "@mui/icons-material/CalendarMonth"; -import TimelapseIcon from "@mui/icons-material/Timelapse"; -import { Grid, List, ListItem, Chip, Typography } from "@mui/material"; -import { taskStatesColorMap } from "features/workflows/constants"; -import { type IWorkflowRunTasks } from "features/workflows/types/runs"; - -interface IWorkflowRunTasksExtended extends IWorkflowRunTasks { - pieceName: string; -} - -interface ITaskDetailsProps { - taskData: IWorkflowRunTasksExtended; -} - -export const TaskDetails = (props: ITaskDetailsProps) => { - // @todo use style components instead of inline styles - - return ( - - - - - - State: - - - { - - } - - - - - Piece: - - - {props.taskData.pieceName} - - - - - Start Date: - - - - {new Date(props.taskData.start_date).toLocaleString()} - - - - - End Date: - - - - {new Date(props.taskData.end_date).toLocaleString()} - - - - - Duration: - - - - {new Date(1000 * props.taskData.duration) - .toISOString() - .substring(11, 19)} - - - - - - ); -}; diff --git a/frontend/src/features/workflows/components/WorkflowsRunTasksFlowchart/WorkflowTaskLogs.tsx b/frontend/src/features/workflows/components/WorkflowsRunTasksFlowchart/WorkflowTaskLogs.tsx deleted file mode 100644 index 0afe917f..00000000 --- a/frontend/src/features/workflows/components/WorkflowsRunTasksFlowchart/WorkflowTaskLogs.tsx +++ /dev/null @@ -1,67 +0,0 @@ -import { - Grid, - TextareaAutosize, - Switch, - FormControlLabel, - FormGroup, -} from "@mui/material"; -import { useState, useEffect, useMemo } from "react"; - -interface ITaskLogsProps { - logs: string[]; -} - -export const TaskLogs = (props: ITaskLogsProps) => { - // @todo use style components instead of inline styles - const { logs } = props; - const [logContent, setLogContent] = useState(""); - const [renderOverflowX, setRenderOverflowX] = useState(true); - - // @todo - // const logsTypeColorMap = { - // 'INFO': '#64df46', - // 'ERROR': '#f00', - // 'WARNING': '#f90', - // 'DEBUG': '#00f', - // } - - useEffect(() => { - setLogContent(logs.join("\n")); - }, [logs]); - - const textareaStyle: any = useMemo(() => { - return { - width: "100%", - border: "none", - overflowX: renderOverflowX ? "hidden" : "scroll", - whiteSpace: renderOverflowX ? "pre-wrap" : "pre", - outline: "none", - }; - }, [renderOverflowX]); - - return ( - - - - { - setRenderOverflowX(!renderOverflowX); - }} - /> - } - label="Wrap text horizontally." - /> - - - - - ); -}; diff --git a/frontend/src/features/workflows/components/WorkflowsRunTasksFlowchart/WorkflowTaskResult.tsx b/frontend/src/features/workflows/components/WorkflowsRunTasksFlowchart/WorkflowTaskResult.tsx deleted file mode 100644 index 80a17ec5..00000000 --- a/frontend/src/features/workflows/components/WorkflowsRunTasksFlowchart/WorkflowTaskResult.tsx +++ /dev/null @@ -1,88 +0,0 @@ -import { Box, CircularProgress } from "@mui/material"; -import ReactMarkdown from "react-markdown"; -// import { PDFViewer, Page, Text, View, Document, StyleSheet } from '@react-pdf/renderer'; - -interface ITaskResultProps { - base64_content: string; - file_type: string; -} - -export const TaskResult = (props: ITaskResultProps) => { - const { base64_content, file_type } = props; - - const renderContent = () => { - if (!base64_content || !file_type) { - return ; - } - switch (file_type) { - case "txt": - return
{window.atob(base64_content)}
; - case "json": - return ( -
-            {JSON.stringify(JSON.parse(window.atob(base64_content)), null, 2)}
-          
- ); - case "jpeg": - case "png": - case "bmp": - case "gif": - case "tiff": - return ( - Content - ); - case "svg": - return ( - - Your browser does not support SVG - - ); - case "md": - return {window.atob(base64_content)}; - case "pdf": - return ( -
- PDF result display not yet implemented - {/* - - - - */} -
- ); - case "html": - return ( -
- HTML result display not yet implemented -
- //