Custom Action via Object Actions Menu

The CLI component is only working for versions before 9.10. It must be upgraded to Angular 15 as well and will come later.

Example 1: Finalize

Description

In this example, we create our own implementation of the already existing 'Finalize' action.


Implementation

  1. Use a CLI command to generate a plug-in component with the name finalize-object-action.

    eo g action finalize-object-action
  2. Update finalize-object-action.component.ts to extend DmsObjectTarget and implement SimpleAction interface.

    finalize-object-action.component.ts
    import {of as observableOf} from 'rxjs';
    import {Component} from '@angular/core';
    import {SimpleAction} from '@eo-sdk/client';
    import {DmsObjectTarget, SelectionRange} from '@eo-sdk/client';
    import {DmsService, TranslateService, DmsObject} from '@eo-sdk/core';
    
    @Component({
      selector: 'eo-finalize-object-action',
      template: ``
    })
    export class FinalizeObjectActionComponent extends DmsObjectTarget implements SimpleAction {
      label: string;
      description: string;
      priority = 0;
      iconSrc = 'assets/_default/svg/ic_finalized.svg';
      group = 'common';
      range = SelectionRange.MULTI_SELECT;
    
      constructor(private translate: TranslateService, private dmsService: DmsService) {
        super();
        this.label = this.translate.instant('eo.custom.action.finalize-object-action.label');
        this.description = this.translate.instant('eo.custom.action.finalize-object-action.description');
      }
    
      isExecutable(item: DmsObject) {
        return observableOf((item.rights && item.rights.finalize) && !item.lock && !item.isFinalized);
      };
    
      run(selection: DmsObject[]) {
        selection.forEach(item => {
          this.dmsService.finalize(item).subscribe();
        });
      }
    }
    
    
  3. Use a CLI command to generate labels/translations.

    eo g label eo.custom.action.finalize-object-action.label --en "Finalize (new)" --de "Finalisieren (neu)"
    eo g label eo.custom.action.finalize-object-action.description --en "Finalizes the selected objects." --de "Finalisiert die markierten Objekte."

Example 2: Paint

Description

In this example, we utilize an already existing angular component to open and edit images. The changes will be saved back to the object.



