<am-search-bar (valueChanges)="searchList($event)"></am-search-bar>
<ejs-grid
#grid
id="grid"
[pageSettings]="pageSettings"
[allowPaging]="true"
[editSettings]="editSettings"
[toolbar]="toolbar"
[gridLines]="lines"
[allowFiltering]="true"
[filterSettings]="filterSettings"
[allowSorting]="true"
[allowMultiSorting]="true"
showColumnChooser="true"
[allowReordering]="true"
[allowResizing]="true"
[allowRowDragAndDrop]="allowRowDragAndDrop"
[allowSelection]="true"
[allowPdfExport]="true"
[allowExcelExport]="true"
(actionBegin)="actionBegin($event)"
(dataBound)="dataBound()"
(dataStateChange)="dataStateChange($event)"
(rowDrop)="rowDrop($event)"
(actionFailure)="onActionFailure($event)"
(actionComplete)="saveGridState()"
(resizeStop)="saveGridState()"
>
<ng-template #emptyRecordTemplate>
<span class="loader" *ngIf="showLoader; else reallyEmpty">
<ejs-skeleton
[width]="'100%'"
[height]="'28px'"
*ngFor="let _ of [].constructor(5)"
></ejs-skeleton>
</span>
<ng-template #reallyEmpty>
<div class="empty-records">
<img src="assets/images/empty-records.svg" alt="No records" />
<span>{{ 'Common.Grid.NoData' | translate }}</span>
</div>
</ng-template>
</ng-template>
<e-columns>
<e-column
[width]="'36px'"
field="order"
headerText=""
[customAttributes]="{ class: 'order-column' }"
[showInColumnChooser]="false"
[allowReordering]="false"
[allowFiltering]="false"
[allowResizing]="false"
[allowEditing]="false"
[filterBarTemplate]="''"
>
</e-column>
<e-column
type="checkbox"
[width]="'32px'"
[showInColumnChooser]="false"
[allowReordering]="false"
[allowResizing]="false"
[allowSorting]="false"
></e-column>
<e-column
field="id"
[isPrimaryKey]="true"
[visible]="false"
[allowEditing]="false"
[showInColumnChooser]="false"
></e-column>
<e-column
field="code"
[headerText]="'Processes.Headers.Code' | translate"
width="120"
></e-column>
<e-column
field="nameEN"
[visible]="true"
[headerText]="('Processes.Headers.Name' | translate) + ' (EN)'"
></e-column>
<e-column
field="nameNL"
[visible]="currentLanguage === 'nl'"
[headerText]="('Processes.Headers.Name' | translate) + ' (NL)'"
></e-column>
<e-column
field="nameFR"
[visible]="currentLanguage === 'fr'"
[headerText]="('Processes.Headers.Name' | translate) + ' (FR)'"
></e-column>
<e-column
field="nameDE"
[visible]="currentLanguage === 'de'"
[headerText]="('Processes.Headers.Name' | translate) + ' (DE)'"
></e-column>
<e-column
field="nameES"
[visible]="currentLanguage === 'es'"
[headerText]="('Processes.Headers.Name' | translate) + ' (ES)'"
></e-column>
<e-column
field="nameSK"
[visible]="currentLanguage === 'sk'"
[headerText]="('Processes.Headers.Name' | translate) + ' (SK)'"
></e-column>
<e-column
field="namePL"
[visible]="currentLanguage === 'pl'"
[headerText]="('Processes.Headers.Name' | translate) + ' (PL)'"
></e-column>
<e-column
field="descriptionEN"
[visible]="currentLanguage === 'en'"
[headerText]="('Processes.Headers.Description' | translate) + ' (EN)'"
></e-column>
<e-column
field="descriptionNL"
[visible]="currentLanguage === 'nl'"
[headerText]="('Processes.Headers.Description' | translate) + ' (NL)'"
></e-column>
<e-column
field="descriptionFR"
[visible]="currentLanguage === 'fr'"
[headerText]="('Processes.Headers.Description' | translate) + ' (FR)'"
></e-column>
<e-column
field="descriptionDE"
[visible]="currentLanguage === 'de'"
[headerText]="('Processes.Headers.Description' | translate) + ' (DE)'"
></e-column>
<e-column
field="descriptionES"
[visible]="currentLanguage === 'es'"
[headerText]="('Processes.Headers.Description' | translate) + ' (ES)'"
></e-column>
<e-column
field="descriptionSK"
[visible]="currentLanguage === 'sk'"
[headerText]="('Processes.Headers.Description' | translate) + ' (SK)'"
></e-column>
<e-column
field="descriptionPL"
[visible]="currentLanguage === 'pl'"
[headerText]="('Processes.Headers.Description' | translate) + ' (PL)'"
></e-column>
<e-column
field="wcmPillarNames"
[headerText]="'Processes.Headers.WcmPillars' | translate"
[allowSorting]="false"
>
<ng-template #editTemplate let-data>
<ejs-multiselect
[dataSource]="wcmPillars$ | async"
[fields]="wcmPillarFields"
[(value)]="selectedWcmPillarIds[data.id]"
></ejs-multiselect>
</ng-template>
</e-column>
<e-column
field="strategicalAxisNames"
[headerText]="'Processes.Headers.StrategicalAxis' | translate"
[allowSorting]="false"
>
<ng-template #editTemplate let-data>
<ejs-multiselect
[dataSource]="strategicalAxises$ | async"
[fields]="strategicalAxisFields"
[(value)]="selectedStrategicalAxisIds[data.id]"
></ejs-multiselect>
</ng-template>
</e-column>
</e-columns>
</ejs-grid>
<am-custom-toolbar
[filterTypeItems]="filterTypeItems"
[gridLineItems]="gridLineItems"
[freezingOptions]="freezingOptions"
[selectedFrozenColumns]="selectedFrozenColumns"
[selectedFilterType]="grid.filterSettings.type"
[selectedGridlineItem]="grid.gridLines"
(filterChange)="filterChangeHandler($event)"
(gridLineChange)="gridLinesChangeHandler($event)"
(freezeChange)="handleFreezeChange($event, $event.field)"
(clearFiltering)="handleClearFiltering()"
>
</am-custom-toolbar>
import { AfterViewInit, Component, Inject, Input, OnDestroy, OnInit, ViewChild } from '@angular/core';
import { FormArray } from '@angular/forms';
import { APP_CONFIG, CoreConfig, TranslationService } from '@arcelormittal-platform/core';
import { AuthenticationService } from '@arcelormittal-platform/security';
import { SnackBarService, SnackBarType } from '@arcelormittal-platform/ui';
import { StrategicalAxisDropdownItem, WcmPillarDropdownItem } from '@masterdata/models';
import {
ProcessesGridService,
StrategicalAxisesService,
WcmPillarsService
} from '@masterdata/services';
import { TranslateService } from '@ngx-translate/core';
import { GridService, ToolbarConfigService } from '@shared/services';
import { FieldSettingsModel } from '@syncfusion/ej2-angular-dropdowns';
import {
ColumnChooserService,
DataResult,
DataStateChangeEventArgs,
EditService,
EditSettingsModel,
ExcelExportService,
FailureEventArgs,
FilterService,
FilterSettings,
FreezeService,
GridComponent,
GridLine,
PageService,
PageSettingsModel,
PdfExportService,
ReorderService,
ResizeService,
RowDDService,
RowDropEventArgs,
SortService,
ToolbarService
} from '@syncfusion/ej2-angular-grids';
import { MenuEventArgs } from '@syncfusion/ej2-angular-splitbuttons';
import { DataManager, Query, RemoteSaveAdaptor } from '@syncfusion/ej2-data';
import { catchError, finalize, Observable, retry, Subject, takeUntil, tap } from 'rxjs';
@Component({
selector: 'am-process-tab-item',
templateUrl: './process-tab-item.component.html',
styleUrls: ['./process-tab-item.component.scss'],
providers: [
PageService,
EditService,
ToolbarService,
ColumnChooserService,
FilterService,
FreezeService,
ReorderService,
ResizeService,
SortService,
RowDDService,
PdfExportService,
ExcelExportService,
],
})
export class ProcessTabItemComponent implements OnInit, AfterViewInit, OnDestroy {
@Input() public fetchActive = true;
@ViewChild('grid') grid: GridComponent | undefined;
public clientData: DataResult | undefined;
public showLoader = true;
public pageSettings: PageSettingsModel;
public editSettings: EditSettingsModel;
public toolbar: (string | object)[];
public currentDescriptionFormArray: FormArray | undefined;
public descriptionDialogVisible = false;
public wcmPillars$: Observable<WcmPillarDropdownItem[]> | undefined;
public selectedWcmPillarIds: number[][] = [];
public wcmPillarFields: FieldSettingsModel;
public strategicalAxises$: Observable<StrategicalAxisDropdownItem[]> | undefined;
public selectedStrategicalAxisIds: number[][] = [];
public strategicalAxisFields: FieldSettingsModel;
public freezingOptions: { text: string; field: string }[];
public filterTypeItems = [
{ text: 'FilterBar', iconCss: 'e-icons e-bullet-5' },
{ text: 'Menu', iconCss: 'e-icons e-bullet-5' },
{ text: 'CheckBox', iconCss: 'e-icons e-bullet-5' },
{ text: 'Excel', iconCss: 'e-icons e-bullet-5' },
];
public gridLineItems = [
{ text: 'None', iconCss: 'e-icons e-bullet-5' },
{ text: 'Default', iconCss: 'e-icons e-bullet-5' },
{ text: 'Both', iconCss: 'e-icons e-bullet-5' },
{ text: 'Horizontal', iconCss: 'e-icons e-bullet-5' },
{ text: 'Vertical', iconCss: 'e-icons e-bullet-5' },
];
public filterSettings: Partial<FilterSettings>;
public allowRowDragAndDrop = true;
public currentLanguage: string | undefined;
private _baseUrl: string | undefined;
private _accessToken: string | undefined;
private userSettingsKey: string | undefined;
private destroy$ = new Subject<void>();
constructor(
private readonly processesGridService: ProcessesGridService,
private readonly wcmPillarsService: WcmPillarsService,
private readonly strategicalAxisesService: StrategicalAxisesService,
private readonly toolbarConfigService: ToolbarConfigService,
private readonly gridService: GridService,
private readonly translationService: TranslationService,
@Inject(APP_CONFIG) private readonly appConfig: CoreConfig,
private readonly snackBarService: SnackBarService,
private readonly translateService: TranslateService,
private readonly authService: AuthenticationService
) {
this._baseUrl = `${this.appConfig.api}masterdata/lists/processes/grid`;
const authValue = JSON.parse(
sessionStorage.getItem('oidc.user:https://sts.belgium.arcelormittal.com/TokenService:PROMATO')
);
this._accessToken = authValue.access_token;
}
public get selectedFrozenColumns() {
return this.gridService.selectedFrozenColumns;
}
public get lines() {
return this.gridService.lines;
}
public ngOnInit(): void {
this.authService.userProfile$
.pipe(
tap((userProfile) => {
this.userSettingsKey = `${userProfile.sid}processes-gridState-${
this.fetchActive ? 'active' : 'inactive'
}`;
}),
takeUntil(this.destroy$)
)
.subscribe();
this.currentLanguage = this.translationService.getCurrentLanguage();
this.fetchData();
this.pageSettings = { pageSize: 20 };
this.editSettings = {
allowEditing: true,
allowAdding: true,
allowDeleting: true,
mode: 'Normal',
newRowPosition: 'Bottom',
};
this.setupWcmPillars();
this.setupStrategicalAxises();
this.configureToolbar();
}
public ngAfterViewInit(): void {
this.configureToolbar();
this.gridService.loadGridState(this.userSettingsKey, this.grid);
}
public ngOnDestroy(): void {
this.destroy$.next();
this.destroy$.complete();
}
public dataBound() {
this.configureFreezingOptions();
}
public dataStateChange(state: DataStateChangeEventArgs) {
const query = this.grid.getDataModule().generateQuery().requiresCount();
if (state.action) {
this.grid.dataSource = new DataManager(this.clientData.result).executeLocal(query);
if (state.dataSource) {
state.dataSource(this.clientData.result);
}
} else {
this.fetchDataFromService(query);
}
}
public actionBegin(args: any) {
const requestType = args.requestType;
if (requestType === 'beginEdit') {
this.setCurrentWcmPillarValues(args.rowData);
this.setCurrentStrategicalAxises(args.rowData);
}
if (requestType === 'save') {
args.data.wcmPillars = this.selectedWcmPillarIds;
args.data.strategicalAxises = this.selectedStrategicalAxisIds;
}
if (requestType === 'add') {
args.data.isActive = true;
args.data.order = ++(this.grid.getPreviousRowData() as any).order;
}
if (requestType === 'sorting') {
this.allowRowDragAndDrop =
!args.columnName || (args.columnName === 'order' && args.direction === 'Ascending');
}
}
public rowDrop(args: RowDropEventArgs) {
const data = args.data[0] as any;
const pageSize = this.grid.pageSettings.pageSize;
const currentPage = this.grid.pageSettings.currentPage;
const newIndex = args.dropIndex + pageSize * (currentPage - 1) + 1;
const oldIndex = args.fromIndex + pageSize * (currentPage - 1) + 1;
this.processesGridService
.saveNewOrder$({ id: data.id, newIndex, oldIndex })
.pipe(
finalize(() => this.fetchData()),
takeUntil(this.destroy$)
)
.subscribe();
}
public filterChangeHandler(args: MenuEventArgs) {
this.gridService.handleFilterChange(args, this.grid);
setTimeout(() => {
this.saveGridState();
}, 0);
}
public gridLinesChangeHandler(args: MenuEventArgs) {
const type = args.item.text;
this.gridService.lines = type as GridLine;
this.saveGridState();
setTimeout(() => {
this.grid.refresh();
}, 0);
}
public handleFreezeChange(args: any, fieldColumn: string) {
this.gridService.selectedFrozenColumns = this.gridService.handleFreezeChange(
args,
fieldColumn,
this.grid
);
this.saveGridState();
}
public pdfExport() {
this.grid.pdfExport();
}
public excelExport() {
this.grid.excelExport();
}
public addNewRecord() {
this.grid.addRecord();
}
public handleClearFiltering() {
this.gridService.handleClearFiltering(this.grid);
}
public fetchData() {
const state = { skip: 0, take: 20 };
const query = new Query().skip(state.skip).take(state.take).requiresCount();
this.fetchDataFromService(query);
}
public searchList(searchTerm: string) {
const state = { skip: 0, take: 20 };
const query = new Query().skip(state.skip).take(state.take).requiresCount();
this.fetchDataFromService(query, searchTerm);
}
public onActionFailure(args: FailureEventArgs) {
this.showLoader = false;
this.snackBarService.open(
{
message: this.translateService.instant('Processes.ErrorMessages.Save'),
},
SnackBarType.ERROR
);
}
public saveGridState() {
this.gridService.saveGridState(this.userSettingsKey, this.grid);
}
private fetchDataFromService(query: Query, searchTerm = '') {
this.processesGridService
.getAllData$(query, this.fetchActive, searchTerm)
.pipe(
tap((response: DataResult | Response) => {
this.showLoader = false;
this.clientData = response as DataResult;
this.grid.dataSource = new DataManager({
json: this.clientData.result,
updateUrl: `${this._baseUrl}/update`,
insertUrl: `${this._baseUrl}/create`,
adaptor: new RemoteSaveAdaptor(),
headers: [
{
Authorization: `Bearer ${this._accessToken}`,
},
],
});
}),
catchError((err) => {
this.showLoader = false;
this.snackBarService.open(
{
message: this.translateService.instant('Processes.ErrorMessages.Fetch'),
},
SnackBarType.ERROR
);
return err;
}),
retry(3),
takeUntil(this.destroy$)
)
.subscribe();
}
private setCurrentWcmPillarValues(data: any) {
this.selectedWcmPillarIds[data.id] = data.wcmPillars.map((x) => x.id);
}
private setupWcmPillars() {
this.wcmPillars$ = this.wcmPillarsService.GetDropdownItems();
this.wcmPillarFields = { value: 'id', text: 'name' };
}
private setCurrentStrategicalAxises(data: any) {
this.selectedStrategicalAxisIds[data.id] = data.strategicalAxises.map((x) => x.id);
}
private setupStrategicalAxises() {
this.strategicalAxises$ = this.strategicalAxisesService.getDropdownItems();
this.strategicalAxisFields = { value: 'id', text: 'name' };
}
private configureFreezingOptions() {
if (this.grid) {
this.freezingOptions = this.grid
?.getVisibleColumns()
.map((column) => ({ text: column.headerText, field: column.field }))
.filter((x) => !!x.field && !!x.text)
.sort((a, b) => a.text?.localeCompare(b.text));
}
}
private configureToolbar() {
this.toolbar = this.toolbarConfigService.getConfig();
}
}