-
Notifications
You must be signed in to change notification settings - Fork 24
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
5 changed files
with
213 additions
and
85 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,8 +1,4 @@ | ||
# Initial setup | ||
|
||
|
||
|
||
#### How to use the Git Hub identity provider | ||
## How to use the Git Hub identity provider | ||
|
||
The `workspaces/orchestrator/app-config.yaml` and the `workspaces/orchestrator/packages/app/src/App.tsx` files contain sufficient configuration to use the Git Hub identity provider. | ||
|
||
|
@@ -17,41 +13,17 @@ export AUTH_GITHUB_CLIENT_SECRET=...fill | |
yarn dev | ||
``` | ||
|
||
|
||
#### API Development instruction | ||
|
||
Checkout the backstage-plugin | ||
If you need to change the OpenAPI spec, edit the [openapi.yaml](../plugins/orchestrator-common/src/openapi/openapi.yaml) according to your needs. | ||
After you update the spec, run: | ||
|
||
`git clone [email protected]:red-hat-developer-hub/backstage-plugins.git` | ||
`yarn --cwd plugins/orchestrator-common openapi:generate` | ||
|
||
If you need to change the OpenAPI spec, edit the [openapi.yaml](https://github.com/redhat-developer/rhdh-plugins/blob/main/workspaces/orchestrator/plugins/orchestrator-common/src/openapi/openapi.yaml) according to your needs and then execute from the project root folder: | ||
|
||
`yarn --cwd plugins/orchestrator-common openapi` | ||
|
||
This command updates the [generated files](https://github.com/redhat-developer/rhdh-plugins/blob/main/workspaces/orchestrator/plugins/orchestrator-common/src/generated) including API, client and docs. | ||
This command updates the [generated files](../plugins/orchestrator-common/src/generated/) including API, client and docs. | ||
|
||
> NOTE: Do not manually edit auto-generated files | ||
If you add a new component in the spec, then you need to export the generated typescript object [here](https://github.com/redhat-developer/rhdh-plugins/blob/main/workspaces/orchestrator/plugins/orchestrator-common/src/generated/client/api.ts). For example, if you define | ||
|
||
```yaml | ||
components: | ||
schemas: | ||
Person: | ||
type: object | ||
properties: | ||
name: | ||
type: string | ||
surname: | ||
type: string | ||
``` | ||
then | ||
```typescript | ||
export type Person = components['schemas']['Person']; | ||
``` | ||
|
||
When defining a new endpoint, you have to define the `operationId`. | ||
That `id` is the one that you can use to implement the endpoint logic. | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,136 @@ | ||
# Extensible Workflow Execution Form | ||
|
||
This capability enables developers to extend and customize the `react-jsonschema-form` workflow execution form component. It is designed to enable developers to implement a Backstage plugin that provides a custom decorator for the workflow execution form. This decorator supports overriding a selected set of [react-json-schema-form properties](https://rjsf-team.github.io/react-jsonschema-form/docs/api-reference/form-props) enabling the following features: | ||
|
||
- **Custom Validations:** Extend default JSON schema validation with: | ||
- **Synchronous Validation** via the `customValidate` property. | ||
- **Asynchronous Validation** via the `getExtraErrors` property, for validations requiring backend calls. | ||
- **Custom Components:** Replace default form components by overriding the `widgets` property. | ||
- **Interdependent Field Values:** Manage complex inter-field dependencies using the `onChange` and `formData` properties. | ||
|
||
The custom decorator is delivered via a factory method that leverages a [Backstage utility API](https://backstage.io/docs/api/utility-apis) provided by the orchestrator. To trigger the desired behavior, the workflow schema should include custom UI properties. | ||
|
||
For reference, an example plugin can be found [here](https://github.com/parodos-dev/custom-form-example-plugin). | ||
|
||
## API | ||
|
||
To implement the API, include @red-hat-developer-hub/backstage-plugin-orchestrator-form-api package as a dependency. | ||
This package provides the `FormExtensionsApi` interface and related types. | ||
|
||
```typescript | ||
export type FormDecoratorProps = Pick< | ||
FormProps<JsonObject, JSONSchema7>, | ||
'formData' | 'formContext' | 'widgets' | 'onChange' | 'customValidate' | ||
> & { | ||
getExtraErrors?: ( | ||
formData: JsonObject, | ||
) => Promise<ErrorSchema<JsonObject>> | undefined; | ||
}; | ||
|
||
export type FormDecorator = ( | ||
FormComponent: React.ComponentType<FormDecoratorProps>, | ||
) => React.ComponentType; | ||
|
||
export interface FormExtensionsApi { | ||
getFormDecorator(schema: JSONSchema7): FormDecorator; | ||
} | ||
``` | ||
|
||
### Example API Implementation | ||
|
||
```typescript | ||
class CustomFormApi implements FormExtensionsApi { | ||
getFormDecorator(schema: JSONSchema7) { | ||
return (FormComponent: React.ComponentType<FormDecoratorProps>>) => { | ||
const widgets = {CountryWidget}; // CountryWidget needs to be implemneted and imported | ||
return () => <FormComponent widgets={widgets} />; | ||
}; | ||
} | ||
} | ||
``` | ||
|
||
### Plugin Creation Example | ||
|
||
```typescript | ||
export const formApiFactory = createApiFactory({ | ||
api: orchestratorFormApiRef, | ||
deps: {}, | ||
factory() { | ||
return new CustomFormApi(); | ||
}, | ||
}); | ||
|
||
export const testFactoryPlugin = createPlugin({ | ||
id: 'custom-form-plugin', | ||
apis: [formApiFactory], | ||
}); | ||
``` | ||
|
||
### Schema example for above plugin | ||
|
||
```typescript | ||
{ | ||
"type": "object", | ||
"properties": { | ||
"personalDetails": { | ||
"type": "object", | ||
"title": "Personal Details", | ||
"properties": { | ||
"name": { | ||
"type": "string", | ||
"title": "Name" | ||
}, | ||
"country": { | ||
"type": "string", | ||
"title": "Country", | ||
"ui:widget": "CountryWidget" | ||
} | ||
} | ||
}, | ||
"contactDetails": { | ||
"type": "object", | ||
"title": "Contact Details", | ||
"properties": { | ||
"email": { | ||
"type": "string", | ||
"title": "Email" | ||
}, | ||
"phone": { | ||
"type": "string", | ||
"title": "Phone Number" | ||
} | ||
} | ||
} | ||
} | ||
} | ||
``` | ||
|
||
### Dynamic plugin configuration example | ||
|
||
Add the following to backstage config to integrate the plugin: | ||
|
||
```yaml | ||
dynamicPlugins: | ||
frontend: | ||
custom-form-plugin: | ||
apiFactories: | ||
- importName: formApiFactory | ||
``` | ||
### Referencing the custom behavior in the schema | ||
The workflow execution schema adheres to the [json-schema](https://json-schema.org/) format, which allows for extending the schema with custom properties beyond the official specification. This flexibility enables the inclusion of additional [uiSchema](https://rjsf-team.github.io/react-jsonschema-form/docs/api-reference/uiSchema/) fields directly within the schema, as demonstrated in the example above. | ||
### How It All Comes Together | ||
The `orchestrator-form-react` plugin implements the form component for workflow execution. It integrates with the custom API provided by the developer's plugin to generate and customize the form. The `orchestrator` plugin then incorporates this form into the workflow execution page. | ||
|
||
The `orchestrator-form-react` plugin handles the following key tasks: | ||
|
||
- **Generating the UI Schema:** It extracts custom UI schema fields from the main schema, automatically generates the [uiSchema](https://rjsf-team.github.io/react-jsonschema-form/docs/api-reference/uiSchema/), and passes it to the `react-jsonschema-form` component, enabling advanced UI customizations. | ||
|
||
- **Organizing Forms into Wizard-Style Steps:** If the schema is an object containing nested objects (i.e., the root is an object, and its properties are also objects), the plugin organizes the form into multiple steps. Each nested object becomes a separate step in a wizard-style interface. For example, the schema provided above results in two steps: _Personal Details_ and _Contact Details_. | ||
|
||
The [`orchestrator-form-react`](https://github.com/janus-idp/backstage-plugins/tree/main/plugins/orchestrator-form-react) plugin is designed to operate independently of the main orchestrator plugin. This modularity allows developers to test and validate form behavior in a standalone Backstage development environment before integrating it with the full orchestrator setup. | ||
|
||
To use this plugin, add the `@red-hat-developer-hub/backstage-plugin-orchestrator-form-react` package as a dependency in your project. |
File renamed without changes