Untitled
unknown
plain_text
3 months ago
15 kB
6
Indexable
import { ProfileService } from './services';
import {
Component,
OnInit,
inject,
ViewChild,
HostListener,
} from '@angular/core';
import { Observable } from 'rxjs/internal/Observable';
import { Profile } from './models/profile';
import { DxDataGridComponent } from 'devextreme-angular';
import { BehaviorSubject, switchMap, lastValueFrom } from 'rxjs';
import { cloneDeep } from 'lodash';
import { Customer, CustomerService } from '../customer';
import dxDataGrid, { Column, ContentReadyEvent } from 'devextreme/ui/data_grid';
interface ButtonDataViewModel {
name: string;
icon: string;
template: string;
type: string;
class: string;
event: string;
disabled: boolean;
}
interface DetailViewModel {
title: string;
visible: boolean;
profile?: Profile;
isEditMode: boolean;
}
interface DeleteViewModel {
visible: boolean;
profileIds: number[];
}
@Component({
selector: 'app-profile',
templateUrl: './profile.component.html',
styleUrls: ['./profile.component.scss'],
standalone: false
})
export class ProfileComponent implements OnInit {
public searchPlaceholder: string;
public buttonsData: ButtonDataViewModel[];
public profiles$: Observable<Profile[]>;
public customers: Customer[];
public detailDialog$: Observable<DetailViewModel>;
public deleteDialog$: Observable<DeleteViewModel>;
public regexDetails$: Observable<boolean>;
public selectedProfiles$: Observable<Profile[]>;
public profileNames: string[];
public uncNetworkPaths: string[];
@ViewChild('gridComponent')
private readonly _gridComponent: DxDataGridComponent;
private readonly _detailDialogSubject: BehaviorSubject<DetailViewModel> =
new BehaviorSubject<DetailViewModel>(null);
private readonly _deleteDialogSubject: BehaviorSubject<DeleteViewModel> =
new BehaviorSubject<DeleteViewModel>(null);
private readonly _regexDetailsSubject: BehaviorSubject<boolean> =
new BehaviorSubject<boolean>(false);
private readonly _refreshDataSubject = new BehaviorSubject<void>(undefined);
private readonly _selectedProfilesSubject = new BehaviorSubject<Profile[]>(
[],
);
private _profileService: ProfileService = inject(ProfileService);
private _customerService: CustomerService = inject(CustomerService);
@HostListener('window:resize')
public onResize(): void {
const gridInstance = this._gridComponent.instance as any;
const columnChooserElementRef = document.querySelector(
'.dx-datagrid-column-chooser',
);
if (gridInstance == undefined || columnChooserElementRef == undefined) {
return;
}
gridInstance
.getView('columnChooserView')
._popupContainer.option('position', {
of: gridInstance.element(),
my: 'right bottom',
at: 'right bottom',
offset: '-2 -2',
});
}
public async ngOnInit(): Promise<void> {
this.searchPlaceholder = this._profileService.getSearchPlaceHolder();
this.buttonsData = this._profileService.getPriorityNavItems();
this.detailDialog$ = this._detailDialogSubject.asObservable();
this.deleteDialog$ = this._deleteDialogSubject.asObservable();
this.regexDetails$ = this._regexDetailsSubject.asObservable();
this.selectedProfiles$ = this._selectedProfilesSubject.asObservable();
this.profiles$ = this._refreshDataSubject.pipe(
switchMap(() => this._profileService.getAll()),
);
this.customers = await lastValueFrom(this._customerService.getAll());
this.fetchProfileData();
}
public onCloseDetailDialog(event: boolean): void {
this._detailDialogSubject.next(null);
this.refreshData(event);
}
public onCloseDeleteDialog(event: boolean): void {
this._deleteDialogSubject.next(null);
this.refreshData(event);
}
public onCloseRegexDetails(): void {
this._regexDetailsSubject.next(false);
}
public calculateCustomerCellValue = (rowData: Profile): string => {
const customer = this.customers.find(
(c) => c.id === rowData.customerId,
);
if (customer) {
return customer.name;
}
return '';
}
public onButtonClick(e: any): void {
if (e == undefined) {
return;
}
switch (e.detail) {
case 'ADD':
this._detailDialogSubject.next({
visible: true,
title: 'generalWords.add',
profile: new Profile(),
isEditMode: false,
});
break;
case 'EDIT':
this._gridComponent.instance.getSelectedRowsData().then((values) => {
this._detailDialogSubject.next({
visible: true,
title: 'generalWords.edit',
profile: cloneDeep(
values[0],
),
isEditMode: true,
});
})
break;
case 'DELETE':
this._gridComponent.instance.getSelectedRowKeys().then((values) => {
this._deleteDialogSubject.next({
visible: true,
profileIds:
values
});
})
this._gridComponent.instance.deselectAll();
this._gridComponent.instance.clearSelection();
break;
case 'COLUMN-CHOOSER':
this._gridComponent.instance.showColumnChooser();
break;
case 'REGEX':
this._regexDetailsSubject.next(
!this._regexDetailsSubject.value,
);
break;
}
}
public onSearch(e: any): void {
if (e == undefined) {
return;
}
this._gridComponent.instance.searchByText(e.detail.value);
this._gridComponent.instance.clearSelection();
}
public onSelectionChanged(e: any): void {
if (e == undefined) {
return;
}
const selectedDataCount = e.component.getSelectedRowKeys().then((values) => {
this.buttonsData[2].disabled = values.length !== 1;
this.buttonsData[3].disabled = values.length !== 1;
this.buttonsData[4].disabled = values.length === 0;
this.buttonsData = Object.assign([{}], this.buttonsData);
e.component.getSelectedRowsData().then((value) => { this._selectedProfilesSubject.next(value) });
if (this._regexDetailsSubject.value && selectedDataCount !== 1) {
this._regexDetailsSubject.next(false);
}
});
}
public onRowClick(e: any): void {
if (e == undefined) {
return;
}
this._gridComponent.instance.selectRows(e.key, e.event.ctrlKey);
}
public onRowDblClick(e: any): void {
if (e == undefined) {
return;
}
this._detailDialogSubject.next({
visible: true,
title: 'generalWords.edit',
profile: cloneDeep(e.data),
isEditMode: true,
});
}
// Dynamically set minWidth of columns to fit header text
public onContentReady(e: ContentReadyEvent): void {
const grid: dxDataGrid = e.component;
grid.getVisibleColumns().forEach((col: Column) => {
const headerText = col.caption || col.dataField;
const span = document.createElement('span');
span.innerText = headerText;
document.body.appendChild(span);
const width = span.offsetWidth + 32;
document.body.removeChild(span);
grid.columnOption(col.dataField, 'minWidth', width);
});
}
public onCustomLoad(): unknown {
return JSON.parse(localStorage.getItem('profilesGrid'));
}
public onCustomSave(state: any): void {
if (state == undefined) {
return;
}
state.searchText = null;
state.selectedRowKeys = [];
localStorage.setItem('profilesGrid', JSON.stringify(state));
}
private fetchProfileData(): void {
this._profileService
.getAll()
.subscribe((returnedProfiles: Profile[]) => {
this.profileNames = returnedProfiles.map(
(profile) => profile.name,
);
this.uncNetworkPaths = returnedProfiles.map(
(profile) => profile.uncNetworkPath,
);
});
}
private refreshData(refresh: boolean): void {
if (!refresh) {
return;
}
this.fetchProfileData();
this._refreshDataSubject.next();
}
@HostListener('window:beforeunload', ['$event'])
public onBeforeUnload(event: Event): void {
if (this._gridComponent && this._gridComponent.instance) {
this._gridComponent.instance.deselectAll();
}
}
}
-----------------------------------------------------------------------------------------
<div class="profile__actions-bar">
<buttons-app
[buttonsData]="buttonsData"
(buttonEventEmitter)="onButtonClick($event)"
(searchBarEventEmitter)="onSearch($event)"
[searchBoxItems]="[{name: searchPlaceholder, icon: 'fas fa-search'}]">
</buttons-app>
</div>
<app-profile-detail
*ngIf="detailDialog$ | async as detailDialog"
[title]="detailDialog.title"
[visible]="detailDialog.visible"
[profile]="detailDialog.profile"
[isEditMode]="detailDialog.isEditMode"
[profileNames]="profileNames"
[uncNetworkPaths]="uncNetworkPaths"
(closeDialog)="onCloseDetailDialog($event)">
</app-profile-detail>
<app-profile-delete
*ngIf="deleteDialog$ | async as deleteDialog"
title="generalWords.delete"
[visible]="deleteDialog.visible"
[profileIds]="deleteDialog.profileIds"
(closeDialog)="onCloseDeleteDialog($event)">
</app-profile-delete>
<ng-container *ngIf="profiles$ | async as profiles">
<div class="profiles__container">
<dx-data-grid
#gridComponent
class="profiles_grid"
keyExpr="id"
[dataSource]="profiles"
[showRowLines]="true"
[allowColumnResizing]="true"
[allowColumnReordering]="true"
[scrolling]="{ mode: 'virtual' }"
[selection]="{ mode: 'multiple', deferred: true }"
(onRowClick)="onRowClick($event)"
(onSelectionChanged)="onSelectionChanged($event)"
(onRowDblClick)="onRowDblClick($event)"
(onContentReady)="onContentReady($event)">
<dxo-header-filter [visible]="true"></dxo-header-filter>
<dxo-filter-row [visible]="true"></dxo-filter-row>
<dxo-sorting
[ascendingText]="'devextreme.sortAscending' | translate"
[descendingText]="'devextreme.sortDescending' | translate"
[clearText]="'devextreme.clearSorting' | translate">
</dxo-sorting>
<dxo-toolbar [visible]="false"></dxo-toolbar>
<dxo-scrolling mode="infinite"></dxo-scrolling>
<dxo-selection
mode="multiple"
showCheckBoxesMode="always">
</dxo-selection>
<dxo-column-chooser
mode="select"
[enabled]="true"
[title]="'devextreme.columnChooser' | translate">
<dxo-search [enabled]="true"></dxo-search>
</dxo-column-chooser>
<dxo-state-storing
type="custom"
[enabled]="true"
[customLoad]="onCustomLoad"
[customSave]="onCustomSave">
</dxo-state-storing>
<dxi-column
dataField="name"
dataType="string"
sortOrder="asc"
[caption]="'properties.profile.name' | translate">
</dxi-column>
<dxi-column
dataField="email"
dataType="string"
[caption]="'properties.customer.email' | translate">
</dxi-column>
<dxi-column
dataField="viewerUrl"
dataType="string"
[caption]="'properties.customer.viewerUrl' | translate">
</dxi-column>
<dxi-column
dataField="stabibaseDb"
dataType="string"
[caption]="'properties.customer.stabibaseDb' | translate">
</dxi-column>
<dxi-column
dataField="asBuiltDb"
dataType="string"
[caption]="'properties.customer.asBuiltDb' | translate">
</dxi-column>
<dxi-column
dataField="uncNetworkPath"
dataType="string"
[caption]="'properties.profile.uncNetworkPath' | translate">
</dxi-column>
<dxi-column
dataField="uploadService"
dataType="string"
[caption]="'properties.profile.uploadService' | translate">
</dxi-column>
<dxi-column
dataField="projectLeader"
dataType="string"
[caption]="'properties.profile.projectLeader' | translate">
</dxi-column>
<dxi-column
dataField="description"
dataType="string"
[caption]="'properties.profile.description' | translate">
</dxi-column>
<dxi-column
*ngIf="customers"
[allowSorting]="true"
[allowFiltering]="true"
[calculateCellValue]="calculateCustomerCellValue"
dataType="string"
[caption]="'properties.profile.customerId' | translate">
</dxi-column>
</dx-data-grid>
<app-regex
[visible]="regexDetails$ | async"
[selectedProfiles$]="selectedProfiles$"
(closeDialog)="onCloseRegexDetails()">
</app-regex>
</div>
</ng-container> Editor is loading...
Leave a Comment