nm-select-table-operations
    src/app/shared/widgets/select-table-operations/select-table-operations.component.ts
| selector | nm-select-table-operations | 
| styleUrls | select-table-operations.component.scss | 
| templateUrl | ./select-table-operations.component.html | 
| constructor(injector: Injector, widgetFrameService: WidgetframeService, http: HttpClient, progressbarService: ProgressbarService) | |||||||||||||||
| 
                                    Parameters :
                                     
 | 
| Protected configureWidget | ||||||
| configureWidget(configuration: WidgetConfig | ||||||
| Decorators : WidgetConfigure | ||||||
| 
                                    Parameters :
                                     
 
                                Returns :      void | 
| createItem | 
| createItem() | 
| 
                                Returns :      void | 
| deleteItem | 
| deleteItem() | 
| 
                                Returns :      void | 
| editItem | 
| editItem() | 
| 
                                Returns :      void | 
| executeMenuAction | ||||
| executeMenuAction(action: ) | ||||
| 
                                    Parameters :
                                     
 
                                Returns :      void | 
| ngOnDestroy | 
| ngOnDestroy() | 
| 
                                Returns :      void | 
| reloadData | 
| reloadData() | 
| 
                                Returns :      void | 
| selectionChanged | ||||
| selectionChanged(row: ) | ||||
| 
                                    Parameters :
                                     
 
                                Returns :      void | 
| Public autoFocus | 
| autoFocus:      | 
| Type : boolean | 
| Default value : true | 
| Public columns | 
| columns:      | 
| Default value : new ReplaySubject<any>(1) | 
| Public configuration | 
| configuration:      | 
| Type : WidgetConfig<SelectTableOperationsConfiguration> | 
| Decorators : WidgetConfiguration | 
| Public createButtonTitle | 
| createButtonTitle:      | 
| Type : string | 
| Public createDialogConfig | 
| createDialogConfig:      | 
| Type : any | 
| Public createItemChannel | 
| createItemChannel:      | 
| Default value : new Subject<any>() | 
| Decorators : WidgetOutput | 
| Emits an event when create button is clicked | 
| Public dataObservable | 
| dataObservable:      | 
| Default value : new ReplaySubject<any>(1) | 
| Public dataType | 
| dataType:      | 
| Type : string | 
| Public dataUrl | 
| dataUrl:      | 
| Type : any | 
| Public deleteButtonTitle | 
| deleteButtonTitle:      | 
| Type : string | 
| Public deleteIcon | 
| deleteIcon:      | 
| Type : string | 
| Default value : HalService.iconForAction("delete") | 
| Public deleteItemChannel | 
| deleteItemChannel:      | 
| Default value : new Subject<any>() | 
| Decorators : WidgetOutput | 
| Emits an event when delete button is clicked | 
| Public deleteTooltip | 
| deleteTooltip:      | 
| Type : string | 
| Default value : "" | 
| Public dialog | 
| dialog:      | 
| Type : MatDialog | 
| Public disableCreate | 
| disableCreate:      | 
| Type : boolean | 
| Default value : true | 
| Public disableCreateButton | 
| disableCreateButton:      | 
| Type : ReplaySubject<boolean> | 
| Default value : new ReplaySubject(1) | 
| Decorators : WidgetInput | 
| Disables create button | 
| Public disableDelete | 
| disableDelete:      | 
| Type : boolean | 
| Default value : true | 
| Public disableDeleteButton | 
| disableDeleteButton:      | 
| Type : ReplaySubject<boolean> | 
| Default value : new ReplaySubject(1) | 
| Decorators : WidgetInput | 
| Disables delete button | 
| Public disableEdit | 
| disableEdit:      | 
| Type : boolean | 
| Default value : true | 
| Public disableEditButton | 
| disableEditButton:      | 
| Type : ReplaySubject<boolean> | 
| Default value : new ReplaySubject(1) | 
| Decorators : WidgetInput | 
| Disables edit button | 
| Public disableMenuAction | 
| disableMenuAction:      | 
| Type : any | 
| Default value : {} | 
| Public disableMenuActionChannel | 
| disableMenuActionChannel:      | 
| Default value : new BehaviorSubject<string>(null) | 
| Decorators : WidgetInput | 
| Disables menu action | 
| Public editButtonAsButton | 
| editButtonAsButton:      | 
| Type : boolean | 
| Public editButtonTitle | 
| editButtonTitle:      | 
| Type : string | 
| Public editDialogConfig | 
| editDialogConfig:      | 
| Type : any | 
| Public editItemChannel | 
| editItemChannel:      | 
| Default value : new Subject<any>() | 
| Decorators : WidgetOutput | 
| Emits an event when edit button is clicked | 
| Public enableMenuAction | 
| enableMenuAction:      | 
| Default value : new BehaviorSubject<string>(null) | 
| Decorators : WidgetInput | 
| Enables menu action | 
| Public executeMenuActionChannel | 
| executeMenuActionChannel:      | 
| Default value : new Subject<any>() | 
| Decorators : WidgetOutput | 
| Emits an event when a menu action button is clicked | 
| Public header | 
| header:      | 
| Type : string | 
| Public isDataLoaded | 
| isDataLoaded:      | 
| Type : Subject<boolean> | 
| Default value : new Subject() | 
| Decorators : WidgetOutput | 
| Emits when data loading is completed | 
| Public isDisabled | 
| isDisabled:      | 
| Default value : new BehaviorSubject<boolean>(false) | 
| Decorators : WidgetInput | 
| Disables the input field and row selection | 
| Public isTree | 
| isTree:      | 
| Type : boolean | 
| Public listService | 
| listService:      | 
| Type : DataListService | 
| Public loadDataChannel | 
| loadDataChannel:      | 
| Default value : new BehaviorSubject<string>(null) | 
| Decorators : WidgetInput | 
| Sets the URL used to load data | 
| Public localStorageKey | 
| localStorageKey:      | 
| Type : string | 
| Public menuInteractions | 
| menuInteractions:      | 
| Type : any[] | 
| Public preselection | 
| preselection:      | 
| Type : ReplaySubject<string> | 
| Default value : new ReplaySubject<string>(1) | 
| Decorators : WidgetInput | 
| Sets data table selected row | 
| Public preselectionById | 
| preselectionById:      | 
| Type : boolean | 
| Default value : false | 
| Public primaryKey | 
| primaryKey:      | 
| Type : string | 
| Public reloadChannel | 
| reloadChannel:      | 
| Default value : new BehaviorSubject<boolean>(true) | 
| Decorators : WidgetInput | 
| Reloads data and disable delete and edit buttons | 
| Public resetSelectionChannel | 
| resetSelectionChannel:      | 
| Default value : new BehaviorSubject<boolean>(null) | 
| Decorators : WidgetInput | 
| Resets selected row | 
| Public resetSelectionObservable | 
| resetSelectionObservable:      | 
| Default value : new ReplaySubject<any>(1) | 
| Public selectedRow | 
| selectedRow:      | 
| Type : Subject<SelectionParams> | 
| Default value : new Subject<SelectionParams>() | 
| Decorators : WidgetOutput | 
| Emits when a data row is selected | 
| Public selection | 
| selection:      | 
| Type : any | 
| Default value : null | 
| Public selectionDescription | 
| selectionDescription:      | 
| Type : string | 
| Public selectPlaceholder | 
| selectPlaceholder:      | 
| Type : any | 
| Public selectTableWidth | 
| selectTableWidth:      | 
| Type : any | 
| Public sendDialogConfig | 
| sendDialogConfig:      | 
| Type : any | 
| Public sortBy | 
| sortBy:      | 
| Type : SortBy[] | 
| Public title | 
| title:      | 
| Type : string | 
| Public toolbarInvisible | 
| toolbarInvisible:      | 
| Type : boolean | 
| Default value : false | 
| unsubscribe | 
| unsubscribe:      | 
| Default value : NgUnsubscribe.create() | 
| Public widgetId | 
| widgetId:      | 
| Type : string | 
| Decorators : WidgetId | 
| Public withButtons | 
| withButtons:      | 
| Type : boolean | 
import {
  WidgetComponent,
  WidgetConfiguration,
  WidgetId,
  WidgetInput,
  WidgetOutput,
  WidgetConfigure,
} from "../widget.metadata";
import { WidgetConfig } from "../widget.configuration";
import { NgUnsubscribe } from "../../../shared/ng-unsubscribe";
import { HalService } from "../../components/hal/hal.service";
import {
  getOrDefault,
  throwIfUndefined,
} from "../../widgets/widget.configuration";
import { ProgressbarService } from "../../components/progressbar";
import { WidgetframeService } from "../widgetframe/widgetframe.service";
import { SelectionParams, SortBy } from "../interfaces/list.interfaces";
import { DataListService } from "../data-list";
import { Component, Injector, OnInit } from "@angular/core";
import { HttpClient } from "@angular/common/http";
import { ReplaySubject, BehaviorSubject, Subject } from "rxjs";
import { MatDialog } from "@angular/material/dialog";
import { takeUntil } from "rxjs/operators";
import * as uriTemplates_ from "uri-templates";
import { SelectTableColumn } from "../../components/select-table/select-table.component";
const uriTemplates = uriTemplates_;
export interface SelectTableOperationsDialogConfig {
  /**
   * Dialog title
   */
  title: string;
}
export interface SelectTableOperationsMenuAction {
  /**
   * Action identifier
   */
  name: string;
  /**
   * Action title, should be a translation key
   */
  title: string;
  /**
   * Dialog configuration
   */
  dialogConfig?: SelectTableOperationsDialogConfig;
}
export interface SelectTableOperationsConfiguration {
  header?: string;
  /**
   * The title for the component header, should be a translation key
   */
  title?: string;
  /**
   * Local storage key
   */
  localStorageKey?: string;
  /**
   * Data type, the backend response list name
   */
  dataType: string;
  /**
   * Select table placeholder, should be a translation key
   */
  selectPlaceholder?: string;
  /**
   * Create button title, should be a translation key @default(button.create)
   */
  createButtonTitle?: string;
  /**
   * Edit button title, should be a translation key @default(label.edit)
   */
  editButtonTitle?: string;
  /**
   * Delete button title, should be a translation key @default(label.delete)
   */
  deleteButtonTitle?: string;
  /**
   * Create dialog configuration
   */
  createDialogConfig?: SelectTableOperationsDialogConfig;
  /**
   * Edit dialog configuration
   */
  editDialogConfig?: SelectTableOperationsDialogConfig;
  /**
   * Select table width percentage relative to overall widget width @default(50%)
   */
  selectTableWidth?: string;
  /**
   * Select table columns.
   */
  columns: SelectTableColumn[];
  /**
   * Hides\Shows the header of the frame @default(false)
   */
  toolbarInvisible?: boolean;
  /**
   * Shows\Hides action buttons (Create, Edit, Delete) @default(false)
   */
  withButtons?: boolean;
  /**
   * Shows Edit button as separate button Or in context menu @default(false)
   */
  editButtonAsButton?: boolean;
  /**
   * Render data table as tree grid @default(false)
   */
  isTree?: boolean;
  /**
   * If set to true the preselection channel selects the row by pimRef, otherwise the row is selected by identifier @default(false)
   */
  preselectionById?: boolean;
  /**
   * Data table row primary key @default(identifier)
   */
  primaryKey?: string;
  /**
   * Context menu actions configurations
   */
  menuInteractions?: SelectTableOperationsMenuAction[];
  /**
   * Data table sort by columns
   */
  sortBy?: SortBy[];
  /**
   * Auto focus @default(true)
   */
  autoFocus?: boolean;
  /**
   * Field to show when selecting an element @default(description)
   */
  selectionDescription?: string;
}
@WidgetComponent("nm-select-table-operations")
@Component({
  selector: "nm-select-table-operations",
  templateUrl: "./select-table-operations.component.html",
  styleUrls: ["./select-table-operations.component.scss"],
})
/*  TODO: BJaenichen : Pimweb-2159: this needs to be moved to a more general
 * directory. it should also be splitted into smaller components
 *
 */
export class SelectTableOperationsComponent {
  unsubscribe = NgUnsubscribe.create();
  public header: string;
  public dataObservable = new ReplaySubject<any>(1);
  public resetSelectionObservable = new ReplaySubject<any>(1);
  public columns = new ReplaySubject<any>(1);
  public listService: DataListService;
  public dialog: MatDialog;
  public selection: any = null;
  public dataType: string;
  public selectPlaceholder: any;
  public createButtonTitle: string;
  public deleteButtonTitle: string;
  public editButtonTitle: string;
  public deleteIcon: string = HalService.iconForAction("delete");
  public title: string;
  public deleteTooltip: string = "";
  public createDialogConfig: any;
  public editDialogConfig: any;
  public sendDialogConfig: any;
  public selectTableWidth: any;
  public toolbarInvisible: boolean = false;
  public dataUrl: any;
  public disableCreate: boolean = true;
  public disableDelete: boolean = true;
  public disableEdit: boolean = true;
  public disableMenuAction: any = {};
  public withButtons: boolean;
  public editButtonAsButton: boolean;
  public isTree: boolean;
  public preselectionById: boolean = false;
  public primaryKey: string;
  public menuInteractions: any[];
  public sortBy: SortBy[];
  public autoFocus: boolean = true;
  public selectionDescription: string;
  public localStorageKey: string;
  @WidgetId()
  public widgetId: string;
  /**
   * Emits when a data row is selected
   */
  @WidgetOutput("selectedItems")
  public selectedRow: Subject<SelectionParams> = new Subject<SelectionParams>();
  /**
   * Sets data table selected row
   */
  @WidgetInput("preselection")
  public preselection: ReplaySubject<string> = new ReplaySubject<string>(1);
  /**
   * Disables create button
   */
  @WidgetInput("disableCreateButton")
  public disableCreateButton: ReplaySubject<boolean> = new ReplaySubject(1);
  /**
   * Disables delete button
   */
  @WidgetInput("disableDeleteButton")
  public disableDeleteButton: ReplaySubject<boolean> = new ReplaySubject(1);
  /**
   * Disables edit button
   */
  @WidgetInput("disableEditButton")
  public disableEditButton: ReplaySubject<boolean> = new ReplaySubject(1);
  /**
   * Sets the URL used to load data
   */
  @WidgetInput("loadData")
  public loadDataChannel = new BehaviorSubject<string>(null);
  /**
   * Reloads data and disable delete and edit buttons
   */
  @WidgetInput("reload")
  public reloadChannel = new BehaviorSubject<boolean>(true);
  /**
   * Resets selected row
   */
  @WidgetInput("resetSelection")
  public resetSelectionChannel = new BehaviorSubject<boolean>(null);
  /**
   * Disables menu action
   */
  @WidgetInput("disableMenuAction")
  public disableMenuActionChannel = new BehaviorSubject<string>(null);
  /**
   * Enables menu action
   */
  @WidgetInput("enableMenuAction")
  public enableMenuAction = new BehaviorSubject<string>(null);
  /**
   * Emits an event when create button is clicked
   */
  @WidgetOutput("createItem")
  public createItemChannel = new Subject<any>();
  /**
   * Emits an event when edit button is clicked
   */
  @WidgetOutput("editItem")
  public editItemChannel = new Subject<any>();
  /**
   * Emits an event when delete button is clicked
   */
  @WidgetOutput("deleteItem")
  public deleteItemChannel = new Subject<any>();
  /**
   * Disables the input field and row selection
   */
  @WidgetInput("isDisabled")
  public isDisabled = new BehaviorSubject<boolean>(false);
  /**
   * Emits when data loading is completed
   */
  @WidgetOutput("isDataLoaded")
  public isDataLoaded: Subject<boolean> = new Subject();
  /**
   * Emits an event when a menu action button is clicked
   */
  @WidgetOutput("executeMenuAction")
  public executeMenuActionChannel = new Subject<any>();
  constructor(
    injector: Injector,
    private widgetFrameService: WidgetframeService,
    protected http: HttpClient,
    protected progressbarService: ProgressbarService
  ) {
    this.dialog = injector.get(MatDialog);
  }
  @WidgetConfiguration()
  public configuration: WidgetConfig<SelectTableOperationsConfiguration>;
  @WidgetConfigure()
  protected configureWidget(
    configuration: WidgetConfig<SelectTableOperationsConfiguration>
  ) {
    this.header = getOrDefault(configuration.configuration.header, "primary");
    this.title = getOrDefault(configuration.configuration.title, "");
    this.localStorageKey = getOrDefault(
      configuration.configuration.localStorageKey,
      ""
    );
    this.dataType = throwIfUndefined(configuration.configuration.dataType);
    this.selectPlaceholder = getOrDefault(
      configuration.configuration.selectPlaceholder,
      ""
    );
    this.createButtonTitle = getOrDefault(
      configuration.configuration.createButtonTitle,
      "button.create"
    );
    this.deleteButtonTitle = getOrDefault(
      configuration.configuration.deleteButtonTitle,
      "label.delete"
    );
    this.editButtonTitle = getOrDefault(
      configuration.configuration.editButtonTitle,
      "label.edit"
    );
    this.createDialogConfig = getOrDefault(
      configuration.configuration.createDialogConfig,
      null
    );
    this.editDialogConfig = getOrDefault(
      configuration.configuration.editDialogConfig,
      null
    );
    this.selectTableWidth = getOrDefault(
      configuration.configuration.selectTableWidth,
      "50%"
    );
    this.columns.next(configuration.configuration.columns);
    this.toolbarInvisible = getOrDefault(
      configuration.configuration.toolbarInvisible,
      false
    );
    this.withButtons = getOrDefault(
      configuration.configuration.withButtons,
      true
    );
    this.editButtonAsButton = getOrDefault(
      configuration.configuration.editButtonAsButton,
      false
    );
    this.isTree = getOrDefault(configuration.configuration.isTree, false);
    this.preselectionById = getOrDefault(
      configuration.configuration.preselectionById,
      false
    );
    this.primaryKey = getOrDefault(
      configuration.configuration.primaryKey,
      "identifier"
    );
    this.menuInteractions = getOrDefault(
      configuration.configuration.menuInteractions,
      []
    );
    this.sortBy = getOrDefault(configuration.configuration.sortBy, []);
    this.autoFocus = getOrDefault(configuration.configuration.autoFocus, true);
    this.selectionDescription =
      configuration.configuration.selectionDescription;
    this.loadDataChannel.pipe(takeUntil(this.unsubscribe)).subscribe((uri) => {
      if (uri) {
        this.dataUrl = uri;
        this.reloadData();
      }
    });
    this.reloadChannel.pipe(takeUntil(this.unsubscribe)).subscribe(() => {
      this.reloadData();
    });
    this.disableCreateButton
      .pipe(takeUntil(this.unsubscribe))
      .subscribe((disable) => {
        this.disableCreate = disable;
      });
    this.disableDeleteButton
      .pipe(takeUntil(this.unsubscribe))
      .subscribe((disable) => {
        this.disableDelete = disable;
      });
    this.disableMenuActionChannel
      .pipe(takeUntil(this.unsubscribe))
      .subscribe((action) => {
        this.disableMenuAction[action] = true;
      });
    this.enableMenuAction
      .pipe(takeUntil(this.unsubscribe))
      .subscribe((action) => {
        this.disableMenuAction[action] = false;
      });
    this.disableEditButton
      .pipe(takeUntil(this.unsubscribe))
      .subscribe((disable) => {
        this.disableEdit = disable;
      });
    this.resetSelectionChannel
      .pipe(takeUntil(this.unsubscribe))
      .subscribe((reset) => {
        if (reset) {
          this.resetSelectionObservable.next(true);
        }
      });
  }
  createItem() {
    if (this.createDialogConfig) {
      this.createItemChannel.next(this.createDialogConfig);
    } else {
      this.resetSelectionObservable.next(true);
      this.createItemChannel.next("event");
      this.selection = "";
    }
  }
  deleteItem() {
    this.deleteItemChannel.next(this.selection);
  }
  editItem() {
    if (this.selection) {
      let editDialogAndSelectedItem = {
        dialogConfig: this.editDialogConfig,
        selectedItem: this.selection,
      };
      this.editItemChannel.next(editDialogAndSelectedItem);
    }
  }
  executeMenuAction(action) {
    const actionConfig = {
      action: action.name,
      dialogConfig: action.dialogConfig,
      selectedItem: this.selection,
    };
    this.executeMenuActionChannel.next(actionConfig);
  }
  reloadData() {
    if (this.dataUrl) {
      this.widgetFrameService.getData(this.dataUrl).subscribe((data) => {
        this.dataObservable.next(data._embedded[this.dataType]);
        this.isDataLoaded.next(true);
      });
    }
  }
  selectionChanged(row) {
    this.selection = row;
    this.selectedRow.next(this.selection);
  }
  ngOnDestroy() {
    this.unsubscribe.destroy();
  }
}
<nm-widgetframe
  [configuration]="configuration"
  [header]="header"
  [toolbarInvisible]="toolbarInvisible"
>
  <ng-container slot="title">
    <p class="nm-widgetframe__title">
      {{ title | translate }}
    </p>
  </ng-container>
  <ng-container slot="content">
    <div class="nm-widgetframe__content">
      <div class="nm-selectTableOperations__wrapper">
        <nm-select-table
          class="select-table"
          [data]="dataObservable"
          [columns]="columns"
          [dataType]="dataType"
          [selectionDescription]="selectionDescription"
          [width]="selectTableWidth"
          [preselection]="preselection"
          [preselectionById]="preselectionById"
          [primaryKey]="primaryKey"
          (selectedRowOutput)="selectionChanged($event)"
          [placeholder]="selectPlaceholder | translate"
          [resetSelection]="resetSelectionObservable"
          [isTree]="isTree"
          [isDisabled]="isDisabled | async"
          [inputWidth]="'400px'"
          [sortBy]="sortBy"
          [autoFocus]="autoFocus"
          [localStorageKey]="localStorageKey"
        >
        </nm-select-table>
        <div class="u-flex-1"></div>
        <div class="nm-selectTableOperations__buttons">
          <div *ngIf="withButtons">
            <button
              mat-stroked-button
              class="btn-black"
              (click)="createItem()"
              [disabled]="disableCreate"
            >
              {{ createButtonTitle | translate }}
            </button>
            <nm-delete-button
              [isDisabled]="selection == null || disableDelete"
              [tooltip]="deleteTooltip"
              [placholder]="deleteButtonTitle"
              (action)="deleteItem()"
            ></nm-delete-button>
            <mat-menu #appMenu="matMenu" xPosition="before" yPosition="below">
              <button
                *ngFor="let action of menuInteractions"
                mat-menu-item
                class="select-table-menu-action"
                (click)="executeMenuAction(action)"
                [disabled]="
                  selection == null || disableMenuAction[action.name] !== false
                "
              >
                {{ action.title | translate }}
              </button>
            </mat-menu>
            <button
              mat-icon-button
              [matMenuTriggerFor]="appMenu"
              *ngIf="menuInteractions.length > 0"
            >
              <mat-icon>more_vert</mat-icon>
            </button>
          </div>
          <button
            *ngIf="editButtonAsButton"
            mat-stroked-button
            (click)="editItem()"
            [disabled]="selection == null || disableEdit"
          >
            {{ editButtonTitle | translate }}
          </button>
        </div>
      </div>
    </div>
  </ng-container>
</nm-widgetframe>