diff --git a/README.md b/README.md index bc9f872..5e2dd16 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # Custom Form Plugin Example -This repository demonstrates a Backstage plugin that customizes and extends the orchestrator workflow execution form. It provides a standalone Backstage instance for testing and debugging the plugin before integration with the orchestrator in a Red Hat Developer Hub (RHDH) deployment. The plugin’s features are illustrated using an [example workflow](https://github.com/parodos-dev/serverless-workflows-config/tree/main/charts/extendable-workflow). This workflow’s input schema includes custom UI properties that trigger specific form enhancements, such as the property `["ui:widget": "CountryWidget"](https://github.com/parodos-dev/serverless-workflows-config/blob/main/charts/extendable-workflow/templates/02-configmap_01-extendable-workflow-resources-schemas.yaml#L24)`, which loads the plugin's custom `CountryWidget` component. +This repository demonstrates a Backstage plugin that customizes and extends the orchestrator workflow execution form. It provides a standalone Backstage instance for testing and debugging the plugin before integration with the orchestrator in a Red Hat Developer Hub (RHDH) deployment. The plugin’s features are illustrated using an [example workflow](https://github.com/parodos-dev/serverless-workflows-config/tree/main/charts/extendable-workflow). This workflow’s input schema includes custom UI properties that trigger specific form enhancements, such as the property ["ui:widget": "CountryWidget"](https://github.com/parodos-dev/serverless-workflows-config/blob/main/charts/extendable-workflow/templates/02-configmap_01-extendable-workflow-resources-schemas.yaml#L24), which loads the plugin's custom `CountryWidget` component. ## Getting Started diff --git a/packages/app/package.json b/packages/app/package.json index 203fbcf..45a065d 100644 --- a/packages/app/package.json +++ b/packages/app/package.json @@ -38,7 +38,6 @@ "@backstage/plugin-user-settings": "^0.8.9", "@backstage/theme": "^0.5.6", "@backstage/types": "^1.1.1", - "@janus-idp/backstage-plugin-orchestrator-form-react": "1.0.101", "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", "custom-form-example-plugin": "*", @@ -48,7 +47,8 @@ "react-dom": "^18.0.2", "react-router": "^6.3.0", "react-router-dom": "^6.3.0", - "react-use": "^17.2.4" + "react-use": "^17.2.4", + "@janus-idp/backstage-plugin-orchestrator-form-react": "^1.0.102" }, "devDependencies": { "@backstage/test-utils": "^1.5.8", diff --git a/packages/app/src/components/TestForm.tsx b/packages/app/src/components/TestForm.tsx index 2a17f7a..f80d449 100644 --- a/packages/app/src/components/TestForm.tsx +++ b/packages/app/src/components/TestForm.tsx @@ -37,13 +37,27 @@ const schema = { } } as JSONSchema7; + +const data = { + personalInfo: { + firstName: "john", + lastName: "doe", + country: "Israel", + password: "aaa", + confirmPassword: "aaa" + }, + languageInfo: { + language: "heb" + } +}; + const handleExecute = (parameters: JsonObject): Promise => {console.log(parameters); return Promise.resolve();} export const TestFormPage = () => (
- + ); diff --git a/plugins/custom-form-example-plugin/package.json b/plugins/custom-form-example-plugin/package.json index 1dd05d7..9239f53 100644 --- a/plugins/custom-form-example-plugin/package.json +++ b/plugins/custom-form-example-plugin/package.json @@ -3,7 +3,7 @@ "version": "0.1.0", "main": "src/index.ts", "types": "src/index.ts", - "license": "Apache-2.0", + "license": "Apache-2.0", "publishConfig": { "access": "public", "main": "dist/index.esm.js", @@ -32,7 +32,7 @@ "@backstage/core-plugin-api": "^1.9.3", "@backstage/theme": "^0.5.6", "@backstage/types": "^1.1.1", - "@janus-idp/backstage-plugin-orchestrator-form-api": "1.0.101", + "@janus-idp/backstage-plugin-orchestrator-form-api": "^1.0.102", "@material-ui/core": "^4.12.4", "@rjsf/utils": "5.18.5", "json-schema": "^0.4.0", diff --git a/plugins/custom-form-example-plugin/src/customApi.tsx b/plugins/custom-form-example-plugin/src/customApi.tsx index 88be1a4..d409235 100644 --- a/plugins/custom-form-example-plugin/src/customApi.tsx +++ b/plugins/custom-form-example-plugin/src/customApi.tsx @@ -26,11 +26,11 @@ const sleep = (ms: number) => { return new Promise(resolve => setTimeout(resolve, ms)); } class CustomFormExtensionsApi implements OrchestratorFormApi { - getFormDecorator(_schema: JSONSchema7, _uiSchema: UiSchema) { + getFormDecorator(_schema: JSONSchema7, _uiSchema: UiSchema, initialFormData?: JsonObject) { return (FormComponent: React.ComponentType) => { return () => { - const [formContext, setFormContext] = React.useState({}); + const [formContext, setFormContext] = React.useState({country: initialFormData?.personalInfo?.country}); const customValidate = (formData: JsonObject | undefined, errors: FormValidation): FormValidation => { const _formData = formData as Data | undefined; if (_formData?.personalInfo?.password !== _formData?.personalInfo?.confirmPassword) { diff --git a/plugins/custom-form-example-plugin/src/widgets/LanguageSelectWidget.tsx b/plugins/custom-form-example-plugin/src/widgets/LanguageSelectWidget.tsx index 622c831..1ca279a 100644 --- a/plugins/custom-form-example-plugin/src/widgets/LanguageSelectWidget.tsx +++ b/plugins/custom-form-example-plugin/src/widgets/LanguageSelectWidget.tsx @@ -16,10 +16,10 @@ interface Option { } const LanguageWidget: Widget = ({ value, onChange, formContext }) => { + const [languages, setLanguages] = useState([]); const [loading, setLoading] = useState(false); const country = formContext?.country; - const fetchLanguages = React.useCallback(async () => { try { const response = await fetch("https://restcountries.com/v3.1/all"); @@ -42,12 +42,6 @@ const LanguageWidget: Widget = ({ valu } }, [country]); - useEffect(() => { - if (languages.length === 1) { - onChange(languages[0].value); - } - }, [languages, onChange]); - useEffect(() => { if (country) { fetchLanguages(); diff --git a/yarn.lock b/yarn.lock index fc9d530..0ed84b2 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5071,25 +5071,25 @@ resolved "https://registry.yarnpkg.com/@istanbuljs/schema/-/schema-0.1.3.tgz#e45e384e4b8ec16bce2fd903af78450f6bf7ec98" integrity sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA== -"@janus-idp/backstage-plugin-orchestrator-form-api@1.0.101": - version "1.0.101" - resolved "https://registry.yarnpkg.com/@janus-idp/backstage-plugin-orchestrator-form-api/-/backstage-plugin-orchestrator-form-api-1.0.101.tgz#65099691195aa0dbef0fe7609edac46eb6607643" - integrity sha512-g+es+mvlvRSrPivPz6vTButMZlG5UnAybC2oIarVGv/+zDucAqt2R3B98O5ZC2L511CkFz4aHN0FALj5fvbZuA== +"@janus-idp/backstage-plugin-orchestrator-form-api@1.0.102", "@janus-idp/backstage-plugin-orchestrator-form-api@^1.0.102": + version "1.0.102" + resolved "https://registry.yarnpkg.com/@janus-idp/backstage-plugin-orchestrator-form-api/-/backstage-plugin-orchestrator-form-api-1.0.102.tgz#02846b525eaabc82cc274171395f6b80988336c3" + integrity sha512-yIjq5jbFwRCmD9fWzg4Dm/cdq990NQPsiN1vBwqF3rIPdWDrr57sFKJfH+sMK5vw+7W3mXzzSzbfkNh7RaKbWQ== dependencies: "@backstage/core-plugin-api" "^1.9.3" "@backstage/types" "^1.1.1" "@rjsf/core" "5.18.5" "@rjsf/utils" "5.18.5" -"@janus-idp/backstage-plugin-orchestrator-form-react@1.0.101": - version "1.0.101" - resolved "https://registry.yarnpkg.com/@janus-idp/backstage-plugin-orchestrator-form-react/-/backstage-plugin-orchestrator-form-react-1.0.101.tgz#be4743d6e0b796a0915829e6846f5b5216af412a" - integrity sha512-BcRUwqj/FQjOruN8HWmJTa5Pf8NXbE2gkv01Pa6ir4bz2a4nu7y8fy+X0rCXviHaqtyd9Ioggf7sKriSCxbf9g== +"@janus-idp/backstage-plugin-orchestrator-form-react@^1.0.102": + version "1.0.102" + resolved "https://registry.yarnpkg.com/@janus-idp/backstage-plugin-orchestrator-form-react/-/backstage-plugin-orchestrator-form-react-1.0.102.tgz#57f764af8469fde4db22beac82d22766ae198df9" + integrity sha512-C373p0fcTi/Tgz+jgd1Tk0Spq28exxCNO6NC2oXzJ30S94UOSA3vxGjp6Q5FdeONe8EctreUfKcu0B5wIhGYJQ== dependencies: "@backstage/core-components" "^0.14.9" "@backstage/core-plugin-api" "^1.9.3" "@backstage/types" "^1.1.1" - "@janus-idp/backstage-plugin-orchestrator-form-api" "1.0.101" + "@janus-idp/backstage-plugin-orchestrator-form-api" "1.0.102" "@material-ui/core" "^4.12.4" "@rjsf/core" "5.18.5" "@rjsf/material-ui" "5.18.5" @@ -10318,7 +10318,7 @@ apg-lite@^1.0.3: "@backstage/plugin-user-settings" "^0.8.9" "@backstage/theme" "^0.5.6" "@backstage/types" "^1.1.1" - "@janus-idp/backstage-plugin-orchestrator-form-react" "1.0.101" + "@janus-idp/backstage-plugin-orchestrator-form-react" "^1.0.102" "@material-ui/core" "^4.12.2" "@material-ui/icons" "^4.9.1" custom-form-example-plugin "*"