Implementation

  1. Use a CLI command to generate a plug-in component with name paint-action.

    eo g action paint-action
  2. Update paint-action.component.ts to extend DmsObjectTarget and implement ExternalComponentAction interface.

    paint-action.component.ts
    import {Component} from '@angular/core';
    import {of as observableOf} from 'rxjs';
    import {DmsObjectTarget} from '@eo-sdk/client';
    import {DmsObject} from '@eo-sdk/core';
    import {SelectionRange} from '@eo-sdk/client';
    import {ExternalComponentAction} from '@eo-sdk/client';
    import {PaintComponent} from './paint/paint.component';
    import {TranslateService} from '@eo-sdk/core';
    
    @Component({
      selector: 'eo-paint-action',
      template: ``
    })
    export class PaintActionComponent extends DmsObjectTarget implements ExternalComponentAction {
      extComponents = PaintComponent;
      // component = PaintComponent;
      label: string;
      description: string;
      priority = 0;
      iconSrc = 'assets/_default/svg/ic_edit.svg';
      group = 'common';
      range = SelectionRange.SINGLE_SELECT;
      api: any;
    
      constructor(private translate: TranslateService) {
        super();
        this.label = this.translate.instant('eo.custom.action.menu.edit.picture.label');
        this.description = this.translate.instant('eo.custom.action.menu.edit.picture.description');
      }
    
      isExecutable(element: DmsObject) {
        // enable action only if DmsObject can be edited
        return observableOf(!!element.content && !element.isFinalized && element.rights.edit);
      }
    }
  3. Use a CLI command to install the canvas package.

    npm install -P ng2-canvas-whiteboard
  4. Import CanvasWhiteboardModule module to CustomActionsModule.

    custom-actions.module.ts
    import {NgModule} from '@angular/core';
    import {CommonModule} from '@angular/common';
    import {EoFrameworkModule} from '@eo-sdk/client';
    import {ActionModule} from '@eo-sdk/client';
    import {BaseAction} from '@eo-sdk/client';
    import {PaintActionComponent} from './paint-action/paint-action.component';
    import {CanvasWhiteboardModule} from 'ng2-canvas-whiteboard';
    
    export const entryComponents: BaseAction[] = [
      PaintActionComponent,
    ];
    
    @NgModule({
      imports: [
        CommonModule,
        EoFrameworkModule,
        CanvasWhiteboardModule,
        ActionModule.forRoot(entryComponents)
      ],
      declarations: [PaintActionComponent],
      exports: [ActionModule]
    })
    export class CustomActionsModule {
    }
    
    
  5. Use a CLI command to generate a plug-in component with name paint inside of paint-action.

    eo g action paint-action/paint
  6. Update paint.component.ts to implement ActionComponent inteface, plus create dialog with canvas.

    paint.component.ts
    import {Component, EventEmitter, OnInit, ViewChild} from '@angular/core';
    import {CanvasWhiteboardComponent, CanvasWhiteboardOptions} from 'ng2-canvas-whiteboard';
    import {ActionComponent} from '@eo-sdk/client';
    import {EnaioEvent} from '@eo-sdk/core';
    import {PluginsService} from '@eo-sdk/client';
    import {HttpClient} from '@angular/common/http';
    
    // temporary fix: rxjs not compatible
    CanvasWhiteboardComponent.prototype['_initCanvasEventListeners'] = function () {};
    
    @Component({
      selector: 'eo-paint',
      template: `
        <eo-dialog [title]="'Paint'"
               [visible]="true"
               [minWidth]="1000"
               [minHeight]="630"
               #dialog>
          <section>
            <div class="canvas-container" [style.minWidth.px]="700" [style.height.px]="1000">
              <canvas-whiteboard #canvasWhiteboard
                                 [options]="canvasOptions"
                                 [imageUrl]="imgUrl"
                                 (onSave)="onCanvasSave($event)">
              </canvas-whiteboard>
            </div>
          </section>
        </eo-dialog>
      `,
      viewProviders: [CanvasWhiteboardComponent],
      styles: [`
      ::ng-deep .canvas_whiteboard_buttons,
      ::ng-deep .canvas_whiteboard_button
      { background: rgba(255,255,255,0.2); color:#000; }`
      ]
    })
    export class PaintComponent implements OnInit, ActionComponent {
    
      @ViewChild('canvasWhiteboard') canvasWhiteboard: CanvasWhiteboardComponent;
    
      selection: any[];
      finished: EventEmitter<any> = new EventEmitter();
      canceled: EventEmitter<any> = new EventEmitter();
      canvasOptions: CanvasWhiteboardOptions;
      imgUrl: string;
      api: any;
      static isSubAction = true;
    
      constructor(private pluginService: PluginsService, private http: HttpClient) {
        this.api = pluginService.getApi();
      }
    
      ngOnInit() {
        this.canvasOptions = {
          drawButtonEnabled: true,
          drawButtonClass: 'drawButtonClass',
          drawButtonText: 'Draw',
          clearButtonEnabled: true,
          clearButtonClass: 'clearButtonClass',
          clearButtonText: 'Clear',
          undoButtonText: 'Undo',
          undoButtonEnabled: true,
          redoButtonText: 'Redo',
          redoButtonEnabled: true,
          colorPickerEnabled: true,
          saveDataButtonEnabled: true,
          saveDataButtonText: 'Save',
          lineWidth: 4,
          scaleFactor: 1,
          shouldDownloadDrawing: false
        };
        this.imgUrl = `${this.api.config.get().serviceBase}/dms/${this.selection[0].id}/content?type=${this.selection[0].typeName}`;
      }
    
      onCanvasSave(e) {
        let uri = this.imgUrl.replace('content?', 'contents?');
        this.canvasWhiteboard.generateCanvasBlob((blob: any) => {
          blob.name = 'Bild';
          let files = [blob];
          this.upload(uri, files)
            .then(() => {
              return this.api.dms.getObject(this.selection[0].id, this.selection[0].typeName);
            })
            .then(dmsObject => {
              this.api.events.trigger(EnaioEvent.DMS_OBJECT_UPDATED, dmsObject);
              this.finished.emit();
            });
        }, 'image/png');
      }
    
      upload(uri: string, files: File[]) {
        let formData = new FormData();
        for (let file of files) {
          formData.append('files[]', file, this.api.util.encodeFileName(file.name));
        }
        return this.http.post(uri, formData).toPromise();
      }
    
    }    
    
    
  7. Use a CLI command to generate labels/translations.

    eo g label eo.custom.action.menu.edit.picture.label --en "Edit picture" --de "Bild bearbeiten"
    eo g label eo.custom.action.menu.edit.picture.description --en "Edit picture of the selected object." --de "Bild des markierten Objekts bearbeiten."