Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

docs(orchestrator): improve readme #227

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
260 changes: 94 additions & 166 deletions workspaces/orchestrator/README.md

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion workspaces/orchestrator/app-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ auth:
# permission:
# enabled: true
# rbac:
# policies-csv-file: ../../plugins/orchestrator/docs/rbac-policy.csv
# policies-csv-file: ./docs/rbac-policy.csv
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If a relative path is used then it is from the rhdh-plugins/workspaces/orchestrator/packages/backend.

I would keep the former value

# policyFileReload: true
# admin:
# users:
Expand Down
70 changes: 70 additions & 0 deletions workspaces/orchestrator/docs/Contributors.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
## How to use the Git Hub identity provider
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: s/Git Hub/GitHub


The [app config](../app-config.yaml) and the [App.tsx](../packages/app/src/App.tsx) files contain sufficient configuration to use the Git Hub identity provider.

Follow these steps to login to backstage using your github account:

### Create a Github OAuth App
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

s/Github/GitHub


Go to your Github account -> Setting -> Developer settings -> OAuth Apps -> New OAuth App.
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

s/Github/GitHub

Enter a name, enter http://localhost:3000 to Homepage URL and http://localhost:7007/api/auth/github/handler/frame to Authorization callback URL and click on Register applicatdion.

### Update backstage user entity

Update [users.yaml](../users.yaml) to match you Github account. Put your github username in the metadata.name field, and you github email in spec.profile.email field.
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

s/Github/GitHub

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps a snippet will be a simpler option of a User entity (just a thought)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you have it in ../users.yaml


### Setup environment variables and run

```
export AUTH_GITHUB_CLIENT_ID=...fill from OAuth App client ID
export AUTH_GITHUB_CLIENT_SECRET=...fill from OAuth App client secret

yarn dev
```

## API Development instruction
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't this section go under orchestrator-common/README.md and be pointed from here or the other way around?


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:

`yarn --cwd plugins/orchestrator-common openapi:generate`

This command updates the [generated files](../plugins/orchestrator-common/src/generated/) including API, client and docs.

> NOTE: Do not manually edit auto-generated files

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.

For example, let's assume you add

```yaml
paths:
/names:
get:
operationId: getNames
description: Get a list of names
responses:
'200':
description: Success
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/Person'
```

Then you can implement the endpoint in [router.ts](https://github.com/redhat-developer/rhdh-plugins/blob/main/workspaces/orchestrator/plugins/orchestrator-backend/src/service/router.ts) referring the operationId `getNames`:

```typescript
api.register('getNames', async (_c, _req, res: express.Response, next) => {
// YOUR LOGIC HERE
const result: Person[] = [
{ name: 'John', surname: 'Snow' },
{ name: 'John', surname: 'Black' },
];

res.status(200).json(result);
});
```
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ See https://casbin.org/docs/rbac for more information about casbin rules.

## Enable permissions

To enable permissions, you need to add the following in the [app-config file](../../../app-config.yaml):
To enable permissions, you need to add the following in the [app-config file](../app-config.yaml):

```
permission:
Expand Down
136 changes: 136 additions & 0 deletions workspaces/orchestrator/docs/extensibleForm.md
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.
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.


To use this plugin, add the `@red-hat-developer-hub/backstage-plugin-orchestrator-form-react` package as a dependency in your project.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
Binary file not shown.
Binary file not shown.
35 changes: 0 additions & 35 deletions workspaces/orchestrator/plugins/orchestrator/docs/quickstart.md

This file was deleted.

Binary file not shown.
Binary file not shown.
Loading