From 7075bcacc3cda78f28ad27f2024ba91b77f0b5b5 Mon Sep 17 00:00:00 2001 From: Ruben van Leeuwen Date: Tue, 9 Dec 2025 12:13:32 +0100 Subject: [PATCH 1/5] 2023: Npm uninstall uniforms --- package-lock.json | 52 ++----------------- .../orchestrator-ui-components/package.json | 3 -- 2 files changed, 5 insertions(+), 50 deletions(-) diff --git a/package-lock.json b/package-lock.json index 04b02ab7c..c3cc41719 100644 --- a/package-lock.json +++ b/package-lock.json @@ -354,7 +354,7 @@ } }, "apps/wfo-ui-surf": { - "version": "4.16.0", + "version": "4.17.0", "hasInstallScript": true, "dependencies": { "@copilotkit/react-core": "^1.10.6", @@ -29716,6 +29716,7 @@ "version": "3.10.2", "resolved": "https://registry.npmjs.org/uniforms/-/uniforms-3.10.2.tgz", "integrity": "sha512-5FIqpAqyWDmDhaNkmXOxuz8dJ09jPg0gTpn13O6WiqtCY+nmVtHK4yGSpFU1UIjwBt9KfbRPFFmCAbYlCyV4bw==", + "dev": true, "dependencies": { "invariant": "^2.0.0", "lodash": "^4.0.0", @@ -29728,25 +29729,6 @@ "react": "^18.0.0 || ^17.0.0 || ^16.8.0" } }, - "node_modules/uniforms-bridge-json-schema": { - "version": "3.10.2", - "resolved": "https://registry.npmjs.org/uniforms-bridge-json-schema/-/uniforms-bridge-json-schema-3.10.2.tgz", - "integrity": "sha512-J2RG0WQrMH39M9124lhopXnbR/ycuLJk9IkA/ix9Dxpk1dQ7EuHLg/CeXTeZTeQiF2KZrKMYXxUswEmFh7kIMQ==", - "dependencies": { - "invariant": "^2.0.0", - "lodash": "^4.0.0", - "tslib": "^2.2.0", - "uniforms": "^3.10.2" - }, - "funding": { - "url": "https://github.com/vazco/uniforms?sponsor=1" - } - }, - "node_modules/uniforms-bridge-json-schema/node_modules/tslib": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", - "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" - }, "node_modules/uniforms-bridge-simple-schema-2": { "version": "3.10.2", "resolved": "https://registry.npmjs.org/uniforms-bridge-simple-schema-2/-/uniforms-bridge-simple-schema-2-3.10.2.tgz", @@ -29769,32 +29751,11 @@ "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", "dev": true }, - "node_modules/uniforms-unstyled": { - "version": "3.10.2", - "resolved": "https://registry.npmjs.org/uniforms-unstyled/-/uniforms-unstyled-3.10.2.tgz", - "integrity": "sha512-Wd4RoWaPldCGNJuEhiyrkCb6hhr823+0pFqH8qlkY58dpggwTcbu2gdWQrnfR8J3o3hB6mpt0SvcDXVfl2CLMA==", - "dependencies": { - "invariant": "^2.0.0", - "lodash": "^4.0.0", - "tslib": "^2.2.0", - "uniforms": "^3.10.2" - }, - "funding": { - "url": "https://github.com/vazco/uniforms?sponsor=1" - }, - "peerDependencies": { - "react": "^18.0.0 || ^17.0.0 || ^16.8.0" - } - }, - "node_modules/uniforms-unstyled/node_modules/tslib": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", - "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" - }, "node_modules/uniforms/node_modules/tslib": { "version": "2.8.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", - "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "dev": true }, "node_modules/unist-builder": { "version": "2.0.3", @@ -31024,7 +30985,7 @@ }, "packages/orchestrator-ui-components": { "name": "@orchestrator-ui/orchestrator-ui-components", - "version": "6.7.7", + "version": "6.8.0", "license": "Apache-2.0", "dependencies": { "@ag-ui/client": "0.0.39", @@ -31054,9 +31015,6 @@ "react-select": "^5.8.0", "scroll-into-view": "^1.16.2", "unidiff": "^1.0.4", - "uniforms": "^3.8.1", - "uniforms-bridge-json-schema": "^3.8.1", - "uniforms-unstyled": "^3.8.1", "use-query-params": "2.2.1" }, "devDependencies": { diff --git a/packages/orchestrator-ui-components/package.json b/packages/orchestrator-ui-components/package.json index ad1d13461..26b537ff7 100644 --- a/packages/orchestrator-ui-components/package.json +++ b/packages/orchestrator-ui-components/package.json @@ -61,9 +61,6 @@ "react-select": "^5.8.0", "scroll-into-view": "^1.16.2", "unidiff": "^1.0.4", - "uniforms": "^3.8.1", - "uniforms-bridge-json-schema": "^3.8.1", - "uniforms-unstyled": "^3.8.1", "use-query-params": "2.2.1" }, "devDependencies": { From ea548d7a3e9f9ba2d1ba92ce7663d3dc95af482c Mon Sep 17 00:00:00 2001 From: Ruben van Leeuwen Date: Tue, 9 Dec 2025 12:35:55 +0100 Subject: [PATCH 2/5] 2023: Remove all uniforms related components --- apps/wfo-ui | 2 +- .../components/WfoForms/AutoFieldLoader.tsx | 118 --- .../src/components/WfoForms/AutoFields.tsx | 49 -- .../src/components/WfoForms/CreateForm.tsx | 75 -- .../src/components/WfoForms/UserInputForm.tsx | 697 ------------------ .../WfoForms/UserInputFormStyling.ts | 80 -- .../WfoForms/UserInputFormWizard.tsx | 127 ---- .../WfoForms/formFields/AcceptField.tsx | 243 ------ .../WfoForms/formFields/AcceptFieldStyling.ts | 35 - .../WfoForms/formFields/BoolField.tsx | 77 -- .../WfoForms/formFields/BoolFieldStyling.ts | 64 -- .../formFields/ConnectedSelectField.tsx | 19 - .../WfoForms/formFields/CustomerField.tsx | 77 -- .../WfoForms/formFields/DateField.tsx | 72 -- .../WfoForms/formFields/DividerField.tsx | 29 - .../WfoForms/formFields/ErrorField.tsx | 40 - .../WfoForms/formFields/ErrorsField.tsx | 34 - .../WfoForms/formFields/LabelField.tsx | 43 -- .../WfoForms/formFields/ListAddField.tsx | 95 --- .../WfoForms/formFields/ListDelField.tsx | 95 --- .../WfoForms/formFields/ListField.tsx | 117 --- .../WfoForms/formFields/ListItemField.tsx | 40 - .../WfoForms/formFields/ListSelectField.tsx | 95 --- .../WfoForms/formFields/LocationCodeField.tsx | 60 -- .../WfoForms/formFields/LongTextField.tsx | 68 -- .../WfoForms/formFields/NestField.tsx | 107 --- .../WfoForms/formFields/NumField.tsx | 85 --- .../WfoForms/formFields/OptGroupField.tsx | 74 -- .../WfoForms/formFields/RadioField.tsx | 87 --- .../formFields/SelectField/SelectField.tsx | 177 ----- .../WfoForms/formFields/SelectField/index.ts | 1 - .../WfoForms/formFields/SelectField/styles.ts | 52 -- .../WfoForms/formFields/SubmitField.tsx | 50 -- .../formFields/SubscriptionSummaryField.tsx | 74 -- .../WfoForms/formFields/SummaryField.tsx | 104 --- .../formFields/SummaryFieldStyling.ts | 44 -- .../WfoForms/formFields/TextField.tsx | 81 -- .../WfoForms/formFields/commonStyles.ts | 32 - .../deprecated/ContactPersonAutocomplete.tsx | 99 --- .../ContactPersonAutocompleteStyles.ts | 41 -- .../deprecated/ContactPersonNameField.tsx | 263 ------- .../formFields/deprecated/FileUploadField.tsx | 151 ---- .../formFields/deprecated/ImsNodeIdField.tsx | 109 --- .../formFields/deprecated/ImsPortIdField.tsx | 233 ------ .../deprecated/ImsPortIdFieldStyling.ts | 17 - .../formFields/deprecated/IpNetworkField.tsx | 105 --- .../deprecated/IpPrefixTableField.tsx | 390 ---------- .../deprecated/IpPrefixTableFieldStyling.ts | 117 --- .../formFields/deprecated/SplitPrefix.tsx | 138 ---- .../deprecated/SplitPrefixStyling.ts | 11 - .../deprecated/SubscriptionField.tsx | 263 ------- .../deprecated/SubscriptionFieldStyling.ts | 33 - .../formFields/deprecated/TimestampField.tsx | 110 --- .../formFields/deprecated/VlanField.tsx | 300 -------- .../WfoForms/formFields/deprecated/index.ts | 15 - .../WfoForms/formFields/deprecated/types.ts | 74 -- .../WfoForms/formFields/deprecated/utils.ts | 1 - .../components/WfoForms/formFields/index.ts | 30 - .../WfoForms/formFields/listFieldStyling.ts | 86 --- .../components/WfoForms/formFields/types.ts | 41 -- .../WfoForms/formFields/utils.spec.ts | 296 -------- .../components/WfoForms/formFields/utils.ts | 69 -- .../src/components/WfoForms/index.ts | 5 - .../WfoPydanticForm/RenderFormErrors.tsx | 3 +- .../src/components/WfoPydanticForm/Row.tsx | 4 +- .../WfoPydanticForm/fields/WfoSummary.tsx | 8 +- .../WfoPydanticForm/fields/styles.ts | 72 ++ .../WfoWorkflowSteps/WfoStep/WfoStep.tsx | 26 +- .../WfoStep/WfoStepFormOld.tsx | 67 -- .../src/components/index.ts | 1 - .../pages/processes/WfoStartProcessPage.tsx | 112 +-- 71 files changed, 94 insertions(+), 6615 deletions(-) delete mode 100644 packages/orchestrator-ui-components/src/components/WfoForms/AutoFieldLoader.tsx delete mode 100644 packages/orchestrator-ui-components/src/components/WfoForms/AutoFields.tsx delete mode 100644 packages/orchestrator-ui-components/src/components/WfoForms/CreateForm.tsx delete mode 100644 packages/orchestrator-ui-components/src/components/WfoForms/UserInputForm.tsx delete mode 100644 packages/orchestrator-ui-components/src/components/WfoForms/UserInputFormStyling.ts delete mode 100644 packages/orchestrator-ui-components/src/components/WfoForms/UserInputFormWizard.tsx delete mode 100644 packages/orchestrator-ui-components/src/components/WfoForms/formFields/AcceptField.tsx delete mode 100644 packages/orchestrator-ui-components/src/components/WfoForms/formFields/AcceptFieldStyling.ts delete mode 100644 packages/orchestrator-ui-components/src/components/WfoForms/formFields/BoolField.tsx delete mode 100644 packages/orchestrator-ui-components/src/components/WfoForms/formFields/BoolFieldStyling.ts delete mode 100644 packages/orchestrator-ui-components/src/components/WfoForms/formFields/ConnectedSelectField.tsx delete mode 100644 packages/orchestrator-ui-components/src/components/WfoForms/formFields/CustomerField.tsx delete mode 100644 packages/orchestrator-ui-components/src/components/WfoForms/formFields/DateField.tsx delete mode 100644 packages/orchestrator-ui-components/src/components/WfoForms/formFields/DividerField.tsx delete mode 100644 packages/orchestrator-ui-components/src/components/WfoForms/formFields/ErrorField.tsx delete mode 100644 packages/orchestrator-ui-components/src/components/WfoForms/formFields/ErrorsField.tsx delete mode 100644 packages/orchestrator-ui-components/src/components/WfoForms/formFields/LabelField.tsx delete mode 100644 packages/orchestrator-ui-components/src/components/WfoForms/formFields/ListAddField.tsx delete mode 100644 packages/orchestrator-ui-components/src/components/WfoForms/formFields/ListDelField.tsx delete mode 100644 packages/orchestrator-ui-components/src/components/WfoForms/formFields/ListField.tsx delete mode 100644 packages/orchestrator-ui-components/src/components/WfoForms/formFields/ListItemField.tsx delete mode 100644 packages/orchestrator-ui-components/src/components/WfoForms/formFields/ListSelectField.tsx delete mode 100644 packages/orchestrator-ui-components/src/components/WfoForms/formFields/LocationCodeField.tsx delete mode 100644 packages/orchestrator-ui-components/src/components/WfoForms/formFields/LongTextField.tsx delete mode 100644 packages/orchestrator-ui-components/src/components/WfoForms/formFields/NestField.tsx delete mode 100644 packages/orchestrator-ui-components/src/components/WfoForms/formFields/NumField.tsx delete mode 100644 packages/orchestrator-ui-components/src/components/WfoForms/formFields/OptGroupField.tsx delete mode 100644 packages/orchestrator-ui-components/src/components/WfoForms/formFields/RadioField.tsx delete mode 100644 packages/orchestrator-ui-components/src/components/WfoForms/formFields/SelectField/SelectField.tsx delete mode 100644 packages/orchestrator-ui-components/src/components/WfoForms/formFields/SelectField/index.ts delete mode 100644 packages/orchestrator-ui-components/src/components/WfoForms/formFields/SelectField/styles.ts delete mode 100644 packages/orchestrator-ui-components/src/components/WfoForms/formFields/SubmitField.tsx delete mode 100644 packages/orchestrator-ui-components/src/components/WfoForms/formFields/SubscriptionSummaryField.tsx delete mode 100644 packages/orchestrator-ui-components/src/components/WfoForms/formFields/SummaryField.tsx delete mode 100644 packages/orchestrator-ui-components/src/components/WfoForms/formFields/SummaryFieldStyling.ts delete mode 100644 packages/orchestrator-ui-components/src/components/WfoForms/formFields/TextField.tsx delete mode 100644 packages/orchestrator-ui-components/src/components/WfoForms/formFields/commonStyles.ts delete mode 100644 packages/orchestrator-ui-components/src/components/WfoForms/formFields/deprecated/ContactPersonAutocomplete.tsx delete mode 100644 packages/orchestrator-ui-components/src/components/WfoForms/formFields/deprecated/ContactPersonAutocompleteStyles.ts delete mode 100644 packages/orchestrator-ui-components/src/components/WfoForms/formFields/deprecated/ContactPersonNameField.tsx delete mode 100644 packages/orchestrator-ui-components/src/components/WfoForms/formFields/deprecated/FileUploadField.tsx delete mode 100644 packages/orchestrator-ui-components/src/components/WfoForms/formFields/deprecated/ImsNodeIdField.tsx delete mode 100644 packages/orchestrator-ui-components/src/components/WfoForms/formFields/deprecated/ImsPortIdField.tsx delete mode 100644 packages/orchestrator-ui-components/src/components/WfoForms/formFields/deprecated/ImsPortIdFieldStyling.ts delete mode 100644 packages/orchestrator-ui-components/src/components/WfoForms/formFields/deprecated/IpNetworkField.tsx delete mode 100644 packages/orchestrator-ui-components/src/components/WfoForms/formFields/deprecated/IpPrefixTableField.tsx delete mode 100644 packages/orchestrator-ui-components/src/components/WfoForms/formFields/deprecated/IpPrefixTableFieldStyling.ts delete mode 100644 packages/orchestrator-ui-components/src/components/WfoForms/formFields/deprecated/SplitPrefix.tsx delete mode 100644 packages/orchestrator-ui-components/src/components/WfoForms/formFields/deprecated/SplitPrefixStyling.ts delete mode 100644 packages/orchestrator-ui-components/src/components/WfoForms/formFields/deprecated/SubscriptionField.tsx delete mode 100644 packages/orchestrator-ui-components/src/components/WfoForms/formFields/deprecated/SubscriptionFieldStyling.ts delete mode 100644 packages/orchestrator-ui-components/src/components/WfoForms/formFields/deprecated/TimestampField.tsx delete mode 100644 packages/orchestrator-ui-components/src/components/WfoForms/formFields/deprecated/VlanField.tsx delete mode 100644 packages/orchestrator-ui-components/src/components/WfoForms/formFields/deprecated/index.ts delete mode 100644 packages/orchestrator-ui-components/src/components/WfoForms/formFields/deprecated/types.ts delete mode 100644 packages/orchestrator-ui-components/src/components/WfoForms/formFields/deprecated/utils.ts delete mode 100644 packages/orchestrator-ui-components/src/components/WfoForms/formFields/index.ts delete mode 100644 packages/orchestrator-ui-components/src/components/WfoForms/formFields/listFieldStyling.ts delete mode 100644 packages/orchestrator-ui-components/src/components/WfoForms/formFields/types.ts delete mode 100644 packages/orchestrator-ui-components/src/components/WfoForms/formFields/utils.spec.ts delete mode 100644 packages/orchestrator-ui-components/src/components/WfoForms/formFields/utils.ts delete mode 100644 packages/orchestrator-ui-components/src/components/WfoForms/index.ts delete mode 100644 packages/orchestrator-ui-components/src/components/WfoWorkflowSteps/WfoStep/WfoStepFormOld.tsx diff --git a/apps/wfo-ui b/apps/wfo-ui index bc7ced020..e95c93d3e 160000 --- a/apps/wfo-ui +++ b/apps/wfo-ui @@ -1 +1 @@ -Subproject commit bc7ced02055fc56b37e1d1d694b2d774eb3f5083 +Subproject commit e95c93d3ef62458fdca7d6965ad0f69a93478e51 diff --git a/packages/orchestrator-ui-components/src/components/WfoForms/AutoFieldLoader.tsx b/packages/orchestrator-ui-components/src/components/WfoForms/AutoFieldLoader.tsx deleted file mode 100644 index 53cc4ab19..000000000 --- a/packages/orchestrator-ui-components/src/components/WfoForms/AutoFieldLoader.tsx +++ /dev/null @@ -1,118 +0,0 @@ -import { Context, GuaranteedProps } from 'uniforms'; -import { AutoField } from 'uniforms-unstyled'; - -import { - AcceptField, - BoolField, - ConnectedSelectField, - ContactPersonNameField, - CustomerField, - DateField, - DividerField, - FileUploadField, - ImsNodeIdField, - ImsPortIdField, - IpNetworkField, - LabelField, - ListField, - LocationCodeField, - LongTextField, - NestField, - NumField, - OptGroupField, - RadioField, - SubscriptionField, - SubscriptionSummaryField, - SummaryField, - TextField, - TimestampField, - VlanField, -} from './formFields'; - -export function autoFieldFunction( - props: GuaranteedProps & Record, - uniforms: Context>, -) { - const { allowedValues, checkboxes, fieldType, field } = props; - const { format } = field; - - /* - Note, uniforms adds the fieldType property with one of the primitive types (Number, String..) based on the value of "type" in - node_modules/uniforms-bridge-json-schema/src/JSONSchemaBridge.ts. The only exception being dateFields where it matches on the - "format" field being "date-time" to populate fieldType with a Date constructor - */ - switch (fieldType) { - case Number: - switch (format) { - case 'imsPortId': // Deprecated - return ImsPortIdField; - case 'imsNodeId': // Deprecated - return ImsNodeIdField; - case 'timestamp': - return TimestampField; // Deprecated - } - break; - case Object: - switch (format) { - case 'optGroup': - return OptGroupField; - case 'summary': - return SummaryField; - } - break; - case String: - switch (format) { - case 'subscriptionId': - return SubscriptionField; - case 'long': - return LongTextField; - case 'label': - return LabelField; - case 'divider': - return DividerField; - case 'summary': - return SummaryField; - case 'subscription': - return SubscriptionSummaryField; - case 'customerId': - return CustomerField; - case 'locationCode': - return LocationCodeField; - case 'contactPersonName': // Deprecated - return ContactPersonNameField; - case 'vlan': // Deprecated - return VlanField; - case 'accept': - return AcceptField; - case 'ipvanynetwork': // Deprecated - return IpNetworkField; - case 'file': // Deprecated - return FileUploadField; - } - break; - } - - if (allowedValues && format !== 'accept') { - return checkboxes && fieldType !== Array - ? RadioField - : ConnectedSelectField; - } else { - switch (fieldType) { - case Array: - return ListField; - case Boolean: - return BoolField; - case Number: - return NumField; - case Object: - return NestField; - case String: - return TextField; - case Date: - // See the note at line above about how Date fields are matched on the "format" field instead of "type" like other fields - return DateField; - } - } - - return AutoField.defaultComponentDetector(props, uniforms); -} diff --git a/packages/orchestrator-ui-components/src/components/WfoForms/AutoFields.tsx b/packages/orchestrator-ui-components/src/components/WfoForms/AutoFields.tsx deleted file mode 100644 index 64cc3e3ec..000000000 --- a/packages/orchestrator-ui-components/src/components/WfoForms/AutoFields.tsx +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright 2019-2023 SURF. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ -import { ComponentType, createElement } from 'react'; - -import { useForm } from 'uniforms'; -import { AutoField } from 'uniforms-unstyled'; - -export type AutoFieldsProps = { - autoField?: ComponentType<{ className: string; name: string }>; - element?: ComponentType | string; - fields?: string[]; - omitFields?: string[]; -}; - -export default function AutoFields({ - autoField = AutoField, - element = 'section', - fields, - omitFields = [], - ...props -}: AutoFieldsProps) { - const { schema } = useForm(); - - return createElement( - element, - { ...props }, - (fields ?? schema.getSubfields()) - .filter((field) => !omitFields.includes(field)) - .map((field) => - createElement(autoField, { - key: field, - name: field, - className: 'form-input', - }), - ), - ); -} diff --git a/packages/orchestrator-ui-components/src/components/WfoForms/CreateForm.tsx b/packages/orchestrator-ui-components/src/components/WfoForms/CreateForm.tsx deleted file mode 100644 index bfc9cf48c..000000000 --- a/packages/orchestrator-ui-components/src/components/WfoForms/CreateForm.tsx +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright 2019-2023 SURF. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ -import React, { useCallback, useEffect, useState } from 'react'; - -import { UserInputFormWizard } from '@/components'; -import { handlePromiseErrorWithCallback } from '@/rtk'; -import { useStartFormMutation } from '@/rtk/endpoints/forms'; -import { Form, FormNotCompleteResponse } from '@/types/forms'; - -interface IProps { - /* eslint-disable @typescript-eslint/no-explicit-any */ - preselectedInput?: unknown; - formKey: string; - handleSubmit: (userInputs: any) => void; - handleCancel?: () => void; -} - -export function CreateForm(props: IProps) { - const { preselectedInput, formKey, handleSubmit, handleCancel } = props; - const [form, setForm] = useState
({}); - const { stepUserInput, hasNext } = form; - const [startForm] = useStartFormMutation(); - - const submit = useCallback( - (userInputs: object[]) => { - return startForm({ formKey, userInputs }) - .unwrap() - .then((form) => { - handleSubmit(form); - }); - }, - [formKey, handleSubmit, startForm], - ); - - useEffect(() => { - if (formKey) { - handlePromiseErrorWithCallback( - submit([]), - 510, - (json) => { - setForm({ - stepUserInput: json.form, - hasNext: json.meta?.hasNext ?? false, - }); - }, - ); - } - }, [formKey, submit, preselectedInput]); - - return ( -
- {stepUserInput && ( - - )} -
- ); -} diff --git a/packages/orchestrator-ui-components/src/components/WfoForms/UserInputForm.tsx b/packages/orchestrator-ui-components/src/components/WfoForms/UserInputForm.tsx deleted file mode 100644 index ba70824b8..000000000 --- a/packages/orchestrator-ui-components/src/components/WfoForms/UserInputForm.tsx +++ /dev/null @@ -1,697 +0,0 @@ -/* eslint-disable @typescript-eslint/no-explicit-any */ - -/* - * Copyright 2019-2023 SURF. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ -import React, { useContext, useState } from 'react'; - -import invariant from 'invariant'; -import { JSONSchema6 } from 'json-schema'; -import { isObject } from 'lodash'; -import cloneDeep from 'lodash/cloneDeep'; -import get from 'lodash/get'; -import { useTranslations } from 'next-intl'; -import { NextRouter } from 'next/router'; -import { filterDOMProps, joinName } from 'uniforms'; -import { JSONSchemaBridge } from 'uniforms-bridge-json-schema'; -import { AutoField, AutoForm } from 'uniforms-unstyled'; - -import { - EuiButton, - EuiButtonColor, - EuiFlexGroup, - EuiHorizontalRule, -} from '@elastic/eui'; - -import { ConfirmDialogHandler, ConfirmationDialogContext } from '@/contexts'; -import { useOrchestratorTheme, useWfoErrorMonitoring } from '@/hooks'; -import { WfoPlayFill } from '@/icons'; -import { FormValidationError, ValidationError } from '@/types/forms'; - -import { autoFieldFunction } from './AutoFieldLoader'; -import AutoFields from './AutoFields'; -import { userInputFormStyling } from './UserInputFormStyling'; - -type UniformJSONSchemaProperty = JSONSchema6 & { - uniforms: any; - defaultValue: any; -}; - -interface IProps { - router: NextRouter; - stepUserInput: JSONSchema6; - validSubmit: (userInput: { [index: string]: unknown }) => Promise; - cancel?: ConfirmDialogHandler; - previous: ConfirmDialogHandler; - hasNext?: boolean; - hasPrev?: boolean; - userInput: object; - isTask?: boolean; - isResuming?: boolean; - disabled?: boolean; -} - -interface Buttons { - previous: { - text?: string; - dialog?: string; - color?: EuiButtonColor; - }; - next: { - text?: string; - dialog?: string; - color?: EuiButtonColor; - }; -} - -declare module 'uniforms' { - interface FilterDOMProps { - customPropToFilter: never; - description: never; - const: never; - default: never; - required: never; - pattern: never; - examples: never; - allOf: never; - anyOf: never; - options: never; - } -} -filterDOMProps.register('description'); -filterDOMProps.register('const'); -filterDOMProps.register('default'); -filterDOMProps.register('required'); -filterDOMProps.register('pattern'); -filterDOMProps.register('examples'); -filterDOMProps.register('allOf'); -filterDOMProps.register('anyOf'); -filterDOMProps.register('options'); - -function resolveRef(reference: string, schema: Record) { - invariant( - reference.startsWith('#'), - 'Reference is not an internal reference, and only such are allowed: "%s"', - reference, - ); - - const resolvedReference = reference - .split('/') - .filter((part) => part && part !== '#') - .reduce((definition, next) => { - // FIXME: There is a ticket to fix this in the return value from GraphQL: https://git.ia.surfsara.nl/netdev/automation/projects/orchestrator/-/issues/1891 - // TLDR: currently the form properties may reference things in the forms $defs property but the forms $defs property doesn't exist but is called 'definitions' instead - const newDefinition = (() => { - if (next === '$defs' && !definition[next]) { - return definition['definitions']; - } - return definition[next]; - })(); - return newDefinition; - }, schema); - - invariant( - resolvedReference, - 'Reference not found in schema: "%s"', - reference, - ); - - return resolvedReference; -} - -class CustomTitleJSONSchemaBridge extends JSONSchemaBridge { - t: any; - - constructor(schema: JSONSchema6, validator: any, t: any) { - super(schema, validator); - this.t = t; - } - - translationKeyExists(key: string): boolean { - const translation = this.t(key); - return translation && translation !== key ? true : false; - } - - // This a copy of the super class function to provide a fix for https://github.com/vazco/uniforms/issues/863 - getField(name: string) { - return joinName(null, name).reduce( - (definition, next, nextIndex, array) => { - const previous = joinName(array.slice(0, nextIndex)); - const isRequired = get( - definition, - 'required', - get(this._compiledSchema, [previous, 'required'], []), - ).includes(next); - - const _key = joinName(previous, next); - const _definition = this._compiledSchema[_key] || {}; - - if (next === '$' || next === '' + parseInt(next, 10)) { - if ( - definition.anyOf && - definition.anyOf[0].type === 'array' - ) { - invariant( - definition.anyOf[0].type === 'array', - 'Field not found in schema: "%s"', - name, - ); - definition = Array.isArray(definition.anyOf[0].items) - ? definition.anyOf[0].items[parseInt(next, 10)] - : definition.anyOf[0].items; - } else { - invariant( - definition.type === 'array', - 'Field not found in schema: "%s"', - name, - ); - definition = Array.isArray(definition.items) - ? definition.items[parseInt(next, 10)] - : definition.items; - } - } else if (definition.type === 'object') { - invariant( - definition.properties, - 'Field properties not found in schema: "%s"', - name, - ); - definition = definition.properties[next]; - } else { - const [{ properties: combinedDefinition = {} } = {}] = [ - 'allOf', - 'anyOf', - 'oneOf', - ] - .filter((key) => definition[key]) - .map((key) => { - // FIXME: Correct type for `definition`. - const localDef = (definition[key] as any[]).map( - (subSchema) => - subSchema.$ref - ? resolveRef( - subSchema.$ref, - this.schema, - ) - : subSchema, - ); - return localDef.find( - ({ properties = {} }) => properties[next], - ); - }); - - definition = combinedDefinition[next]; - } - - invariant(definition, 'Field not found in schema: "%s"', name); - - if (definition.$ref) { - definition = resolveRef(definition.$ref, this.schema); - } - - ['allOf', 'anyOf', 'oneOf'].forEach((key) => { - if (definition[key]) { - // FIXME: Correct type for `definition`. - _definition[key] = (definition[key] as any[]).map( - (def) => - def.$ref - ? resolveRef(def.$ref, this.schema) - : def, - ); - } - }); - - // Naive computation of combined type, properties and required - const combinedPartials: any[] = [] - .concat( - _definition.allOf, - _definition.anyOf, - _definition.oneOf, - ) - .filter(Boolean); - - if (combinedPartials.length) { - const localProperties = definition.properties - ? { ...definition.properties } - : {}; - const localRequired = definition.required - ? definition.required.slice() - : []; - - combinedPartials.forEach((combinedPartial) => { - const { properties, required } = combinedPartial; - if (properties) { - Object.assign(localProperties, properties); - } - if (required) { - localRequired.push(...required); - } - - // Copy all properties instead of only type - for (const key in combinedPartial) { - if (combinedPartial[key] && !_definition[key]) { - _definition[key] = combinedPartial[key]; - - // This isExtensible check is introduced to fix this bug: https://github.com/workfloworchestrator/orchestrator-ui-library/issues/878 - // The reason the definition object is not extensible here but is in the same place in v1 is not known but - // deemed not worth to investigate further at this point. - if (Object.isExtensible(definition)) { - definition[key] = combinedPartial[key]; - } - } - } - }); - - if (Object.keys(localProperties).length > 0) { - _definition.properties = localProperties; - } - if (localRequired.length > 0) { - _definition.required = localRequired; - } - } - - this._compiledSchema[_key] = Object.assign(_definition, { - isRequired, - }); - - return definition; - }, - this.schema, - ); - } - - getProps(name: string) { - const props = super.getProps(name); - - const translationKey = name.replace(/\.\d+(.\d+)*/, '_fields'); // This is evaluates to name or name_fields - const nextIntlKey = `pydanticForms.backendTranslations.${translationKey}`; - let label = this.translationKeyExists(nextIntlKey) - ? this.t(nextIntlKey) - : props.label; - - // Mark required inputs. Might be delegated to the form components itself in the future. - if ( - props.required && - !props.readOnly && - !props.isDisabled && - !name.includes('.') - ) { - label = `${label} *`; - } - - props.label = label; - - const descriptionTranslationKey = `pydanticForms.backendTranslations.${translationKey}_info`; - props.description = this.translationKeyExists(descriptionTranslationKey) - ? this.t(descriptionTranslationKey) - : ' '; - - props.id = `input-${name}`; - - if (props.const) { - props.disabled = true; - props.default = props.const; - delete props['const']; - } - - if (props.initialCount === undefined) { - props.initialCount = props.minCount; - } - - return props; - } - - getInitialValue(name: string, props: Record = {}): any { - const { - default: _default, - const: _const, - type: _type, - } = this.getField(name); - let { - default: defaultValue = _default !== undefined - ? _default - : get(this.schema.default, name), - } = this._compiledSchema[name]; - const { const: constValue = _const, type = _type } = - this._compiledSchema[name]; - - // use const if present - if (defaultValue === undefined) defaultValue = constValue; - - // See https://github.com/vazco/uniforms/issues/749 - if (defaultValue === undefined) { - const nameArray = joinName(null, name); - const relativeName = nameArray.pop()!; - const parentName = joinName(nameArray); - if (parentName !== '') { - const model = this.getInitialValue(parentName, { - lookUpParent: true, - }); - defaultValue = get(model, relativeName); - } - } - - if (defaultValue !== undefined) return cloneDeep(defaultValue); - - if (type === 'array' && !props.lookUpParent && !name.endsWith('$')) { - const item = this.getInitialValue(joinName(name, '0')); - const items = props.initialCount || 0; - return Array(items).fill(item); - } - - if (type === 'object') { - return {}; - } - return undefined; - } -} - -function fillPreselection(form: JSONSchema6, router: NextRouter) { - const queryParams = router.query; - if (form && form.properties) { - Object.keys(queryParams).forEach((param) => { - if (form && form.properties && form.properties[param]) { - const customerInput = form.properties[ - param - ] as UniformJSONSchemaProperty; - if (!customerInput.uniforms) { - customerInput.uniforms = {}; - } - customerInput.uniforms.disabled = true; - customerInput.default = queryParams[param]; - } - }); - - // ipvany preselect - if (queryParams.prefix && queryParams.prefixlen) { - if (form && form.properties.ip_prefix) { - const ipPrefix = isObject(form.properties.ip_prefix) - ? form.properties.ip_prefix - : {}; - const ipPrefixInput = { - ...ipPrefix, - uniforms: { prefixMin: 0 }, - default: {}, - } as UniformJSONSchemaProperty; - if (!ipPrefixInput.uniforms) { - ipPrefixInput.uniforms = { prefixMin: 0 }; - } - ipPrefixInput.default = `${queryParams.prefix}/${queryParams.prefixlen}`; - ipPrefixInput.uniforms.prefixMin = parseInt( - queryParams.prefixlen as string, - 10, - ); - return { - ...form, - properties: { - ...form.properties, - ip_prefix: ipPrefixInput, - }, - }; - } - } - } - return form; -} - -export function WfoUserInputForm({ - router, - stepUserInput, - validSubmit, - cancel = () => {}, - previous = () => {}, - hasNext = false, - hasPrev = false, - userInput, - isTask = false, - isResuming = false, - disabled = false, -}: IProps) { - const t = useTranslations('pydanticForms.userInputForm'); - const tDialog = useTranslations('confirmationDialog'); - const { theme } = useOrchestratorTheme(); - const { showConfirmDialog } = useContext(ConfirmationDialogContext); - const [processing, setProcessing] = useState(false); - const [nrOfValidationErrors, setNrOfValidationErrors] = useState(0); - const [rootErrors, setRootErrors] = useState([]); - const { reportError } = useWfoErrorMonitoring(); - - const openLeavePageDialog = ( - leaveAction: ConfirmDialogHandler, - leaveQuestion?: string, - ) => { - const question = leaveQuestion || tDialog('leavePage'); - const subQuestion = leaveQuestion ? tDialog('leavePageSub') : ''; - const cancelButtonText = tDialog('stay'); - const confirmButtonText = tDialog('leave'); - - return () => - showConfirmDialog({ - question, - subQuestion, - onConfirm: leaveAction, - cancelButtonText, - confirmButtonText, - }); - }; - - const submit = async (userInput: any = {}) => { - if (!processing) { - setProcessing(true); - - try { - await validSubmit(userInput); - setProcessing(false); - return null; - } catch (error) { - setProcessing(false); - if (typeof error === 'object' && error !== null) { - const validationError = error as FormValidationError; - if (validationError?.status === 400) { - const json = validationError.data; - setNrOfValidationErrors(json.validation_errors.length); - setRootErrors( - json.validation_errors - .filter( - (e: ValidationError) => - e.loc[0] === '__root__', - ) - .map((e: ValidationError) => e.msg), - ); - throw Object.assign(new Error(), { - details: json.validation_errors.map( - (e: ValidationError) => ({ - message: e.msg, - params: e.ctx || {}, - dataPath: '.' + e.loc.join('.'), - }), - ), - }); - } - } - // Let the error escape, so it can be caught by our own onerror handler instead of being silenced by uniforms - setTimeout(() => { - reportError( - new Error(`Forms error: ${JSON.stringify({ error })}`), - ); - throw error; - }, 0); - - // The form will clear the errors so also remove the warning - setNrOfValidationErrors(0); - setRootErrors([]); - - // The error we got contains no validation errors so don't send it to uniforms - return null; - } - } - }; - - const onButtonClick = ( - e: - | React.MouseEvent - | React.MouseEvent, - question: string | undefined, - confirm: () => void, - ) => { - if (!question) { - return confirm(); - } - - showConfirmDialog({ - question: question, - onConfirm: confirm, - }); - }; - - const renderButtons = (buttons: Buttons) => { - const prevButton = hasPrev ? ( - ) => { - onButtonClick( - e, - buttons.previous.dialog, - openLeavePageDialog(previous, t('previousQuestion')), - ); - }} - disabled={disabled} - > - {buttons.previous.text ?? t('previous')} - - ) : !isResuming ? ( -
{ - onButtonClick( - e, - buttons.previous.dialog, - openLeavePageDialog(cancel), - ); - }} - css={{ - cursor: 'pointer', - color: theme.colors.link, - fontWeight: theme.font.weight.bold, - marginLeft: '8px', - display: 'flex', - alignItems: 'center', - }} - > - {buttons.previous.text ?? t('cancel')} -
- ) : ( -
- ); - - const nextButtonTranslationKey: string = (() => { - if (isResuming) { - return isTask ? 'resumeTask' : 'resumeWorkflow'; - } - return isTask ? 'startTask' : 'startWorkflow'; - })(); - - const nextButton = hasNext ? ( - - {buttons.next.text ?? t('next')} - - ) : ( - - } - iconSide="right" - disabled={disabled} - > - {buttons.next.text ?? t(nextButtonTranslationKey)} - - ); - - return ( - <> - - - - {prevButton} - {nextButton} - - - ); - }; - - const prefilledForm = fillPreselection(stepUserInput, router); - const bridge = new CustomTitleJSONSchemaBridge( - prefilledForm, - () => {}, - useTranslations(), - ); - const AutoFieldProvider = AutoField.componentDetectorContext.Provider; - - // Get the Button config from the form default values, or default to empty config - const buttonsFromSchema = (prefilledForm.properties?.buttons && - prefilledForm.properties?.buttons !== true && - prefilledForm.properties?.buttons.default) || { - previous: {}, - next: {}, - }; - - const buttons: Buttons = buttonsFromSchema as unknown as Buttons; - - return ( -
-
-
- {stepUserInput.title && - stepUserInput.title !== 'unknown' && ( -

{stepUserInput.title}

- )} - - - - {/* Show top level validation info about backend validation */} - {nrOfValidationErrors > 0 && ( -
- - {t('inputFieldsHaveValidationErrors', { - nrOfValidationErrors: - nrOfValidationErrors, - })} - -
- )} - {rootErrors.length > 0 && ( -
- - {rootErrors.map((error, index) => ( -
- {error} -
- ))} -
-
- )} - {renderButtons(buttons)} -
-
-
-
-
- ); -} diff --git a/packages/orchestrator-ui-components/src/components/WfoForms/UserInputFormStyling.ts b/packages/orchestrator-ui-components/src/components/WfoForms/UserInputFormStyling.ts deleted file mode 100644 index 7757d5858..000000000 --- a/packages/orchestrator-ui-components/src/components/WfoForms/UserInputFormStyling.ts +++ /dev/null @@ -1,80 +0,0 @@ -import { css } from '@emotion/react'; - -// Todo: theme with decent colors from theme (style was copied from v1) -const PRIMARY_COLOR = '#0077cc'; - -export const userInputFormStyling = css` - .user-input-form { - h3 { - padding: 20px 0; - font-size: larger; - font-weight: bold; - margin-bottom: 15px; - } - - .form-input { - margin: 20px 0; - - padding-bottom: 20px; - - em { - margin-bottom: 1px; - } - - &.first_lightpath, - &.second_lightpath, - p.label { - text-transform: uppercase; - font-weight: bold; - color: ${PRIMARY_COLOR}; - } - - &.downgrade_redundant_lp_choice, - &.service_ports_primary, - &.service_ports_secondary { - margin-left: 40px; - } - - b { - // styles the arrows of numeric input - margin-top: 4px; - margin-left: 1px; - } - } - - section.form-errors { - padding-bottom: 20px; - } - - .actions { - display: flex; - margin-top: 25px; - - .notes { - display: flex; - align-items: center; - flex-grow: 2; - } - - label { - margin-right: 10px; - } - } - } - - /* EUI specific styling for the forms */ - - .euiFormRow { - margin-bottom: 26px; // For service ports this add margin to the label?? - } - - .euiFormRow__labelWrapper { - flex-direction: column; - margin-top: -10px; - } - - .euiFormRow__label__large { - font-size: +1.1em; - margin-bottom: 0; - } -`; diff --git a/packages/orchestrator-ui-components/src/components/WfoForms/UserInputFormWizard.tsx b/packages/orchestrator-ui-components/src/components/WfoForms/UserInputFormWizard.tsx deleted file mode 100644 index bf78d2c03..000000000 --- a/packages/orchestrator-ui-components/src/components/WfoForms/UserInputFormWizard.tsx +++ /dev/null @@ -1,127 +0,0 @@ -/* - * Copyright 2019-2023 SURF. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ -import React, { useEffect, useState } from 'react'; - -import { useRouter } from 'next/router'; -import hash from 'object-hash'; - -import type { ConfirmDialogHandler } from '@/contexts'; -import { HttpStatus, handlePromiseErrorWithCallback } from '@/rtk'; -import { FormNotCompleteResponse, InputForm } from '@/types/forms'; - -import { WfoUserInputForm } from './UserInputForm'; - -interface Form { - form: InputForm; - hasNext?: boolean; -} - -interface UserInputFormWizardProps { - stepUserInput: InputForm; - stepSubmit: (processInput: object[]) => Promise; - cancel?: ConfirmDialogHandler; - isTask: boolean; - hasNext?: boolean; - isResuming?: boolean; - allowSubmit?: boolean; -} - -function stop(e: React.SyntheticEvent) { - if (e !== undefined && e !== null) { - e.preventDefault(); - e.stopPropagation(); - } -} - -export const UserInputFormWizard = ({ - hasNext = false, - stepUserInput, - stepSubmit, - cancel, - isTask, - isResuming = false, - allowSubmit = true, -}: UserInputFormWizardProps) => { - const router = useRouter(); - const [forms, setForms] = useState([ - { form: stepUserInput, hasNext: hasNext }, - ]); - const [userInputs, setUserInputs] = useState([]); - - useEffect(() => { - setForms([{ form: stepUserInput, hasNext: hasNext }]); - }, [hasNext, stepUserInput]); - - const previous: ConfirmDialogHandler = (e) => { - if (e) { - stop(e); - } - const current = forms.pop(); - setForms(forms.filter((item) => item !== current)); - }; - - const submit = (currentFormData: object) => { - const newUserInputs = userInputs.slice(0, forms.length - 1); - newUserInputs.push(currentFormData); - - const promise = stepSubmit(newUserInputs); - const callback = (data: FormNotCompleteResponse) => { - window.scrollTo(0, 0); - setForms([ - ...forms, - { form: data.form, hasNext: data.meta?.hasNext }, - ]); - setUserInputs(newUserInputs); - }; - - return handlePromiseErrorWithCallback( - promise, - HttpStatus.FormNotComplete, - callback, - ); - }; - - const currentForm = forms[forms.length - 1]; - const currentUserInput = userInputs[forms.length - 1]; - if (!currentForm || !currentForm.form.properties) { - return null; - } - - /* Generate a key based on input widget names that results in a new - * clean instance + rerender of UserInputForm if the form changes. Without this, state of previous, - * wizard step can cause wrong/weird default values for forms inputs. - * - * Note: to ensure a new form for multiple form wizard steps with exactly the same fields and labels on - * the form the hash is calculated on the form object itself + length, which generates a unique hash as it - * has a changing ".length" attribute. - * */ - const key = hash.sha1({ form: currentForm.form, length: forms.length }); - return ( - 1} - cancel={cancel} - userInput={currentUserInput} - isTask={isTask} - isResuming={isResuming} - disabled={!allowSubmit} - /> - ); -}; diff --git a/packages/orchestrator-ui-components/src/components/WfoForms/formFields/AcceptField.tsx b/packages/orchestrator-ui-components/src/components/WfoForms/formFields/AcceptField.tsx deleted file mode 100644 index b2fa92af1..000000000 --- a/packages/orchestrator-ui-components/src/components/WfoForms/formFields/AcceptField.tsx +++ /dev/null @@ -1,243 +0,0 @@ -/* - * Copyright 2019-2023 SURF. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ -import React, { useReducer } from 'react'; - -import { useTranslations } from 'next-intl'; -import { connectField, filterDOMProps } from 'uniforms'; - -import { EuiCheckbox, EuiFlexItem, EuiText } from '@elastic/eui'; - -import { useWithOrchestratorTheme } from '@/hooks'; - -import { getAcceptFieldStyles } from './AcceptFieldStyling'; -import { FieldProps } from './types'; - -type AcceptItemType = - | 'info' - | 'label' - | 'warning' - | 'url' - | 'checkbox' - | '>checkbox' - | 'checkbox?' - | '>checkbox?' - | 'skip' - | 'margin' - | 'value'; -type AcceptItem = [string, AcceptItemType, Record?]; -type AcceptValue = 'SKIPPED' | 'ACCEPTED' | 'INCOMPLETE'; - -export type AcceptFieldProps = FieldProps; - -declare module 'uniforms' { - interface FilterDOMProps { - data: never; - } -} - -filterDOMProps.register('data'); - -interface AcceptState { - checks: { [index: number]: boolean }; - skip: boolean; - allChecked: boolean; -} - -interface Action { - field: number; - type: string; - value: boolean; -} - -function Accept({ - disabled, - className = '', - name, - onChange, - error, - showInlineError, - errorMessage, - data, - ...props -}: AcceptFieldProps) { - const t = useTranslations(); - const { acceptFieldStyle } = useWithOrchestratorTheme(getAcceptFieldStyles); - - const legacy = !data; - const i18nBaseKey = data - ? `pydanticForms.backendTranslations.${name}_accept` - : 'pydanticForms.backendTranslations'; - - data = data ?? [ - [name, 'label', {}], - [`${name}_info`, 'info', {}], - [name, 'checkbox', {}], - ]; - - const [state, dispatch] = useReducer( - (state: AcceptState, action: Action) => { - if (action.type === 'skip') { - state.skip = action.value; - state.checks = {}; - } else { - state.checks[action.field] = action.value; - } - - // We intentionally skip optional checkboxes here - state.allChecked = data! - .map( - (entry: AcceptItem, index: number) => - [entry, state.checks[index] || false] as [ - AcceptItem, - boolean, - ], - ) - .filter((entry: [AcceptItem, boolean]) => - entry[0][1].endsWith('checkbox'), - ) - .map((entry: [AcceptItem, boolean]) => entry[1]) - .every((check: boolean) => check); - - onChange( - state.skip - ? 'SKIPPED' - : state.allChecked - ? 'ACCEPTED' - : 'INCOMPLETE', - ); - - return { ...state }; - }, - { checks: {}, skip: false, allChecked: false }, - ); - - return ( - -
- {data.map((entry, index) => { - const label = t(`${i18nBaseKey}.${entry[0]}`, entry[2]); - - switch (entry[1]) { - case 'label': - return ( - - ); - case 'info': - return ( - - {label} - - ); - case 'url': - return ( - - ); - case 'value': - return ( -
- -
- ); - case 'margin': - return
; - case 'warning': - return ( - - ); - case 'skip': - return ( - , - ) => { - const target = - e.target as HTMLInputElement; - dispatch({ - field: index, - type: 'skip', - value: target.checked, - }); - }} - checked={state.skip} - label={label} - className={'skip'} - /> - ); - default: - return ( - ') - ? 'level_2' - : undefined - } - onChange={( - e: React.FormEvent, - ) => { - const target = - e.target as HTMLInputElement; - - dispatch({ - field: index, - type: 'check', - value: target.checked, - }); - }} - checked={state.checks[index]} - label={label} - readOnly={state.skip || disabled} - /> - ); - } - })} - - {error && showInlineError && ( - -
{errorMessage}
-
- )} -
-
- ); -} - -export const AcceptField = connectField(Accept); diff --git a/packages/orchestrator-ui-components/src/components/WfoForms/formFields/AcceptFieldStyling.ts b/packages/orchestrator-ui-components/src/components/WfoForms/formFields/AcceptFieldStyling.ts deleted file mode 100644 index 71b39b351..000000000 --- a/packages/orchestrator-ui-components/src/components/WfoForms/formFields/AcceptFieldStyling.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { css } from '@emotion/react'; - -import { WfoTheme } from '@/hooks'; - -export const getAcceptFieldStyles = ({ theme }: WfoTheme) => { - const acceptFieldStyle = css({ - '.acceptField': { - 'label.warning': { - color: theme.colors.danger, - }, - '.skip': { - color: theme.colors.success, - fontStyle: 'italic', - }, - - // Don't touch the margin + padding: they also control if the user can click on the checkbox instead of label - '.level_2': { - marginLeft: '24px', - padding: 0, - label: { - marginTop: 0, - }, - }, - - '.labelTitle': { - fontWeight: '600', - color: theme.colors.text, - }, - }, - }); - - return { - acceptFieldStyle: acceptFieldStyle, - }; -}; diff --git a/packages/orchestrator-ui-components/src/components/WfoForms/formFields/BoolField.tsx b/packages/orchestrator-ui-components/src/components/WfoForms/formFields/BoolField.tsx deleted file mode 100644 index ab6fc7d86..000000000 --- a/packages/orchestrator-ui-components/src/components/WfoForms/formFields/BoolField.tsx +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright 2019-2023 SURF. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ -import React from 'react'; - -import { connectField, filterDOMProps } from 'uniforms'; - -import { EuiCheckbox, EuiFlexItem, EuiFormRow, EuiText } from '@elastic/eui'; - -import { FieldProps } from '@/components'; -import { getCommonFormFieldStyles } from '@/components/WfoForms/formFields/commonStyles'; -import { useWithOrchestratorTheme } from '@/hooks'; - -import { boolFieldStyling } from './BoolFieldStyling'; - -export type BoolFieldProps = FieldProps; - -function Bool({ - disabled, - id, - className = '', - label, - description, - name, - onChange, - readOnly, - value, - error, - showInlineError, - errorMessage, - ...props -}: BoolFieldProps) { - const { formRowStyle } = useWithOrchestratorTheme(getCommonFormFieldStyles); - - return ( - -
- {description}} - error={showInlineError ? errorMessage : false} - isInvalid={error} - id={id} - fullWidth - > -  } - onChange={() => - !disabled && !readOnly && onChange(!value) - } - /> - -
-
- ); -} - -export const BoolField = connectField(Bool, { kind: 'leaf' }); diff --git a/packages/orchestrator-ui-components/src/components/WfoForms/formFields/BoolFieldStyling.ts b/packages/orchestrator-ui-components/src/components/WfoForms/formFields/BoolFieldStyling.ts deleted file mode 100644 index f6d846a43..000000000 --- a/packages/orchestrator-ui-components/src/components/WfoForms/formFields/BoolFieldStyling.ts +++ /dev/null @@ -1,64 +0,0 @@ -import { css } from '@emotion/react'; - -// Todo: theme with decent colors from theme (style was copied from v1) -const PRIMARY_COLOR = '#0077cc'; -const LIGHT_GREY_COLOR = '#eff2f3'; -const MEDIUM_GREY_COLOR = '#a6b6be'; - -export const boolFieldStyling = css` - - .bool-field { - .euiCheckbox .euiCheckbox__input ~ .euiCheckbox__label { - z-index: unset; - } - - label { - display: inline-block; - margin: 3px 0; - &.info { - margin-left: 10px; - cursor: pointer; - } - } - - input[type="checkbox"] + label span { - font-size: 11px; - background-color: white; - border: 1px solid ${PRIMARY_COLOR}; - border-radius: 3px; - padding: 1px 2px; - margin: 2px 0; - cursor: pointer; - i { - color: transparent; - padding: 0 1px; - } - } - - input[type="checkbox"]:disabled + label span { - border: 1px solid ${MEDIUM_GREY_COLOR} - background-color: ${LIGHT_GREY_COLOR}; - cursor: not-allowed; - } - - input[type="checkbox"]:checked + label span { - border: 2px solid ${PRIMARY_COLOR}; - border-radius: 2px; - box-shadow: none; - padding: 0; - i { - background-color: ${PRIMARY_COLOR}; - color: white; - padding: 3px 2px; - } - } - - input[type="checkbox"]:checked:disabled + label span { - border: 3px solid ${MEDIUM_GREY_COLOR}; - cursor: default; - i { - background-color: ${MEDIUM_GREY_COLOR}; - } - } - } -`; diff --git a/packages/orchestrator-ui-components/src/components/WfoForms/formFields/ConnectedSelectField.tsx b/packages/orchestrator-ui-components/src/components/WfoForms/formFields/ConnectedSelectField.tsx deleted file mode 100644 index 81d536eae..000000000 --- a/packages/orchestrator-ui-components/src/components/WfoForms/formFields/ConnectedSelectField.tsx +++ /dev/null @@ -1,19 +0,0 @@ -import React from 'react'; - -import { connectField } from 'uniforms'; - -import type { SelectFieldProps } from './SelectField'; -import { UnconnectedSelectField } from './SelectField'; - -/* - The selectField has a connected and unconnected version. When a SelectField is called from another field that - is connected it can cause errors as described here: https://github.com/workfloworchestrator/orchestrator-ui-library/issues/681 - When called directly it will still need the props that the connectField function provides so it has a connected version as well. -*/ -const ConnectedSelect = (props: SelectFieldProps) => { - return ; -}; - -export const ConnectedSelectField = connectField(ConnectedSelect, { - kind: 'leaf', -}); diff --git a/packages/orchestrator-ui-components/src/components/WfoForms/formFields/CustomerField.tsx b/packages/orchestrator-ui-components/src/components/WfoForms/formFields/CustomerField.tsx deleted file mode 100644 index 5025fa958..000000000 --- a/packages/orchestrator-ui-components/src/components/WfoForms/formFields/CustomerField.tsx +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright 2019-2023 SURF. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ -import React from 'react'; - -import _ from 'lodash'; -import { useTranslations } from 'next-intl'; -import { connectField, useField } from 'uniforms'; - -import { useGetCustomersQuery } from '@/rtk/endpoints'; - -import { - SelectFieldProps, - UnconnectedSelectField, -} from './SelectField/SelectField'; - -export type CustomerFieldProps = Omit< - SelectFieldProps, - 'placeholder' | 'transform' | 'allowedValues' ->; - -function Customer({ ...props }: CustomerFieldProps) { - const t = useTranslations('pydanticForms'); - const [, context] = useField(props.name, {}, { absoluteName: true }); - - const { data: customers, isLoading } = useGetCustomersQuery(); - - const uuidCustomerNameMap = new Map(); - - if (!isLoading && customers) { - customers?.map((customer) => { - uuidCustomerNameMap.set( - customer.customerId, - `${customer.shortcode} - ${customer.fullname}`, - ); - }); - } - - const genericFieldName = props.name.split('.').shift(); - const valueFromContext = - genericFieldName && context.model[genericFieldName]; - - // RVL:19-89-24 This is the only way I found to make sure the value is set to undefined when the value - // is removed from the form (i.e. when the user clicks the "-" button in the form) for the last list item. - const value = - Array.isArray(valueFromContext) && _.isEmpty(valueFromContext) - ? '' - : props.value; - - return ( - uuidCustomerNameMap.get(uuid) || uuid} - disabled={isLoading || props.disabled} - value={value} - placeholder={ - !isLoading - ? t('widgets.customer.placeholder') - : t('widgets.customer.loading') - } - /> - ); -} - -export const CustomerField = connectField(Customer, { kind: 'leaf' }); diff --git a/packages/orchestrator-ui-components/src/components/WfoForms/formFields/DateField.tsx b/packages/orchestrator-ui-components/src/components/WfoForms/formFields/DateField.tsx deleted file mode 100644 index b9b45ca65..000000000 --- a/packages/orchestrator-ui-components/src/components/WfoForms/formFields/DateField.tsx +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright 2019-2023 SURF. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ -import React from 'react'; - -import { connectField, filterDOMProps } from 'uniforms'; - -import { FieldProps } from './types'; - -const DateConstructor = (typeof global === 'object' ? global : window).Date; -const dateFormat = (value?: Date) => { - return value?.toISOString().slice(0, -8); -}; - -export type DateFieldProps = FieldProps; - -function Date({ - disabled, - id, - inputRef, - label, - max, - min, - name, - onChange, - readOnly, - placeholder, - value, - ...props -}: DateFieldProps) { - return ( -
- {label && } - - { - const date = new DateConstructor( - event.target.valueAsNumber, - ); - if (date.getFullYear() < 10000) { - onChange(date); - } else if (isNaN(event.target.valueAsNumber)) { - onChange(undefined); - } - }} - placeholder={placeholder} - readOnly={readOnly} - ref={inputRef} - type="datetime-local" - value={dateFormat(value) ?? ''} - /> -
- ); -} - -export const DateField = connectField(Date, { kind: 'leaf' }); diff --git a/packages/orchestrator-ui-components/src/components/WfoForms/formFields/DividerField.tsx b/packages/orchestrator-ui-components/src/components/WfoForms/formFields/DividerField.tsx deleted file mode 100644 index 0dba1c749..000000000 --- a/packages/orchestrator-ui-components/src/components/WfoForms/formFields/DividerField.tsx +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright 2019-2023 SURF. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ -import React from 'react'; - -import { connectField } from 'uniforms'; - -import { EuiHorizontalRule } from '@elastic/eui'; - -import { FieldProps } from '@/components'; - -export type DividerFieldProps = FieldProps; - -function Divider({ id }: DividerFieldProps) { - return ; -} - -export const DividerField = connectField(Divider, { kind: 'leaf' }); diff --git a/packages/orchestrator-ui-components/src/components/WfoForms/formFields/ErrorField.tsx b/packages/orchestrator-ui-components/src/components/WfoForms/formFields/ErrorField.tsx deleted file mode 100644 index f9fe98a4b..000000000 --- a/packages/orchestrator-ui-components/src/components/WfoForms/formFields/ErrorField.tsx +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright 2019-2023 SURF. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ -import React from 'react'; - -import { connectField, filterDOMProps } from 'uniforms'; - -import { FieldProps } from '@/components'; - -export type ErrorFieldProps = FieldProps; - -// onChange not used on purpose -function Error({ - children, - // eslint-disable-next-line @typescript-eslint/no-unused-vars - onChange, - error, - errorMessage, - ...props -}: ErrorFieldProps) { - return !error ? null : ( -
{children || errorMessage}
- ); -} - -export const ErrorField = connectField(Error, { - initialValue: false, - kind: 'leaf', -}); diff --git a/packages/orchestrator-ui-components/src/components/WfoForms/formFields/ErrorsField.tsx b/packages/orchestrator-ui-components/src/components/WfoForms/formFields/ErrorsField.tsx deleted file mode 100644 index 1b534ddf8..000000000 --- a/packages/orchestrator-ui-components/src/components/WfoForms/formFields/ErrorsField.tsx +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright 2019-2023 SURF. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ -import React, { HTMLProps } from 'react'; - -import { filterDOMProps, useForm } from 'uniforms'; - -export type ErrorsFieldProps = HTMLProps; - -export const ErrorsField = (props: ErrorsFieldProps) => { - const { error, schema } = useForm(); - return !error && !props.children ? null : ( -
- {props.children} - -
    - {schema.getErrorMessages(error).map((message, index) => ( -
  • {message}
  • - ))} -
-
- ); -}; diff --git a/packages/orchestrator-ui-components/src/components/WfoForms/formFields/LabelField.tsx b/packages/orchestrator-ui-components/src/components/WfoForms/formFields/LabelField.tsx deleted file mode 100644 index 01f7bb8ac..000000000 --- a/packages/orchestrator-ui-components/src/components/WfoForms/formFields/LabelField.tsx +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright 2019-2023 SURF. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ -import React from 'react'; - -import { connectField, filterDOMProps } from 'uniforms'; - -import { FieldProps } from '@/components'; -import { useOrchestratorTheme } from '@/hooks'; - -export type LabelFieldProps = FieldProps; - -// onChange not used on purpose -function Label({ id, value, label, ...props }: LabelFieldProps) { - const { theme } = useOrchestratorTheme(); - - return ( -
- -
- ); -} - -export const LabelField = connectField(Label, { kind: 'leaf' }); diff --git a/packages/orchestrator-ui-components/src/components/WfoForms/formFields/ListAddField.tsx b/packages/orchestrator-ui-components/src/components/WfoForms/formFields/ListAddField.tsx deleted file mode 100644 index ece980e8c..000000000 --- a/packages/orchestrator-ui-components/src/components/WfoForms/formFields/ListAddField.tsx +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Copyright 2019-2023 SURF. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ -import React from 'react'; - -import cloneDeep from 'lodash/cloneDeep'; -import { useTranslations } from 'next-intl'; -import { connectField, filterDOMProps, joinName, useField } from 'uniforms'; - -import { EuiIcon, EuiText } from '@elastic/eui'; - -import { useOrchestratorTheme } from '@/hooks'; - -import { FieldProps } from './types'; - -export type ListAddFieldProps = FieldProps< - string, - { initialCount?: number; outerList?: boolean } ->; - -// onChange not used on purpose -function ListAdd({ - disabled, - initialCount, - name, - readOnly, - value, - outerList = false, - ...props -}: ListAddFieldProps) { - const { theme } = useOrchestratorTheme(); - const t = useTranslations('pydanticForms.backendTranslations'); - - const nameParts = joinName(null, name); - const parentName = joinName(nameParts.slice(0, -1)); - const parent = useField< - { initialCount?: number; maxCount?: number }, - unknown[] - >(parentName, { initialCount }, { absoluteName: true })[0]; - const parentValueCount = parent.value?.length ?? 0; - const limitNotReached = - !disabled && (!parent.maxCount || parent.maxCount > parentValueCount); - const count = 1 + Math.max((initialCount ?? 0) - parentValueCount, 0); - - function onAction(event: React.KeyboardEvent | React.MouseEvent) { - if ( - limitNotReached && - !readOnly && - (!('key' in event) || event.key === 'Enter') - ) { - const newRowsValue = Array(count).fill(cloneDeep(value)); - parent.onChange(parent.value!.concat(newRowsValue)); - } - } - - return ( -
- - -
- ); -} - -export const ListAddField = connectField(ListAdd, { - initialValue: false, - kind: 'leaf', -}); diff --git a/packages/orchestrator-ui-components/src/components/WfoForms/formFields/ListDelField.tsx b/packages/orchestrator-ui-components/src/components/WfoForms/formFields/ListDelField.tsx deleted file mode 100644 index 46b663378..000000000 --- a/packages/orchestrator-ui-components/src/components/WfoForms/formFields/ListDelField.tsx +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Copyright 2019-2023 SURF. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ -import React from 'react'; - -import { useTranslations } from 'next-intl'; -import { connectField, filterDOMProps, joinName, useField } from 'uniforms'; - -import { EuiIcon, EuiText } from '@elastic/eui'; - -import { useOrchestratorTheme } from '@/hooks'; - -import { FieldProps } from './types'; - -export type ListDelFieldProps = FieldProps< - null, - { initialCount?: number; itemProps?: object; outerList?: boolean } ->; - -// onChange prop not used on purpose -function ListDel({ - disabled, - name, - readOnly, - id, - outerList = false, - ...props -}: ListDelFieldProps) { - const { theme } = useOrchestratorTheme(); - const t = useTranslations('pydanticForms.backendTranslations'); - - const nameParts = joinName(null, name); - const nameIndex = +nameParts[nameParts.length - 1]; - const parentName = joinName(nameParts.slice(0, -1)); - const parent = useField<{ minCount?: number }, unknown[]>( - parentName, - {}, - { absoluteName: true }, - )[0]; - - const parentValueCount = parent.value?.length ?? 0; - - // Make a row deletable only if its: - const isDeletable: boolean = - !disabled && - !readOnly && - (!parent.minCount || parentValueCount > parent.minCount); - - function onAction(event: React.KeyboardEvent | React.MouseEvent) { - if (isDeletable && (!('key' in event) || event.key === 'Enter')) { - const value = parent?.value!.slice(); - value.splice(nameIndex, 1); - parent.onChange(value); - } - } - - return ( -
- - -
- ); -} - -export const ListDelField = connectField(ListDel, { - initialValue: false, - kind: 'leaf', -}); diff --git a/packages/orchestrator-ui-components/src/components/WfoForms/formFields/ListField.tsx b/packages/orchestrator-ui-components/src/components/WfoForms/formFields/ListField.tsx deleted file mode 100644 index 9afd48a14..000000000 --- a/packages/orchestrator-ui-components/src/components/WfoForms/formFields/ListField.tsx +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Copyright 2019-2023 SURF. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ -import React, { Children, cloneElement, isValidElement } from 'react'; - -import range from 'lodash/range'; -import { connectField, filterDOMProps, joinName, useField } from 'uniforms'; - -import { EuiFlexItem, EuiFormRow, EuiText } from '@elastic/eui'; - -import { getCommonFormFieldStyles } from '@/components/WfoForms/formFields/commonStyles'; -import { useWithOrchestratorTheme } from '@/hooks'; - -import { ListAddField } from './ListAddField'; -import { ListItemField } from './ListItemField'; -import { listFieldStyling } from './listFieldStyling'; -import { FieldProps } from './types'; - -declare module 'uniforms' { - interface FilterDOMProps { - items: never; - uniqueItems: never; - outerList: never; - } -} -filterDOMProps.register('minCount'); -filterDOMProps.register('maxCount'); -filterDOMProps.register('items'); -filterDOMProps.register('uniqueItems'); -filterDOMProps.register('outerList'); - -export type ListFieldProps = FieldProps< - unknown[], - { initialCount?: number; itemProps?: object; uniqueItems?: boolean }, - null, - HTMLUListElement ->; - -function List({ - disabled, - children = , - initialCount = 1, - itemProps, - label, - description, - name, - value, - error, - showInlineError, - errorMessage, - ...props -}: ListFieldProps) { - const { formRowStyle } = useWithOrchestratorTheme(getCommonFormFieldStyles); - - const child = useField(joinName(name, '$'), {}, { absoluteName: true })[0]; - const hasListAsChild = child.fieldType === Array; - - return ( - -
- {description}} - error={showInlineError ? errorMessage : false} - isInvalid={error} - id={`formrow-${name}`} - fullWidth - > - <> - -
    - {range(Math.max(value?.length ?? 0, initialCount ?? 0)).map( - (itemIndex) => - Children.map(children, (child, childIndex) => - isValidElement(child) - ? cloneElement(child, { - key: `${itemIndex}-${childIndex}`, - // eslint-disable-next-line @typescript-eslint/ban-ts-comment - // @ts-ignore - name: child.props.name?.replace( - '$', - itemIndex.toString(), - ), - outerList: hasListAsChild, - ...itemProps, - }) - : child, - ), - )} - -
-
-
- ); -} - -export const ListField = connectField(List); diff --git a/packages/orchestrator-ui-components/src/components/WfoForms/formFields/ListItemField.tsx b/packages/orchestrator-ui-components/src/components/WfoForms/formFields/ListItemField.tsx deleted file mode 100644 index f001eeab9..000000000 --- a/packages/orchestrator-ui-components/src/components/WfoForms/formFields/ListItemField.tsx +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright 2019-2023 SURF. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ -import React, { ReactNode } from 'react'; - -import { connectField } from 'uniforms'; -import { AutoField } from 'uniforms-unstyled'; - -import { ListDelField } from './ListDelField'; - -export type ListItemFieldProps = { - children?: ReactNode; - name: string; - outerList?: boolean; -}; - -function ListItem({ - children = , - outerList = false, -}: ListItemFieldProps) { - return ( -
  • - {children} - -
  • - ); -} - -export const ListItemField = connectField(ListItem, { initialValue: false }); diff --git a/packages/orchestrator-ui-components/src/components/WfoForms/formFields/ListSelectField.tsx b/packages/orchestrator-ui-components/src/components/WfoForms/formFields/ListSelectField.tsx deleted file mode 100644 index cba473ea4..000000000 --- a/packages/orchestrator-ui-components/src/components/WfoForms/formFields/ListSelectField.tsx +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Copyright 2019-2023 SURF. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -/* NOTE: This component is only needed to avoid the circular import that started to be a problem -after the upgrade to react-script 5.0. The original SelectField would import itself to handle the list: -that seems to be impossible with the new webpack. - */ -import React from 'react'; - -import { get } from 'lodash'; -import { joinName, useField, useForm } from 'uniforms'; - -import { ListField, ListFieldProps } from './ListField'; -import { ListItemField } from './ListItemField'; -// Avoid circular deps -import { UnconnectedSelectField } from './SelectField'; -import { FieldProps } from './types'; - -export type ListSelectFieldProps = FieldProps< - string | string[], - { allowedValues?: string[]; transform?(value: string): string } ->; - -export function ListSelectField({ - allowedValues = [], - fieldType, - name, - transform, - ...props -}: ListSelectFieldProps) { - const nameArray = joinName(null, name); - let parentName = joinName(nameArray.slice(0, -1)); - - // We can't call useField conditionally so we call it for ourselves if there is no parent - if (parentName === '') { - parentName = name; - } - const parent = useField(parentName, {}, { absoluteName: true })[0]; - const { model } = useForm(); - - if (parentName !== name) { - if ( - parent.fieldType === Array && - (parent as ListFieldProps).uniqueItems - ) { - const allValues: string[] = get(model, parentName, []); - const chosenValues = allValues.filter( - (_item, index) => - index.toString() !== nameArray[nameArray.length - 1], - ); - - allowedValues = allowedValues.filter( - (value) => !chosenValues.includes(value), - ); - } - } - - if (fieldType === Array) { - return ( - - - - - - ); - } else { - return ( - - ); - } -} diff --git a/packages/orchestrator-ui-components/src/components/WfoForms/formFields/LocationCodeField.tsx b/packages/orchestrator-ui-components/src/components/WfoForms/formFields/LocationCodeField.tsx deleted file mode 100644 index ba4a36947..000000000 --- a/packages/orchestrator-ui-components/src/components/WfoForms/formFields/LocationCodeField.tsx +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright 2019-2023 SURF. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ -import React, { useEffect, useState } from 'react'; - -import { useTranslations } from 'next-intl'; -import { connectField, filterDOMProps } from 'uniforms'; - -import { SelectFieldProps, UnconnectedSelectField } from '@/components'; -import { useLocationCodesQuery } from '@/rtk/endpoints/formFields'; - -export type LocationCodeFieldProps = { locationCodes?: string[] } & Omit< - SelectFieldProps, - 'placeholder' | 'allowedValues' ->; - -declare module 'uniforms' { - interface FilterDOMProps { - locationCodes: never; - } -} - -filterDOMProps.register('locationCodes'); - -function LocationCode({ locationCodes, ...props }: LocationCodeFieldProps) { - const t = useTranslations('pydanticForms'); - const [codes, setCodes] = useState(locationCodes ?? []); - const { data, error } = useLocationCodesQuery(); - - useEffect(() => { - if (data) { - setCodes(data); - } - if (error) { - console.error(error); - setCodes([]); - } - }, [data, error]); - - return ( - - ); -} - -export const LocationCodeField = connectField(LocationCode, { kind: 'leaf' }); diff --git a/packages/orchestrator-ui-components/src/components/WfoForms/formFields/LongTextField.tsx b/packages/orchestrator-ui-components/src/components/WfoForms/formFields/LongTextField.tsx deleted file mode 100644 index ed8b79958..000000000 --- a/packages/orchestrator-ui-components/src/components/WfoForms/formFields/LongTextField.tsx +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright 2019-2023 SURF. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ -import React from 'react'; - -import { connectField, filterDOMProps } from 'uniforms'; - -import { EuiFormRow, EuiText, EuiTextArea } from '@elastic/eui'; - -import { FieldProps } from '@/components'; - -export type LongTextFieldProps = FieldProps< - string, - object, - HTMLTextAreaElement ->; - -function LongText({ - disabled, - id, - label, - description, - name, - onChange, - placeholder, - readOnly, - value, - error, - errorMessage, - ...props -}: LongTextFieldProps) { - return ( -
    - {description}} - error={errorMessage} - isInvalid={error} - id={id} - fullWidth - > - onChange(event.target.value)} - placeholder={placeholder} - readOnly={readOnly} - value={value ?? ''} - fullWidth - /> - -
    - ); -} - -export const LongTextField = connectField(LongText, { kind: 'leaf' }); diff --git a/packages/orchestrator-ui-components/src/components/WfoForms/formFields/NestField.tsx b/packages/orchestrator-ui-components/src/components/WfoForms/formFields/NestField.tsx deleted file mode 100644 index 6aaac86c9..000000000 --- a/packages/orchestrator-ui-components/src/components/WfoForms/formFields/NestField.tsx +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Copyright 2019-2023 SURF. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ -import React from 'react'; - -import { connectField, filterDOMProps, joinName } from 'uniforms'; -import { AutoField } from 'uniforms-unstyled'; - -import { - EuiDescribedFormGroup, - EuiFlexGroup, - EuiFlexItem, - EuiText, -} from '@elastic/eui'; - -import { FieldProps } from './types'; - -export type NestFieldProps = FieldProps< - null, - { fields?: unknown[]; itemProps?: object } ->; - -declare module 'uniforms' { - interface FilterDOMProps { - properties: never; - wrap: never; - ref: never; - } -} -filterDOMProps.register('properties', 'wrap'); - -function Nest({ - children, - fields, - itemProps, - label, - description, - name, - className = '', - ...props -}: NestFieldProps) { - const nameArray = joinName(null, name); - const lastNamePart = nameArray[nameArray.length - 1]; - const isInList = !isNaN(parseInt(lastNamePart)); - const itemIndex = isInList ? parseInt(lastNamePart) : 0; - - if (isInList) { - return ( - - {label && ( - <> - - {description} - - )} - - {children || - fields?.map((field) => ( - - - - ))} - - ); - } else { - return ( - {label}} - description={description} - className={`${className} nest-field`} - > - {children || - fields?.map((field) => ( - - ))} - - ); - } -} - -export const NestField = connectField(Nest); diff --git a/packages/orchestrator-ui-components/src/components/WfoForms/formFields/NumField.tsx b/packages/orchestrator-ui-components/src/components/WfoForms/formFields/NumField.tsx deleted file mode 100644 index a723c8270..000000000 --- a/packages/orchestrator-ui-components/src/components/WfoForms/formFields/NumField.tsx +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright 2019-2023 SURF. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ -import React from 'react'; - -import { connectField, filterDOMProps } from 'uniforms'; - -import { EuiFieldNumber, EuiFormRow, EuiText } from '@elastic/eui'; - -import { FieldProps } from '@/components'; -import { getCommonFormFieldStyles } from '@/components/WfoForms/formFields/commonStyles'; -import { useWithOrchestratorTheme } from '@/hooks'; -import { getFormFieldsBaseStyle } from '@/theme'; - -export type NumFieldProps = FieldProps< - number, - { max?: number; min?: number; precision?: number; step?: number } - // Todo: not sure what this did - // NumericInput ->; - -function Num({ - disabled, - id, - label, - description, - max, - min, - name, - onChange, - placeholder, - readOnly, - step, - value, - error, - showInlineError, - errorMessage, - ...props -}: NumFieldProps) { - const { formRowStyle } = useWithOrchestratorTheme(getCommonFormFieldStyles); - const { formFieldBaseStyle } = useWithOrchestratorTheme( - getFormFieldsBaseStyle, - ); - - return ( -
    - {description}} - error={showInlineError ? errorMessage : false} - isInvalid={error} - id={id} - fullWidth - > - onChange(parseInt(event.target.value))} - min={min} - max={max} - step={step ?? 1} - value={value ?? ''} - disabled={disabled} - /> - -
    - ); -} - -export const NumField = connectField(Num, { kind: 'leaf' }); diff --git a/packages/orchestrator-ui-components/src/components/WfoForms/formFields/OptGroupField.tsx b/packages/orchestrator-ui-components/src/components/WfoForms/formFields/OptGroupField.tsx deleted file mode 100644 index 032665607..000000000 --- a/packages/orchestrator-ui-components/src/components/WfoForms/formFields/OptGroupField.tsx +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright 2019-2023 SURF. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ -import React from 'react'; - -import { useTranslations } from 'next-intl'; -import { connectField, filterDOMProps, useField } from 'uniforms'; -import { AutoField } from 'uniforms-unstyled'; - -import { EuiDescribedFormGroup, EuiFlexItem, EuiFormRow } from '@elastic/eui'; - -import { BoolField } from './BoolField'; -import { FieldProps } from './types'; - -export type OptGroupFieldProps = FieldProps< - null, - { fields?: unknown[]; itemProps?: object } ->; - -filterDOMProps.register('properties'); - -function OptGroup({ - fields, - itemProps, - name, - readOnly, - className = '', - ...props -}: OptGroupFieldProps) { - const t = useTranslations('pydanticForms.backendTranslations'); - const enabled = useField('enabled', {})[0].value; - - return ( - {t(`${name}.title`)}} - description={t(`${name}.description`)} - className={`${className} optgroup-field`} - > - <> - - - - - - {enabled && - fields - ?.filter((field) => field !== 'enabled') - .map((field) => ( - - - - ))} - - - ); -} - -export const OptGroupField = connectField(OptGroup); diff --git a/packages/orchestrator-ui-components/src/components/WfoForms/formFields/RadioField.tsx b/packages/orchestrator-ui-components/src/components/WfoForms/formFields/RadioField.tsx deleted file mode 100644 index 4d846800f..000000000 --- a/packages/orchestrator-ui-components/src/components/WfoForms/formFields/RadioField.tsx +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright 2019-2023 SURF. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ -import React from 'react'; - -import { omit } from 'lodash'; -import { connectField, filterDOMProps } from 'uniforms'; - -import { EuiFormRow, EuiRadio, EuiText } from '@elastic/eui'; - -import { FieldProps } from '@/components'; - -const base64 = - typeof btoa !== 'undefined' - ? btoa - : (x: string) => Buffer.from(x).toString('base64'); -const escape = (x: string) => base64(encodeURIComponent(x)).replace(/=+$/, ''); - -export type RadioFieldProps = FieldProps< - string, - { - allowedValues?: string[]; - checkboxes?: boolean; - transform?(value: string): string; - } ->; - -function Radio({ - allowedValues, - disabled, - id, - label, - description, - name, - onChange, - readOnly, - transform, - value, - error, - showInlineError, - errorMessage, - ...props -}: RadioFieldProps) { - return ( -
    - {description}} - error={showInlineError ? errorMessage : false} - isInvalid={error} - id={id} - fullWidth - > - <> - {allowedValues?.map((item) => ( - { - if (!readOnly) { - onChange(item); - } - }} - /> - ))} - - -
    - ); -} - -export const RadioField = connectField(Radio, { kind: 'leaf' }); diff --git a/packages/orchestrator-ui-components/src/components/WfoForms/formFields/SelectField/SelectField.tsx b/packages/orchestrator-ui-components/src/components/WfoForms/formFields/SelectField/SelectField.tsx deleted file mode 100644 index 754d94df0..000000000 --- a/packages/orchestrator-ui-components/src/components/WfoForms/formFields/SelectField/SelectField.tsx +++ /dev/null @@ -1,177 +0,0 @@ -/* - * Copyright 2019-2023 SURF. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ -import React, { useEffect } from 'react'; -import ReactSelect from 'react-select'; - -import { get } from 'lodash'; -import { useTranslations } from 'next-intl'; -import { joinName, useField, useForm } from 'uniforms'; - -import { EuiFormRow, EuiText } from '@elastic/eui'; - -import { useWithOrchestratorTheme } from '@/hooks'; -import type { Option } from '@/types'; - -import { ListField, ListFieldProps } from '../ListField'; -import { ListItemField } from '../ListItemField'; -import { ListSelectField } from '../ListSelectField'; -import { FieldProps } from '../types'; -import { getSelectFieldStyles } from './styles'; - -export type SelectFieldProps = FieldProps< - string | string[], - { allowedValues?: string[]; transform?(value: string): string } ->; - -/* - -*/ -export function UnconnectedSelectField({ - allowedValues = [], - disabled, - fieldType, - id, - label, - description, - name, - onChange, - placeholder, - readOnly, - transform, - value, - error, - showInlineError, - errorMessage, - ...props -}: SelectFieldProps) { - const t = useTranslations('pydanticForms'); - - const nameArray = joinName(null, name); - let parentName = joinName(nameArray.slice(0, -1)); - - // We can't call useField conditionally so we call it for ourselves if there is no parent - if (parentName === '') { - parentName = name; - } - const parent = useField(parentName, {}, { absoluteName: true })[0]; - const { model } = useForm(); - - if (parentName !== name) { - if ( - parent.fieldType === Array && - (parent as ListFieldProps).uniqueItems - ) { - const allValues: string[] = get(model, parentName, []); - const chosenValues = allValues.filter( - (_item, index) => - index.toString() !== nameArray[nameArray.length - 1], - ); - - allowedValues = allowedValues.filter( - (value) => !chosenValues.includes(value), - ); - } - } - const options = allowedValues.map((value: string) => ({ - label: transform ? transform(value) : value, - text: transform ? transform(value) : value, - value: value, - })); - - const selectedValue = options.find( - (option: Option) => option.value === value, - ); - - // React select allows callbacks to supply style for innercomponents: https://react-select.com/styles#inner-components - const { reactSelectInnerComponentStyles, formRowStyle } = - useWithOrchestratorTheme(getSelectFieldStyles); - - useEffect(() => { - if (selectedValue && selectedValue.value !== 'undefined') { - onChange(selectedValue.value); - } - // Adding the missing dependencies to the dependency array leads to an infinite loop - // eslint-disable-next-line react-hooks/exhaustive-deps - }, []); - - if (fieldType === Array) { - // Avoid circular import with our own ListSelectField (instead of recursively trying to use SelectField) - return ( - - - - - - ); - } else { - return ( -
    - {description}} - error={showInlineError ? errorMessage : false} - isInvalid={error} - id={id} - fullWidth - > - - id={id} - inputId={`${id}.search`} - name={name} - onChange={(option) => { - if (!readOnly) { - // @ts-expect-error - null needs to be passed in some cases to remove something (eg. a fw endpoint in an l2vpn) - onChange(option?.value ?? null); - } - }} - styles={reactSelectInnerComponentStyles} - options={options} - value={selectedValue} - isSearchable={true} - isClearable={true} - placeholder={ - placeholder || t('widgets.select.placeholder') - } - isDisabled={disabled || readOnly} - /> - -
    - ); - } -} diff --git a/packages/orchestrator-ui-components/src/components/WfoForms/formFields/SelectField/index.ts b/packages/orchestrator-ui-components/src/components/WfoForms/formFields/SelectField/index.ts deleted file mode 100644 index ec0bc2da9..000000000 --- a/packages/orchestrator-ui-components/src/components/WfoForms/formFields/SelectField/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './SelectField'; diff --git a/packages/orchestrator-ui-components/src/components/WfoForms/formFields/SelectField/styles.ts b/packages/orchestrator-ui-components/src/components/WfoForms/formFields/SelectField/styles.ts deleted file mode 100644 index 00d247d0e..000000000 --- a/packages/orchestrator-ui-components/src/components/WfoForms/formFields/SelectField/styles.ts +++ /dev/null @@ -1,52 +0,0 @@ -import { getCommonFormFieldStyles } from '@/components/WfoForms/formFields/commonStyles'; -import { WfoTheme } from '@/hooks'; - -export const getSelectFieldStyles = (wfoTheme: WfoTheme) => { - const { theme } = wfoTheme; - const { formRowStyle } = getCommonFormFieldStyles(wfoTheme); - - const reactSelectInnerComponentStyles = { - option: ( - baseStyles: object, - state: { isSelected: boolean; isDisabled: boolean }, - ) => ({ - ...baseStyles, - borderBottom: theme.border.thin, - borderColor: theme.colors.lightShade, - backgroundColor: theme.colors.lightestShade, - color: state.isSelected - ? theme.colors.primaryText - : theme.colors.text, - }), - control: (baseStyles: object, state: { isFocused: boolean }) => { - return { - ...baseStyles, - backgroundColor: state.isFocused - ? theme.colors.emptyShade - : theme.colors.lightestShade, - color: theme.colors.text, - border: `1px solid ${theme.colors.lightShade}`, - }; - }, - input: (baseStyles: object) => ({ - ...baseStyles, - color: theme.colors.text, - }), - singleValue: (baseStyles: object, state: { isDisabled: boolean }) => { - const opacity = state.isDisabled ? 0.3 : 1; - const transition = 'opacity 300ms'; - return { - ...baseStyles, - opacity, - transition, - color: theme.colors.text, - }; - }, - menu: (baseStyles: object) => ({ - ...baseStyles, - backgroundColor: theme.colors.lightestShade, - }), - }; - - return { reactSelectInnerComponentStyles, formRowStyle }; -}; diff --git a/packages/orchestrator-ui-components/src/components/WfoForms/formFields/SubmitField.tsx b/packages/orchestrator-ui-components/src/components/WfoForms/formFields/SubmitField.tsx deleted file mode 100644 index d2b802b10..000000000 --- a/packages/orchestrator-ui-components/src/components/WfoForms/formFields/SubmitField.tsx +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright 2019-2023 SURF. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ -import React from 'react'; - -import { filterDOMProps, useForm } from 'uniforms'; - -import { FieldProps } from '@/components'; - -export type SubmitFieldProps = FieldProps< - null, - object, - HTMLInputElement, - HTMLInputElement ->; - -// onChange not used on purpose -export const SubmitField = ({ - disabled, - inputRef, - readOnly, - value, - ...props -}: SubmitFieldProps) => { - const { error, state } = useForm(); - - return ( - - ); -}; diff --git a/packages/orchestrator-ui-components/src/components/WfoForms/formFields/SubscriptionSummaryField.tsx b/packages/orchestrator-ui-components/src/components/WfoForms/formFields/SubscriptionSummaryField.tsx deleted file mode 100644 index 0cd054528..000000000 --- a/packages/orchestrator-ui-components/src/components/WfoForms/formFields/SubscriptionSummaryField.tsx +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright 2019-2024 SURF. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ -import React from 'react'; - -import { connectField, filterDOMProps } from 'uniforms'; - -import { EuiFormRow, EuiText } from '@elastic/eui'; - -import { WfoLoading, WfoSubscriptionDetailSection } from '@/components'; -import { useGetSubscriptionDetailQuery } from '@/rtk'; - -import { FieldProps } from './types'; - -export type SubscriptionSummaryFieldProps = FieldProps; - -interface SubscriptionSummaryDisplayProps { - subscriptionId: string; -} - -export const SubscriptionSummaryDisplay = ({ - subscriptionId, -}: SubscriptionSummaryDisplayProps) => { - const { data } = useGetSubscriptionDetailQuery({ - subscriptionId, - }); - const subscriptionDetail = data?.subscription; - - if (!subscriptionDetail) { - return ; - } - - return ( - - ); -}; - -const SubscriptionSummary = ({ - id, - value, - description, - ...props -}: SubscriptionSummaryFieldProps) => { - if (!value) { - return null; - } - - return ( -
    - {description}} - fullWidth - > - - -
    - ); -}; - -export const SubscriptionSummaryField = connectField(SubscriptionSummary, { - kind: 'leaf', -}); diff --git a/packages/orchestrator-ui-components/src/components/WfoForms/formFields/SummaryField.tsx b/packages/orchestrator-ui-components/src/components/WfoForms/formFields/SummaryField.tsx deleted file mode 100644 index 68f095220..000000000 --- a/packages/orchestrator-ui-components/src/components/WfoForms/formFields/SummaryField.tsx +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright 2019-2023 SURF. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ -import React from 'react'; - -import { FieldProps, connectField, filterDOMProps } from 'uniforms'; - -import { EuiFlexItem, EuiFormRow, EuiText } from '@elastic/eui'; - -import { summaryFieldStyles } from '@/components/WfoForms/formFields/SummaryFieldStyling'; -import { getCommonFormFieldStyles } from '@/components/WfoForms/formFields/commonStyles'; -import { useWithOrchestratorTheme } from '@/hooks'; - -export type SummaryFieldProps = FieldProps< - null, - { - description?: string; - data?: { headers: string[]; labels: string[]; columns: string[][] }; - } ->; - -// onChange not used on purpose -function Summary({ - id, - label, - description, - data, - ...props -}: SummaryFieldProps) { - const { summaryFieldStyle } = useWithOrchestratorTheme(summaryFieldStyles); - const { formRowStyle } = useWithOrchestratorTheme(getCommonFormFieldStyles); - - if (!data) { - return null; - } - - const { headers, labels, columns } = data; - - const extraColumnsData = columns.filter((_, index) => index !== 0); - const rows = columns[0].map((row, index) => ( - - {labels && {labels[index]}} - - {typeof row === 'string' && row.includes('') ? ( -
    - ) : ( - row - )} - - {extraColumnsData && - extraColumnsData.map((_, idx) => ( - - {extraColumnsData[idx][index]} - - ))} - - )); - - const tableHeader = - !headers || headers.length === 0 ? null : ( - - {labels && } - {headers.map((header, idx) => ( - {header} - ))} - - ); - - return ( - -
    - {description}} - id={id} - fullWidth - > -
    - - {tableHeader} - {rows} -
    -
    -
    -
    -
    - ); -} - -export const SummaryField = connectField(Summary, { kind: 'leaf' }); diff --git a/packages/orchestrator-ui-components/src/components/WfoForms/formFields/SummaryFieldStyling.ts b/packages/orchestrator-ui-components/src/components/WfoForms/formFields/SummaryFieldStyling.ts deleted file mode 100644 index def3e8a41..000000000 --- a/packages/orchestrator-ui-components/src/components/WfoForms/formFields/SummaryFieldStyling.ts +++ /dev/null @@ -1,44 +0,0 @@ -import { css } from '@emotion/react'; - -import { WfoTheme } from '@/hooks'; - -export const summaryFieldStyles = ({ theme }: WfoTheme) => { - const summaryFieldStyle = css({ - 'div.emailMessage': { - td: { - color: theme.colors.textParagraph, - }, - p: { - color: theme.colors.textParagraph, - }, - html: { - marginLeft: '-10px', - }, - }, - 'section.table-summary': { - marginTop: '20px', - width: '100%', - td: { - padding: '10px', - verticalAlign: 'top', - }, - 'td:not(:first-child):not(:last-child)': { - borderRight: `1px solid ${theme.colors.borderBasePlain}`, - }, - '.label': { - fontWeight: 'bold', - color: theme.colors.backgroundBaseSubdued, - backgroundColor: theme.colors.primary, - borderRight: `2px solid ${theme.colors.borderBasePlain}`, - borderBottom: `1px solid ${theme.colors.borderBasePlain}`, - }, - '.value': { - backgroundColor: theme.colors.backgroundBasePrimary, - borderBottom: `1px solid ${theme.colors.borderBasePlain}`, - }, - }, - }); - return { - summaryFieldStyle: summaryFieldStyle, - }; -}; diff --git a/packages/orchestrator-ui-components/src/components/WfoForms/formFields/TextField.tsx b/packages/orchestrator-ui-components/src/components/WfoForms/formFields/TextField.tsx deleted file mode 100644 index 51ca9dd92..000000000 --- a/packages/orchestrator-ui-components/src/components/WfoForms/formFields/TextField.tsx +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright 2019-2023 SURF. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ -import React from 'react'; - -import { connectField, filterDOMProps } from 'uniforms'; - -import { EuiFieldText, EuiFormRow, EuiText } from '@elastic/eui'; - -import { FieldProps } from '@/components'; -import { getCommonFormFieldStyles } from '@/components/WfoForms/formFields/commonStyles'; -import { useWithOrchestratorTheme } from '@/hooks'; -import { getFormFieldsBaseStyle } from '@/theme'; - -export type TextFieldProps = FieldProps; - -function Text({ - autoComplete, - disabled, - id, - label, - description, - name, - onChange, - placeholder, - readOnly, - type, - value, - error, - showInlineError, - errorMessage, - ...props -}: TextFieldProps) { - const { formRowStyle } = useWithOrchestratorTheme(getCommonFormFieldStyles); - const { formFieldBaseStyle } = useWithOrchestratorTheme( - getFormFieldsBaseStyle, - ); - - return ( -
    - {description}} - error={showInlineError ? errorMessage : false} - isInvalid={error} - id={id} - fullWidth - > - onChange(event.target.value)} - placeholder={placeholder} - readOnly={readOnly} - type={type} - value={value ?? ''} - fullWidth - /> - -
    - ); -} - -Text.defaultProps = { type: 'text' }; - -export const TextField = connectField(Text, { kind: 'leaf' }); diff --git a/packages/orchestrator-ui-components/src/components/WfoForms/formFields/commonStyles.ts b/packages/orchestrator-ui-components/src/components/WfoForms/formFields/commonStyles.ts deleted file mode 100644 index 7da990551..000000000 --- a/packages/orchestrator-ui-components/src/components/WfoForms/formFields/commonStyles.ts +++ /dev/null @@ -1,32 +0,0 @@ -import { css } from '@emotion/react'; - -import { WfoTheme } from '@/hooks'; - -export const getCommonFormFieldStyles = ({ theme }: WfoTheme) => { - const formRowStyle = css({ - marginBottom: theme.base * 2, - - '.euiText': { - color: theme.colors.text, - }, - '.euiFormLabel': { - color: theme.colors.text, - cursor: 'text', - '&.euiFormLabel-isFocused': { - color: theme.colors.primaryText, - }, - }, - '.euiFormRow__labelWrapper': { - display: 'flex', - flexDirection: 'column', - }, - }); - - const errorStyle = css({ - color: theme.colors.dangerText, - }); - return { - errorStyle, - formRowStyle, - }; -}; diff --git a/packages/orchestrator-ui-components/src/components/WfoForms/formFields/deprecated/ContactPersonAutocomplete.tsx b/packages/orchestrator-ui-components/src/components/WfoForms/formFields/deprecated/ContactPersonAutocomplete.tsx deleted file mode 100644 index 1cc253d5c..000000000 --- a/packages/orchestrator-ui-components/src/components/WfoForms/formFields/deprecated/ContactPersonAutocomplete.tsx +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Copyright 2019-2023 SURF. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ -import React, { useEffect, useRef } from 'react'; - -import scrollIntoView from 'scroll-into-view'; - -import { EuiFlexItem } from '@elastic/eui'; - -import { useWithOrchestratorTheme } from '@/hooks'; - -import { ContactPerson } from '../types'; -import { isEmpty } from '../utils'; -import { getContactPersonStyles } from './ContactPersonAutocompleteStyles'; - -interface ContactPersonAutocompleteProps { - query: string; - selectedItem: number; - personIndex: number; - itemSelected: (value: ContactPerson, index: number) => void; - suggestions: ContactPerson[]; -} - -export const ContactPersonAutocomplete = ({ - query, - selectedItem, - personIndex, - itemSelected, - suggestions, -}: ContactPersonAutocompleteProps) => { - const { contactPersonAutocompleteStyling } = useWithOrchestratorTheme( - getContactPersonStyles, - ); - - // Intentionally not done with state since we don't need a rerender - // This is only to store a ref for the scroll into view part - const selectedRowRef = useRef(null); - - useEffect(() => { - if (!isEmpty(suggestions) && selectedRowRef.current) { - scrollIntoView(selectedRowRef.current); - } - }, [selectedItem, suggestions]); - - const itemName = (item: ContactPerson, query: string) => { - const name = item.name; - const nameToLower = name.toLowerCase(); - const indexOf = nameToLower.indexOf(query.toLowerCase()); - const first = name.substring(0, indexOf); - const middle = name.substring(indexOf, indexOf + query.length); - const last = name.substring(indexOf + query.length); - return ( - - {first} - {middle} - {last} - - ); - }; - - return isEmpty(suggestions) ? null : ( - -
    - - - {suggestions.map((item, index) => ( - itemSelected(item, personIndex)} - ref={ - selectedItem === index - ? selectedRowRef - : null - } - > - - - - ))} - -
    {itemName(item, query)}{item.email || ''}
    -
    -
    - ); -}; diff --git a/packages/orchestrator-ui-components/src/components/WfoForms/formFields/deprecated/ContactPersonAutocompleteStyles.ts b/packages/orchestrator-ui-components/src/components/WfoForms/formFields/deprecated/ContactPersonAutocompleteStyles.ts deleted file mode 100644 index d5791101f..000000000 --- a/packages/orchestrator-ui-components/src/components/WfoForms/formFields/deprecated/ContactPersonAutocompleteStyles.ts +++ /dev/null @@ -1,41 +0,0 @@ -import { css } from '@emotion/react'; - -import { WfoTheme } from '@/hooks'; - -export const getContactPersonStyles = ({ theme }: WfoTheme) => { - const contactPersonAutocompleteStyling = css` - .autocomplete-container { - position: relative; - } - - section.autocomplete { - position: relative; - z-index: 2000; - width: 100%; - border-radius: ${theme.border.radius.medium}; - background-color: ${theme.colors.lightShade}; - margin-bottom: 20px; - - table.result { - z-index: 2000; - - tbody tr { - cursor: pointer; - - td { - padding: 10px; - width: 50%; - vertical-align: middle; - span.matched { - font-weight: bold; - text-decoration: underline; - } - } - } - } - } - `; - return { - contactPersonAutocompleteStyling, - }; -}; diff --git a/packages/orchestrator-ui-components/src/components/WfoForms/formFields/deprecated/ContactPersonNameField.tsx b/packages/orchestrator-ui-components/src/components/WfoForms/formFields/deprecated/ContactPersonNameField.tsx deleted file mode 100644 index 1f7033a73..000000000 --- a/packages/orchestrator-ui-components/src/components/WfoForms/formFields/deprecated/ContactPersonNameField.tsx +++ /dev/null @@ -1,263 +0,0 @@ -/* - * Copyright 2019-2023 SURF. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ -import React, { Ref, useEffect, useState } from 'react'; - -import { isFunction } from 'lodash'; -import get from 'lodash/get'; -import { useTranslations } from 'next-intl'; -import { - connectField, - filterDOMProps, - joinName, - useField, - useForm, -} from 'uniforms'; - -import { EuiFieldText, EuiFormRow, EuiText } from '@elastic/eui'; - -import { getCommonFormFieldStyles } from '@/components/WfoForms/formFields/commonStyles'; -import { useWithOrchestratorTheme } from '@/hooks'; -import { useContactPersonsQuery } from '@/rtk/endpoints/formFields'; -import { getFormFieldsBaseStyle } from '@/theme'; - -import { ContactPerson, FieldProps } from '../types'; -import { ContactPersonAutocomplete } from './ContactPersonAutocomplete'; - -export function stop(e: React.SyntheticEvent) { - if (e !== undefined && e !== null) { - e.preventDefault(); - e.stopPropagation(); - } -} - -export type ContactPersonNameFieldProps = FieldProps< - string, - { - customerId?: string; - customerKey?: string; - } ->; - -declare module 'uniforms' { - interface FilterDOMProps { - customerId: never; - customerKey: never; - organisationKey: never; - organisationId: never; - } -} -filterDOMProps.register( - 'customerId', - 'customerKey', - 'organisationKey', - 'organisationId', -); - -function ContactPersonName({ - disabled, - id, - inputRef = React.createRef() as Ref, - label, - description, - name, - onChange, - placeholder, - readOnly, - value, - error, - showInlineError, - errorMessage, - customerId, - customerKey, - ...props -}: ContactPersonNameFieldProps) { - const { formRowStyle } = useWithOrchestratorTheme(getCommonFormFieldStyles); - const { formFieldBaseStyle } = useWithOrchestratorTheme( - getFormFieldsBaseStyle, - ); - - const t = useTranslations('pydanticForms'); - const { model, onChange: formOnChange, schema } = useForm(); - - const contactsPersonFieldNameArray = joinName(null, name).slice(0, -1); - const emailFieldName = joinName(contactsPersonFieldNameArray, 'email'); - const contactsFieldName = joinName( - contactsPersonFieldNameArray.slice(0, -1), - ); - - const chosenPersons: ContactPerson[] = get(model, contactsFieldName, []); - // We cant call useField conditionally so if we don't have a parent we call it for ourself - const useFieldName = contactsPersonFieldNameArray.length - ? contactsFieldName - : name; - const contactsField = useField(useFieldName, {}, { absoluteName: true })[0]; - - const customerIdFieldName = - customerKey || contactsField.field.customerKey || 'customer_id'; - - // Get initial value for org field if it exists (we cant really test) - let customerInitialValue; - try { - customerInitialValue = schema.getInitialValue(customerIdFieldName, {}); - } catch { - customerInitialValue = ''; - } - - const customerIdValue = - customerId || - contactsField.field.customerId || - get(model, customerIdFieldName, customerInitialValue); - - const [displayAutocomplete, setDisplayAutocomplete] = useState(false); - const [contactPersons, setContactPersons] = useState([]); - const [selectedIndex, setSelectedIndex] = useState(-1); - - const { data, error: fetchError } = useContactPersonsQuery( - { customerIdValue }, - { skip: !customerIdValue }, - ); - - const suggestions = value - ? contactPersons - .filter( - (item) => - item.name.toLowerCase().indexOf(value.toLowerCase()) > -1, - ) - .filter( - (item) => - !chosenPersons.some( - (person) => person.email === item.email, - ), - ) - : []; - - useEffect(() => { - if (customerIdValue) { - if (data) { - setContactPersons(data); - } - if (fetchError) { - setContactPersons([]); - } - } - }, [customerIdValue, data, fetchError]); - - useEffect(() => { - // Set focus to the last name component to be created - if (!isFunction(inputRef)) { - inputRef!.current?.focus(); - } - }, []); // eslint-disable-line react-hooks/exhaustive-deps - - function onChangeInternal(e: React.FormEvent) { - stop(e); - const target = e.target as HTMLInputElement; - const value = target.value; - - onChange(value); - setDisplayAutocomplete(true); - } - - function itemSelected(item: ContactPerson) { - onChange(item.name || ''); - formOnChange(emailFieldName, item.email || ''); - setDisplayAutocomplete(false); - setSelectedIndex(-1); - } - - function onAutocompleteKeyDown(e: React.KeyboardEvent) { - if (!suggestions) { - return; - } - if (e.keyCode === 40 && selectedIndex < suggestions.length - 1) { - //keyDown - stop(e); - setSelectedIndex(selectedIndex + 1); - } - if (e.keyCode === 38 && selectedIndex >= 0) { - //keyUp - stop(e); - setSelectedIndex(selectedIndex - 1); - } - if (e.keyCode === 13) { - //enter - if (selectedIndex >= 0) { - stop(e); - itemSelected(suggestions[selectedIndex]); - } - } - if (e.keyCode === 27) { - //escape - stop(e); - setDisplayAutocomplete(false); - setSelectedIndex(-1); - } - } - - function onBlurAutoComplete(e: React.FocusEvent) { - stop(e); - setTimeout(() => setDisplayAutocomplete(false), 350); - } - - return ( -
    - {description}} - error={showInlineError ? errorMessage : false} - isInvalid={error} - id={id} - fullWidth - css={formRowStyle} - > - <> - {' '} -
    - {!!(displayAutocomplete && suggestions.length) && ( - - )} -
    - -
    -
    - ); -} - -export const ContactPersonNameField = connectField(ContactPersonName, { - kind: 'leaf', -}); diff --git a/packages/orchestrator-ui-components/src/components/WfoForms/formFields/deprecated/FileUploadField.tsx b/packages/orchestrator-ui-components/src/components/WfoForms/formFields/deprecated/FileUploadField.tsx deleted file mode 100644 index 5028268ba..000000000 --- a/packages/orchestrator-ui-components/src/components/WfoForms/formFields/deprecated/FileUploadField.tsx +++ /dev/null @@ -1,151 +0,0 @@ -/* - * Copyright 2024 SURF. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ -import React, { useState } from 'react'; - -import { useTranslations } from 'next-intl'; -import { connectField, filterDOMProps } from 'uniforms'; - -import { EuiFilePicker, EuiFormRow, EuiText } from '@elastic/eui'; - -import { FieldProps } from '@/components'; -import { getCommonFormFieldStyles } from '@/components/WfoForms/formFields/commonStyles'; -import { useOrchestratorTheme, useWithOrchestratorTheme } from '@/hooks'; -import { useUploadFileMutation } from '@/rtk/endpoints/fileUpload'; - -export type FileUploadProps = FieldProps; - -function FileUpload({ - id, - label, - description, - onChange, - error, - showInlineError, - errorMessage, - ...props -}: FileUploadProps) { - const t = useTranslations('pydanticForms.widgets.fileUpload'); - const { theme } = useOrchestratorTheme(); - const [uploadFile, { isLoading, reset }] = useUploadFileMutation(); - const [hasInValidFiletypes, setHasInValidFiletypes] = useState(false); - const [hasError, setHasError] = useState(false); - const [hasFileToBig, setHasFileToBig] = useState(false); - - const { formRowStyle } = useWithOrchestratorTheme(getCommonFormFieldStyles); - - const { - allowed_file_types: allowedMimeTypes, - url, - filesize_limit: fileSizeLimit, - } = props.field; - - const cimUrl = url.replace('/cim', ''); - - const resetErrors = () => { - setHasInValidFiletypes(false); - setHasError(false); - setHasFileToBig(false); - }; - - const getErrorText = (): string => { - if (hasInValidFiletypes) { - return t('invalidFiletype'); - } - if (hasError) { - return t('errorUploading'); - } - if (hasFileToBig) { - return t('fileToBig', { fileSizeLimit }); - } - return ''; - }; - - const handleUploadedFiles = (files: FileList | null) => { - const file = files?.item(0) || null; - - if (!file) return; - - const { type, size } = file; - - if (allowedMimeTypes && !allowedMimeTypes.includes(type)) { - resetErrors(); - setHasInValidFiletypes(true); - return; - } else if (size > fileSizeLimit) { - resetErrors(); - setHasFileToBig(true); - return; - } else { - uploadFile({ url: cimUrl, file }) - .then((response) => { - if (response.error) { - resetErrors(); - setHasError(true); - return; - } else { - onChange(response.data.file_id); - resetErrors(); - } - }) - .catch((error) => { - resetErrors(); - setHasError(true); - console.error(error); - return; - }); - reset(); - } - }; - - return ( -
    - {description}} - error={showInlineError ? errorMessage : false} - isInvalid={error} - id={id} - fullWidth - > - <> - -
    - {getErrorText()} -
    - -
    -
    - ); -} - -export const FileUploadField = connectField(FileUpload, { kind: 'leaf' }); diff --git a/packages/orchestrator-ui-components/src/components/WfoForms/formFields/deprecated/ImsNodeIdField.tsx b/packages/orchestrator-ui-components/src/components/WfoForms/formFields/deprecated/ImsNodeIdField.tsx deleted file mode 100644 index a703bdf74..000000000 --- a/packages/orchestrator-ui-components/src/components/WfoForms/formFields/deprecated/ImsNodeIdField.tsx +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Copyright 2019-2023 SURF. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ -import React, { useEffect, useState } from 'react'; - -import { get } from 'lodash'; -import { useTranslations } from 'next-intl'; -import { connectField, filterDOMProps } from 'uniforms'; - -import { useImsNodesQuery } from '@/rtk/endpoints/formFields'; - -import { SelectFieldProps, UnconnectedSelectField } from '../SelectField'; -import { ImsNode } from './types'; - -export type ImsNodeIdFieldProps = { - onChange: (value?: number | undefined) => void; - value?: number; - locationCode: string; - status?: string; - unsubscribedOnly?: boolean; -} & Omit< - SelectFieldProps, - | 'placeholder' - | 'transform' - | 'allowedValues' - | 'onChange' - | 'value' - | 'name' ->; - -declare module 'uniforms' { - interface FilterDOMProps { - locationCode: never; - status: never; - unsubscribedOnly: never; - } -} -filterDOMProps.register('locationCode', 'status', 'unsubscribedOnly'); - -function ImsNodeId({ - value, - onChange, - locationCode, - status = 'PL', - unsubscribedOnly = true, - ...props -}: ImsNodeIdFieldProps) { - const t = useTranslations('pydanticForms'); - const [nodes, setNodes] = useState([]); - const { data, isLoading, error } = useImsNodesQuery( - { - locationCode, - status, - unsubscribedOnly, - }, - { skip: !(locationCode && status) }, - ); - - useEffect(() => { - if (data) { - setNodes(data); - } - if (error) { - console.error(error); - } - }, [locationCode, status, unsubscribedOnly, data, error]); - - const placeholder = - isLoading && locationCode - ? t('widgets.node_select.nodes_loading') - : nodes.length - ? t('widgets.node_select.select_node') - : t('forms.widgets.node_select.no_nodes_placeholder'); - - const imsNodeIdLabelLookup = - nodes?.reduce<{ [index: string]: string }>(function (mapping, node) { - mapping[node.id.toString()] = node.name; - return mapping; - }, {}) ?? {}; - - return ( - get(imsNodeIdLabelLookup, id, id)} - onChange={ - ((str: string) => onChange(parseInt(str, 10))) as unknown as ( - v: string | string[] | undefined, - ) => void - } - placeholder={placeholder} - /> - ); -} - -export const ImsNodeIdField = connectField(ImsNodeId, { kind: 'leaf' }); diff --git a/packages/orchestrator-ui-components/src/components/WfoForms/formFields/deprecated/ImsPortIdField.tsx b/packages/orchestrator-ui-components/src/components/WfoForms/formFields/deprecated/ImsPortIdField.tsx deleted file mode 100644 index 47c2be209..000000000 --- a/packages/orchestrator-ui-components/src/components/WfoForms/formFields/deprecated/ImsPortIdField.tsx +++ /dev/null @@ -1,233 +0,0 @@ -/* - * Copyright 2019-2023 SURF. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ -import React, { useCallback, useEffect, useState } from 'react'; -import ReactSelect, { SingleValue } from 'react-select'; - -import { useTranslations } from 'next-intl'; -import { connectField, filterDOMProps } from 'uniforms'; - -import { EuiFlexItem, EuiFormRow, EuiText } from '@elastic/eui'; - -import { useWithOrchestratorTheme } from '@/hooks'; -import { - useFreePortsByNodeSubscriptionIdAndSpeedQuery, - useGetNodeSubscriptionOptionsQuery, -} from '@/rtk/endpoints/formFields'; -import type { Option } from '@/types'; - -import { getSelectFieldStyles } from '../SelectField/styles'; -import { FieldProps } from '../types'; -import { imsPortIdFieldStyling } from './ImsPortIdFieldStyling'; -import { ImsPort, NodeSubscriptionOption } from './types'; - -export type ImsPortFieldProps = FieldProps< - number, - { - nodeSubscriptionId?: string; - interfaceSpeed: number | string; - imsPortMode?: 'patched' | 'unpatched' | 'all'; - nodeStatuses?: ('active' | 'provisioning')[]; - } ->; - -function nodeToOptionCorelink(nodeOption: NodeSubscriptionOption): Option { - return { - value: nodeOption.subscriptionId, - label: `${nodeOption.subscriptionId.substring(0, 8)} ${ - nodeOption.description.trim() || '' - }`, - }; -} - -declare module 'uniforms' { - interface FilterDOMProps { - nodeSubscriptionId: never; - interfaceSpeed: never; - nodeStatuses: never; - imsPortMode: never; - } -} -filterDOMProps.register( - 'nodeSubscriptionId', - 'interfaceSpeed', - 'nodeStatuses', - 'imsPortMode', -); - -function ImsPortId({ - id, - name, - label, - description, - onChange, - value, - disabled, - readOnly, - error, - showInlineError, - errorMessage, - nodeSubscriptionId, - interfaceSpeed, - imsPortMode = 'all', - nodeStatuses, - ...props -}: ImsPortFieldProps) { - const [nodeId, setNodeId] = useState( - nodeSubscriptionId, - ); - const [ports, setPorts] = useState([]); - - const t = useTranslations('pydanticForms'); - // React select allows callbacks to supply style for innercomponents: https://react-select.com/styles#inner-components - const { reactSelectInnerComponentStyles } = - useWithOrchestratorTheme(getSelectFieldStyles); - - const { - data: freePorts, - error: freePortsError, - isFetching: loading, - } = useFreePortsByNodeSubscriptionIdAndSpeedQuery( - { - nodeSubscriptionId: nodeId as string, - interfaceSpeed: interfaceSpeed as number, - mode: imsPortMode, - }, - { - skip: !nodeId, - refetchOnMountOrArgChange: true, - }, - ); - - const { data: nodeSubscriptionOptions } = - useGetNodeSubscriptionOptionsQuery({ - statuses: nodeStatuses?.join('|') ?? 'active', - }); - - useEffect(() => { - setPorts(freePorts ?? []); - }, [freePorts, freePortsError]); - - const onChangeNodes = useCallback( - (option: SingleValue