Skip to content

Commit

Permalink
[AAE-3493] Update the documentation to provide the proper guidance on…
Browse files Browse the repository at this point in the history
… custom forms widgets for APA and APS developers (#6158)

* * improve docs

* * assets fixed

* * links fixed

* * versions fixed

* * assets added

* * fix links

* Update docs/user-guide/aae-extensions.md

Co-authored-by: Mark Hulbert <39801222+m-hulbert@users.noreply.github.com>

* Update docs/user-guide/aae-extensions.md

Co-authored-by: Mark Hulbert <39801222+m-hulbert@users.noreply.github.com>

* Update docs/user-guide/aae-extensions.md

Co-authored-by: Mark Hulbert <39801222+m-hulbert@users.noreply.github.com>

* Update docs/user-guide/aae-extensions.md

Co-authored-by: Mark Hulbert <39801222+m-hulbert@users.noreply.github.com>

* Update docs/user-guide/aae-extensions.md

Co-authored-by: Mark Hulbert <39801222+m-hulbert@users.noreply.github.com>

* Update docs/user-guide/aae-extensions.md

Co-authored-by: Mark Hulbert <39801222+m-hulbert@users.noreply.github.com>

* Update docs/user-guide/aae-extensions.md

Co-authored-by: Mark Hulbert <39801222+m-hulbert@users.noreply.github.com>

* Update docs/user-guide/aae-extensions.md

Co-authored-by: Mark Hulbert <39801222+m-hulbert@users.noreply.github.com>

* Update docs/user-guide/aae-extensions.md

Co-authored-by: Mark Hulbert <39801222+m-hulbert@users.noreply.github.com>

* Update docs/user-guide/aae-extensions.md

Co-authored-by: Mark Hulbert <39801222+m-hulbert@users.noreply.github.com>

* Update docs/user-guide/aae-extensions.md

Co-authored-by: Mark Hulbert <39801222+m-hulbert@users.noreply.github.com>

* Update docs/user-guide/aae-extensions.md

Co-authored-by: Mark Hulbert <39801222+m-hulbert@users.noreply.github.com>

* Apply suggestions from code review

Co-authored-by: Mark Hulbert <39801222+m-hulbert@users.noreply.github.com>

* * example fixed

* * minor changes

* Make stencils document step-based

Co-authored-by: Mark Hulbert <39801222+m-hulbert@users.noreply.github.com>
Co-authored-by: Mark Hulbert <mark.hulbert@alfresco.com>
  • Loading branch information
3 people committed Sep 25, 2020
1 parent c84ef73 commit d7f0fa5
Show file tree
Hide file tree
Showing 13 changed files with 411 additions and 183 deletions.
8 changes: 6 additions & 2 deletions demo-shell/src/app/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,10 @@ import { ProcessServicesCloudModule } from '@alfresco/adf-process-services-cloud
import { FilteredSearchComponent } from './components/files/filtered-search.component';
import { RouterModule } from '@angular/router';
import { ProcessCloudLayoutComponent } from './components/cloud/process-cloud-layout.component';
import { SampleWidgetComponent } from './components/cloud/custom-form-components/sample-widget.component';
import {
CustomEditorComponent,
CustomWidgetComponent
} from './components/cloud/custom-form-components/custom-editor.component';

import { registerLocaleData } from '@angular/common';
import localeFr from '@angular/common/locales/fr';
Expand Down Expand Up @@ -188,7 +191,8 @@ registerLocaleData(localeSv);
ConfirmDialogExampleComponent,
FormCloudDemoComponent,
ConfirmDialogExampleComponent,
SampleWidgetComponent,
CustomEditorComponent,
CustomWidgetComponent,
ProcessCloudLayoutComponent
],
providers: [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,10 @@ import {
FormCloudService
} from '@alfresco/adf-process-services-cloud';
import { Subscription } from 'rxjs';
import { SampleWidgetComponent } from '../../../cloud/custom-form-components/sample-widget.component';
import {
CustomEditorComponent,
CustomWidgetComponent
} from '../../../cloud/custom-form-components/custom-editor.component';

@Component({
templateUrl: 'cloud-form-demo.component.html',
Expand Down Expand Up @@ -60,7 +63,16 @@ export class FormCloudDemoComponent implements OnInit, OnDestroy {
private automationService: CoreAutomationService,
private formRenderingService: FormRenderingService) {
this.formRenderingService.register({
'custom': () => SampleWidgetComponent
'demo-widget': () => CustomEditorComponent,
'custom-editor': () => CustomEditorComponent,
'custom-string': () => CustomWidgetComponent,
'custom-datetime': () => CustomWidgetComponent,
'custom-file': () => CustomWidgetComponent,
'custom-number': () => CustomWidgetComponent,
'custom-something': () => CustomWidgetComponent,
'custom-boolean': () => CustomWidgetComponent,
'custom-date': () => CustomWidgetComponent,
'custom': () => CustomWidgetComponent
});
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,29 @@

import { Component, OnInit } from '@angular/core';
import { FormService, WidgetComponent } from '@alfresco/adf-core';
// tslint:disable:component-selector

@Component({
selector: 'custom-editor-widget',
template: `
<div style="color: green">
ADF version of custom form widget
</div>
`
})
export class CustomEditorComponent extends WidgetComponent {
constructor() {
super();
}
}

@Component({
selector: 'app-sample-widget',
template: `
<div style="color: red">
Look, I'm custom cloud form widget!
<p *ngIf="field.readOnly || readOnly">
Value :: <span> {{displayValue}}</span>
<label class="adf-label" [attr.for]="field.id">{{field.name | translate }}<span *ngIf="isRequired()">*</span></label>
<span>{{field.value}}</span>
</p>
<mat-form-field *ngIf="!(field.readOnly || readOnly)">
Expand All @@ -37,21 +52,20 @@ import { FormService, WidgetComponent } from '@alfresco/adf-core';
[value]="field.value"
[(ngModel)]="field.value"
(ngModelChange)="onFieldChanged(field)">
<mat-hint>{{field.placeholder}}</mat-hint>
</mat-form-field>
<error-widget [error]="field.validationSummary"></error-widget>
<error-widget *ngIf="isInvalidFieldRequired()" required="{{ 'FORM.FIELD.REQUIRED' | translate }}"></error-widget>
</div>
`
})
export class SampleWidgetComponent extends WidgetComponent implements OnInit {

displayValue: string;
export class CustomWidgetComponent extends WidgetComponent implements OnInit {

constructor(public formService: FormService) {
super(formService);
}

ngOnInit() {
this.displayValue = this.field.value;
this.field.value = typeof this.field.value === 'object' ? JSON.stringify(this.field.value) : this.field.value;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
import { Component } from '@angular/core';
import { FormRenderingService } from '@alfresco/adf-core';
import { CloudFormRenderingService } from '@alfresco/adf-process-services-cloud';
import { SampleWidgetComponent } from './custom-form-components/sample-widget.component';
import { CustomEditorComponent, CustomWidgetComponent } from './custom-form-components/custom-editor.component';

@Component({
template: `<router-outlet></router-outlet>`,
Expand All @@ -30,7 +30,16 @@ export class ProcessCloudLayoutComponent {

constructor(private formRenderingService: FormRenderingService) {
this.formRenderingService.register({
'custom': () => SampleWidgetComponent
'custom-editor': () => CustomEditorComponent,
'demo-widget': () => CustomEditorComponent,
'custom-string': () => CustomWidgetComponent,
'custom-datetime': () => CustomWidgetComponent,
'custom-file': () => CustomWidgetComponent,
'custom-number': () => CustomWidgetComponent,
'custom-something': () => CustomWidgetComponent,
'custom-boolean': () => CustomWidgetComponent,
'custom-date': () => CustomWidgetComponent,
'custom': () => CustomWidgetComponent
});
}
}
Binary file added docs/docassets/images/aae-form-widget.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/docassets/images/aae-form-with-widget.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/docassets/images/aae-resolved-widget.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/docassets/images/aae-simple-form.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/docassets/images/aae-unresolved-widget.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
172 changes: 172 additions & 0 deletions docs/user-guide/aae-extensions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
---
Title: Form Extensibility for AAE Form Widget
Added: v4.1.0
---

## Form Extensibility for AAE Form Widget
This page describes how you can customize ADF forms to your own specification.

## Contents
There are two ways to customize the form
- [Replace default form widgets with custom components](#replace-default-form-widgets-with-aae-form-widgets)
- [Replace custom form widget with custom components](#replace-custom-form-widgets-with-custom-components)

## Replace default form widgets with AAE form widgets

This is an example of replacing the standard `Text` [widget](../../lib/testing/src/lib/core/pages/form/widgets/widget.ts) with a custom component for all AAE forms rendered within the `<adf-form>` component.

1. Create a simple form with some `Text` widgets:

![default text widget](../docassets/images/aae-simple-form.png)

Every custom widget component must inherit the [`WidgetComponent`](../insights/components/widget.component.md) class in order to function properly:

```ts
import { Component } from '@angular/core';
import { WidgetComponent } from '@alfresco/adf-core';
@Component({
selector: 'custom-editor',
template: `
<div style="color: red">Look, I'm a AAE custom editor!</div>
`
})
export class CustomEditorComponent extends WidgetComponent {}
```

2. Add it to the application module or any custom module that is imported into the application one:

```ts
import { NgModule } from '@angular/core';
import { CustomEditorComponent } from './custom-editor.component';
@NgModule({
declarations: [ CustomEditorComponent ],
exports: [ CustomEditorComponent ]
})
export class CustomEditorsModule {}
```

3. Every custom widget component should be added into the the collections `declarations` and `exports`. If you decided to store custom widgets in a separate dedicated module (and optionally as a separate re-distributable library) don't forget to import it into the main application:

```ts
@NgModule({
imports: [
// ...
CustomEditorsModule
// ...
],
providers: [],
bootstrap: [ AppComponent ]
})
export class AppModule {}
```

4. Import the [`FormRenderingService`](../core/services/form-rendering.service.md) into any of your Views and override the default mapping, for example:

```ts
import { Component } from '@angular/core';
import { CustomEditorComponent } from './custom-editor.component';
@Component({...})
export class MyView {
constructor(formRenderingService: FormRenderingService) {
this.formRenderingService.register({
'text': () => CustomEditorComponent
}, true);
}
}
```

5. At runtime the form should look similar to the following:

![custom text widget](../docassets/images/aae-simple-override-form.png)


## Replace custom form widgets with custom components

This is an example of rendering custom form widgets using custom Angular components.

### Create a custom form widget

To begin, create a basic form widget and call it `demo-widget`:

![custom form widget](../docassets/images/aae-form-widget.png)

**Note**: The `type` is important as it will become the `field type` when the form is rendered.

You can now design a form that uses your custom form widget:

![custom form widget form](../docassets/images/aae-form-with-widget.png)

### Create a custom widget

When displayed in a task, the field will look similar to the following:

![adf form widget](../docassets/images/aae-unresolved-widget.png)


To render the missing content:

1. Create an Angular component:

```ts
import { Component } from '@angular/core';
import { WidgetComponent } from '@alfresco/adf-core';
@Component({
selector: 'app-demo-widget',
template: `<div style="color: green">ADF version of custom form widget</div>`
})
export class DemoWidgetComponent extends WidgetComponent {}
```

2. Place it inside the custom module:

```ts
import { NgModule } from '@angular/core';
import { DemoWidgetComponent } from './demo-widget.component';
@NgModule({
declarations: [ DemoWidgetComponent ],
exports: [ DemoWidgetComponent ]
})
export class CustomWidgetsModule {}
```

3. Import it into your Application Module:

```ts
@NgModule({
imports: [
// ...
CustomWidgetsModule
// ...
],
providers: [],
bootstrap: [ AppComponent ]
})
export class AppModule {}
```

4. Import the [`FormRenderingService`](../core/services/form-rendering.service.md) in any of your Views and provide the new mapping:

```ts
import { Component } from '@angular/core';
import { DemoWidgetComponent } from './demo-widget.component';
@Component({...})
export class MyView {
constructor(formRenderingService: FormRenderingService) {
this.formRenderingService.register({
'custom-editor': () => DemoWidgetComponent
});
}
}
```

At runtime you should now see your custom Angular component rendered in place of the original form widgets:

![adf form widget runtime](../docassets/images/aae-resolved-widget.png)

## See Also

- [Extensibility](./extensibility.md)
- [Form field model](../core/models/form-field.model.md)
- [Form rendering service](../core/services/form-rendering.service.md)
- [Form component](../core/components/form.component.md)
- [Widget component](../insights/components/widget.component.md)

0 comments on commit d7f0fa5

Please sign in to comment.