Skip to content
Open
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
144 changes: 144 additions & 0 deletions accepted/0000-composer-module.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
# Composer Module

## Summary

Add new library `@orchestrator/composer` that will allow to compose configuration for orchestrator visually via drag-n-drop.

## Motivation

This will allow users to configure their UI visually and generate JSON from that for future use.

## Detailed Explanation

It should expose component `<orc-composer>` that will render all UI controls:

- `<orc-composer-components>` - will render list of all available components ready for dragging
- `<orc-composer-canvas>` - will render area for dropping components and configure them
- `<orc-composer-preview>` - will render currently configured components in live preview
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Also I would add 2 more components:

  • <orc-composer-errors> - will render list of errors that were while rendering
  • <orc-composer-json> - will render result json, aslo it should be possible to edit the whole config via this json. So when user clicks to download button, we can show this result and copy everything to clipboard.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Both of them can be part of <orc-composer-preview> but named differently and used internally in it.

- `<orc-composer-config>` - will render JSON configuration being built
- `<orc-composer-errors>` - will render all error from previous round of preview rendering
- `<orc-composer-controls>` - will render buttons to copy/reset configuration JSON

Those 6 components should also be exported to give more fine grained control over UI to end user.

### Example

First import composer module with all components that you want to be available

```ts
import { NgModule } from '@angular/core';
import { OrchestratorCoreModule } from '@orchestrator/core';
import { ComposerModule } from '@orchestrator/composer';
import { UiWebModule } from '@orchestrator/ui-web';

@NgModule({
imports: [
OrchestratorCoreModule.forRoot(),
ComposerModule.withComponents([
// Custom extra components comes here
]),
UiWebModule.forRoot(), // Extra modules with components also can be used
],
})
export class AppModule {}
```

Then render `<orc-composer>` component where you need

```ts
import { Component } from '@angular/core';

@Component({
selector: 'app-root',
template: `
<orc-composer></orc-composer>
`,
})
export class AppComponent {}
```

## Rationale and Alternatives

We should use already existing library for drag-n-drop support (ex. [`angular-gridster2`](https://github.com/tiberiuzuld/angular-gridster2)).

For UI we can use [Ant Design for Angular](https://github.com/NG-ZORRO/ng-zorro-antd) because it has rich set of high quality components.

For JSON rendering and functions configuration we will use [monaco editor](https://microsoft.github.io/monaco-editor/index.html).

## Implementation

Create module `ComposerModule` that will declare and export components:

- `ComposerComponent`
- `ComposerComponentsComponent`
- `ComposerCanvasComponent`
- `ComposerPreviewComponent`
- `ComposerConfigComponent`
- `ComposerErrorsComponent`
- `ComposerControlsComponent`

Create private components for internal use:

- `ComposerConfiguratorComponent` - should be used to render configuration controls for specific dynamic component
- `ComposerDroppableComponent` - should be used to accept dragged dynamic components. It will be rendered in empty slots of configuration component and last element in items

Communication between components may happen via inputs/outputs as well as via parent `ComposerComponent`.

Any errors during live preview of configuration must be rendered in `<orc-composer-errors>`.

### `ComposerComponent`

- Selector: `orc-composer`
- Will render `ComposerComponentsComponent`, `ComposerCanvasComponent` and `ComposerPreviewComponent` by default
- Or will accept projected template with those components for custom layout
- It should emit event `configUpdate` when config changes

### `ComposerComponentsComponent`

- Selector: `orc-composer-components`
- Will render a list of all currently available dynamic components ready for drag-n-dropping

### `ComposerCanvasComponent`

- Selector: `orc-composer-canvas`
- Will render area for dropping components from `ComposerComponentsComponent` and configure them in the modal window
- It should render `RenderItemComponent` inside with `ComposerDroppableComponent` in appropriate places
- When configuration is updated it should rearrange position of `ComposerDroppableComponent`

### `ComposerPreviewComponent`
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Component should have a download button and a copy button so the user can do either action faster.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Aggreed with duplicate button.


- Selector: `orc-composer-preview`
- It will render current json configuration via `orc-orchestrator`
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

We could use something like hightlight.js to display the JSON

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I think it's a good idea, it will be also useful for editing functions when configuring components.

For that matter I think monaco editor will be more suitable, it's what vscode is built on.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

This feature will allow to provide autocomplete in functions when writing them


### `ComposerConfigComponent`

- Selector: `orc-composer-config`
- It will render current json configuration

### `ComposerErrorsComponent`

- Selector: `orc-composer-errors`
- It will render list of errors from last live render

### `ComposerControlsComponent`

- Selector: `orc-composer-controls`
- It will render buttons to copy and reset JSON config

### `ComposerConfiguratorComponent`

- Selector: `orc-composer-configurator`
- It will render configuration controls for dynamic component provided from DI token `CONFIGURATION_COMPONENT`
- When user updates configuration it should emit event `configUpdate` with current config object
- It should validate configuration to the best it can before allowing to submit the config
- It should use `monaco-editor` for fields that are functions

### `ComposerDroppableComponent`

- Selector: `orc-composer-droppable`
- It will render droppable rectangular area for accepting dynamic components
- When such component will be dropped it should emit event `componentDropped` with dynamic component

## Prior Art

None