Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/617 2 redesign of inbox table #1197

Closed
wants to merge 20 commits into from
Closed
Show file tree
Hide file tree
Changes from 9 commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
2ff0242
feature(inbox): 617 add table settings to inbox table
ds-mmaul Apr 17, 2024
5ba1539
feature(inbox): 617 redesign of inbox table
ds-mmaul Apr 18, 2024
b76a7ea
Merge branch 'refs/heads/main' into feature/617-2-redesign-of-inbox-t…
ds-mmaul Apr 19, 2024
13f1557
Merge branch 'refs/heads/main' into feature/617-2-redesign-of-inbox-t…
ds-mmaul Apr 19, 2024
1455f90
feature(inbox): 617 add menu actions logic
ds-mmaul Apr 19, 2024
163ff8b
feature(inbox): 617 add edit menu to multi select actions
ds-mmaul Apr 19, 2024
49b3c62
feature(inbox): 617 bugfix part table in notfication-detail-view
ds-mmaul Apr 19, 2024
4320795
feature(inbox): 617 fix table header layout
ds-mmaul Apr 19, 2024
d7d6014
feature(inbox): 617 fix tests
ds-mmaul Apr 19, 2024
066a958
Merge branch 'refs/heads/main' into feature/617-2-redesign-of-inbox-t…
ds-mmaul Apr 22, 2024
7f47e1b
feature(inbox): 617 reduce duplication
ds-mmaul Apr 22, 2024
608fd0f
Merge branch 'refs/heads/main' into feature/617-2-redesign-of-inbox-t…
ds-mwesener Apr 22, 2024
75f7dc1
chore(dependencies): XXX Updated
ds-mwesener Apr 22, 2024
c9069f4
feature(inbox): 617 reduce duplication
ds-mmaul Apr 22, 2024
9bd61f7
Merge remote-tracking branch 'origin/feature/617-2-redesign-of-inbox-…
ds-mmaul Apr 22, 2024
7273169
feature(inbox): 617 reduce duplication
ds-mmaul Apr 22, 2024
f2edcd0
Merge branch 'main' into feature/617-2-redesign-of-inbox-table
ds-mmaul Apr 22, 2024
cfc6fd7
feature(inbox): 617 added tests
ds-mmaul Apr 23, 2024
c12a297
feature(inbox): 617 added tests
ds-mmaul Apr 23, 2024
8534e1f
feature(inbox): 617 added user manual documentation
ds-mmaul Apr 23, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -116,10 +116,12 @@ <h3 class="flex items-center">
<app-notifications-tab
[notificationsView$]="alertsCreated$"
[translationContext]="'commonAlert'"
[tableHeader]="'pageTitle.sentQualityTopics'"
[tableType]="TableType.RECEIVED_NOTIFICATION"
[labelId]="'dashboard-alerts-created'"
[hasPagination]="false"
[optionalColumns]="['targetDate', 'severity', 'createdBy', 'type']"
[tableSettingsEnabled]="false"
(selected)="onAlertSelected($event)"
></app-notifications-tab>
</mat-card-content>
Expand Down Expand Up @@ -155,6 +157,7 @@ <h3 class="flex items-center">
<mat-card-content>
<app-notifications-tab
[notificationsView$]="alertsReceived$"
[tableHeader]="'pageTitle.receivedQualityTopics'"
[translationContext]="'commonAlert'"
[labelId]="'dashboard-alerts-received'"
[hasPagination]="false"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ export class NotificationEditComponent implements OnDestroy {
const newNotification: Notification = {
assetIds: this.sharedPartService?.affectedParts?.map(value => value.id) || [],
createdBy: '',
type: this.route.snapshot.queryParams['initialType'],
type: this.route.snapshot.queryParams['initialType'] ?? null,
createdByName: '',
createdDate: undefined,
description: '',
Expand All @@ -158,6 +158,13 @@ export class NotificationEditComponent implements OnDestroy {
}

public notificationFormGroupChange(notificationFormGroup: FormGroup) {
// if user switches type of notification in creation mode, reset affected parts and reload new available parts
if (this.selectedNotification.type !== notificationFormGroup.value['type']) {
this.selectedNotification.type = notificationFormGroup.value['type'];
// TODO: comment back in if todos inside the function were handled
// this.switchSelectedNotificationTypeAndResetParts();
}

this.notificationFormGroup = notificationFormGroup;
this.isSaveButtonDisabled = (notificationFormGroup.invalid || this.affectedPartIds.length < 1) || !this.notificationFormGroup.dirty;
if (this.notificationFormGroup && this.notificationFormGroup.get('type').value === NotificationType.INVESTIGATION.valueOf() && !this.notificationFormGroup.get('bpn').value && this.sharedPartService.affectedParts && this.sharedPartService.affectedParts.length > 0) {
Expand Down Expand Up @@ -340,6 +347,17 @@ export class NotificationEditComponent implements OnDestroy {
};
}

private switchSelectedNotificationTypeAndResetParts() {
this.selectedNotification.assetIds = [];
this.affectedPartIds = [];
// TODO: to switch notifications we need to build a proper request to make them empty
//this.affectedPartsAsBuilt$ = this.partsFacade ...
// TODO: comment back in if the upper todo was handled
//this.availablePartsAsBuilt$ = this.selectedNotification.type === NotificationType.INVESTIGATION ? this.partsFacade.supplierPartsAsBuilt$ : this.ownPartsFacade.partsAsBuilt$;
this.setAffectedPartsBasedOnNotificationType(this.selectedNotification);
this.setAvailablePartsBasedOnNotificationType(this.selectedNotification);
}

protected readonly TableType = TableType;
protected readonly MainAspectType = MainAspectType;
}
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
>
<app-button
*ngIf="actionHelperService.showEditButton(selectedNotification)"
(click)="navigateToDetailView()"
(click)="navigateToEditView()"
[color]="'primary'"
[isDisabled]="!actionHelperService.isAuthorizedForButton(NotificationAction.APPROVE)"
>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,8 @@ export class NotificationDetailComponent implements AfterViewInit, OnDestroy {

@ViewChild('semanticModelIdTmp') semanticModelIdTmp: TemplateRef<unknown>;

public readonly notificationPartsInformation$: Observable<View<Part[]>>;
public readonly supplierPartsDetailInformation$: Observable<View<Part[]>>;
public notificationPartsInformation$: Observable<View<Part[]>>;
public supplierPartsDetailInformation$: Observable<View<Part[]>>;
public readonly selected$: Observable<View<Notification>>;

public readonly selectedItems$ = new BehaviorSubject<Part[]>([]);
Expand Down Expand Up @@ -113,7 +113,7 @@ export class NotificationDetailComponent implements AfterViewInit, OnDestroy {
this.paramSubscription?.unsubscribe();
}

public navigateToDetailView(){
public navigateToEditView() {

this.router.navigate([ `/inbox/${ this.selectedNotification.id }/edit` ], {
queryParams: {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { TableFilterConfiguration } from '@shared/components/parts-table/parts-config.model';

export class NotificationsReceivedConfigurationModel extends TableFilterConfiguration {
constructor() {
const sortableColumns = {
select: false,
createdBy: true,
createdByName: true,
createdDate: true,
description: true,
severity: true,
status: true,
title: true,
type: true,
menu: false,
};

const dateFields = [ 'createdDate' ];
const singleSearchFields = [];
super(sortableColumns, dateFields, singleSearchFields, true);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { TableFilterConfiguration } from '@shared/components/parts-table/parts-config.model';

export class NotificationsSentConfigurationModel extends TableFilterConfiguration {
constructor() {
const sortableColumns = {
select: false,
description: true,
title: true,
status: true,
createdDate: true,
severity: true,
sendTo: true,
sendToName: true,
type: true,
menu: false,
};

const dateFields = [ 'createdDate' ];
const singleSearchFields = [];
super(sortableColumns, dateFields, singleSearchFields, true);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,8 @@
********************************************************************************/


import { TableViewConfig } from '@shared/components/parts-table/table-view-config.model';


import { PartsTableConfigUtils } from '@shared/components/parts-table/parts-table-config.utils';
import { TableViewConfig } from '@shared/components/parts-table/table-view-config.model';


export class TableFilterConfiguration implements TableViewConfig {
Expand All @@ -31,12 +29,12 @@ export class TableFilterConfiguration implements TableViewConfig {
filterFormGroup: any;
sortableColumns: any;

constructor(sortableColumns: any, dateFields?: any, singleSearchFields?: any) {
constructor(sortableColumns: any, dateFields?: any, singleSearchFields?: any, hasFilterColumn?: boolean) {
this.displayedColumns = Object.keys(sortableColumns);
this.filterFormGroup = PartsTableConfigUtils.createFormGroup(this.displayedColumns);
this.filterColumns = PartsTableConfigUtils.createFilterColumns(this.displayedColumns);
this.filterColumns = PartsTableConfigUtils.createFilterColumns(this.displayedColumns, hasFilterColumn);
this.sortableColumns = sortableColumns;
this.displayFilterColumnMappings = PartsTableConfigUtils.generateFilterColumnsMapping(sortableColumns, dateFields, singleSearchFields);
this.displayFilterColumnMappings = PartsTableConfigUtils.generateFilterColumnsMapping(sortableColumns, dateFields, singleSearchFields, hasFilterColumn);

}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,9 +72,16 @@ export class RequestNotificationNewComponent implements OnDestroy, OnInit {

this.formGroupChanged.emit(this.formGroup);

} else {
// when clicking new notification without part context enable switching
if (!this.notification.type) {
this.formGroup.get('type').setValue(NotificationType.INVESTIGATION);
this.formGroup.get('type').enable();
} else {
this.formGroup.get('type').setValue(this.notification.type);
}
}

this.formGroup.get('type').setValue(this.notification.type);
if (this.notification.type === NotificationType.INVESTIGATION) {
this.formGroup.get('bpn').disable();
}
Expand All @@ -84,7 +91,7 @@ export class RequestNotificationNewComponent implements OnDestroy, OnInit {
}
this.formGroupChanged.emit(this.formGroup);

this.formGroup.valueChanges.subscribe(value => {
this.formGroup.valueChanges.subscribe(() => {
//TODO: For Create, check here or in parent if the part tables should update (depending on passed partId, investigation or alert type)
this.formGroupChanged.emit(this.formGroup);
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,6 @@ describe('TableSettingsComponent', () => {
expect(component.tableType).toEqual(TableType.AS_BUILT_OWN);
expect(component.defaultColumns).toEqual([ 'column1', 'column2' ]);
expect(component.defaultFilterColumns).toEqual([ 'filtercolumn1', 'filtercolumn2' ]);
expect(component.isCustomerTable).toEqual(false);
});

it('should call save method and update tableSettingsService', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,14 +47,10 @@ export class TableSettingsComponent {
selectAllSelected: boolean;
selectedColumn: string = null;

isCustomerTable: boolean;


constructor(public dialogRef: MatDialogRef<TableSettingsComponent>, @Inject(MAT_DIALOG_DATA) public data: any, public readonly tableSettingsService: TableSettingsService) {
// Layout
this.title = data.title;
this.panelClass = data.panelClass;
this.isCustomerTable = data.tableType === TableType.AS_BUILT_CUSTOMER || data.tableType === TableType.AS_PLANNED_CUSTOMER;
// Passed Data
this.tableType = data.tableType;
this.defaultColumns = data.defaultColumns;
Expand Down Expand Up @@ -125,11 +121,13 @@ export class TableSettingsComponent {
return;
}

let oldPosition = this.dialogColumns.indexOf(this.selectedColumn);
// in non customer table we have the select Column as first and why
let upperLimit = this.isCustomerTable ? 0 : 1;
const oldPosition = this.dialogColumns.indexOf(this.selectedColumn);
// for tables where we have a select column at first
const upperLimit = this.dialogColumns.includes('select') ? 1 : 0;
// for tables where we have a menu column at last
const bottomLimit = this.dialogColumns.includes('menu') ? this.dialogColumns.length - 2 : this.dialogColumns.length - 1;
let step = direction === 'up' ? -1 : 1;
if ((oldPosition == upperLimit && direction === 'up') || (oldPosition === this.dialogColumns.length - 1 && direction === 'down')) {
if ((oldPosition == upperLimit && direction === 'up') || (oldPosition === bottomLimit && direction === 'down')) {
return;
}
let temp = this.dialogColumns[oldPosition + step];
Expand Down
117 changes: 107 additions & 10 deletions frontend/src/app/modules/shared/components/table/table.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,106 @@

<div *ngIf="additionalTableHeader" class="table-header-wrapper">
<div class="table-header-container">
<div class="large-text table--header--text">{{tableHeader | i18n}}</div>
<div class="large-text table--header--text">{{ tableHeader | i18n }}
<mat-icon (click)="openDialog()" *ngIf="tableSettingsEnabled"
class="cursor-pointer table&#45;&#45;settings&#45;&#45;button ml-2">
settings
</mat-icon>
</div>
<div *ngIf="tableHeaderMenuEnabled" class="table-header--action--container flex mt-1">
<div class="mr-0.5"
matTooltip="{{ (roleService.isAdmin() ? 'routing.unauthorized':'table.createNotification') | i18n}}"
matTooltipClass="table--header--tooltip"
matTooltipPosition="above"
[class.mdc-tooltip--multiline]="true"
[matTooltipShowDelay]="500"
>
<app-button
[iconName]="'announcement'"
(click)="navigateToNavigationCreationView()"
[isDisabled]="roleService.isAdmin()"
></app-button>
</div>
<mat-divider class="mx-0.25" [vertical]="true"></mat-divider>
<div class="ml-0.5"
matTooltip="{{'table.more' | i18n}}"
matTooltipClass="table--header--tooltip"
matTooltipPosition="above"
[class.mdc-tooltip--multiline]="true"
[matTooltipShowDelay]="500"
>
<app-button
[iconName]="'more_horiz'"
[matMenuTriggerFor]="actionMenu"
>
</app-button>
</div>
<mat-menu #actionMenu="matMenu" xPosition="after" class="ml-10">
<div
matTooltip="{{(roleService.isAdmin() ? 'table.unauthorized':'table.selectAtLeastOne') | i18n}}"
matTooltipClass="table--header--tooltip"
matTooltipPosition="above"
[class.mdc-tooltip--multiline]="true"
[matTooltipShowDelay]="500"
[matTooltipDisabled]="selection.selected.length > 0 && !roleService.isAdmin()"
>
<button mat-menu-item
matTooltip="{{'table.onlyNotificationInStatusCreatedAllowed' | i18n}}"
matTooltipClass="table--header--tooltip"
matTooltipPosition="above"
[class.mdc-tooltip--multiline]="true"
[matTooltipDisabled]="notificationsSelectedOnlyInStatusCreated || selection.selected.length < 1"
[matTooltipShowDelay]="500"
[disabled]="selection.selected.length < 1 || roleService.isAdmin() || !notificationsSelectedOnlyInStatusCreated"
(click)="toastService.warning('table.noFunctionality')">
<mat-icon>send</mat-icon>
{{ 'table.sendNotification' | i18n }}
</button>
<button mat-menu-item
matTooltip="{{'table.onlyNotificationInStatusCreatedAllowed' | i18n}}"
matTooltipClass="table--header--tooltip"
matTooltipPosition="above"
[class.mdc-tooltip--multiline]="true"
[matTooltipShowDelay]="500"
[matTooltipDisabled]="notificationsSelectedOnlyInStatusCreated || selection.selected.length < 1"
[disabled]="selection.selected.length < 1 || roleService.isAdmin() || !notificationsSelectedOnlyInStatusCreated"
(click)="toastService.warning('table.noFunctionality')">
<mat-icon>cancel</mat-icon>
{{ 'table.cancelNotification' | i18n }}
</button>
<button mat-menu-item
matTooltip="{{'table.noFunctionality' | i18n}}"
matTooltipClass="table--header--tooltip"
matTooltipPosition="above"
[class.mdc-tooltip--multiline]="true"
[matTooltipShowDelay]="500"
[matTooltipDisabled]="selection.selected.length < 1"
[disabled]="true"
(click)="null">
<mat-icon>edit</mat-icon>
{{ 'table.editNotification' | i18n }}
</button>
<button mat-menu-item
matTooltip="{{'table.noFunctionality' | i18n}}"
matTooltipClass="table--header--tooltip"
matTooltipPosition="above"
[class.mdc-tooltip--multiline]="true"
[matTooltipShowDelay]="500"
[matTooltipDisabled]="selection.selected.length < 1"
[disabled]="true"
(click)="null">
<mat-icon>remove_red_eye</mat-icon>
{{ 'table.viewDetails' | i18n }}
</button>
</div>
</mat-menu>
</div>
</div>
</div>
<div [class.mat-elevation-z8]="!noShadow" class="table-wrapper" [ngClass]="labelId?.startsWith('dashboard') ? 'rows-dashboard' : ''">
<div [class.mat-elevation-z8]="!noShadow" class="table-wrapper"
[ngClass]="labelId?.startsWith('dashboard') ? 'rows-dashboard' : ''">
<ng-container *ngIf="tableHeader && !additionalTableHeader"><p
class="large-text table--header">{{tableHeader | i18n }}</p></ng-container>
class="large-text table--header">{{ tableHeader | i18n }}</p></ng-container>
<ng-container *ngIf="selectedPartsInfoLabel">
<div *appHasRole="tableConfig.columnRoles?.['select'] ?? 'user'" class="table--selected__container">
<p class="regular-text">{{ selectedPartsInfoLabel | i18n : {count: selection?.selected?.length || 0} }}</p>
Expand Down Expand Up @@ -57,8 +151,8 @@
>
<ng-container *ngIf="autocompleteEnabled">

<tr *matHeaderRowDef="tableViewConfig?.displayedColumns; sticky: true" mat-header-row
data-testid="table-component--head-row" class="table--header--row"></tr>
<tr *matHeaderRowDef="tableConfig.displayedColumns; sticky: true" mat-header-row
data-testid="table-component--head-row" class="table--header--row"></tr>

</ng-container>

Expand All @@ -67,7 +161,7 @@
data-testid="table-component--head-row" class="table--header--row"></tr>
</ng-container>
<ng-container *ngIf="autocompleteEnabled">
<tr class="filter-row" mat-header-row *matHeaderRowDef="tableViewConfig?.filterColumns; sticky: true"></tr>
<tr class="filter-row" mat-header-row *matHeaderRowDef="displayedColumns; sticky: true"></tr>
</ng-container>
<ng-container matColumnDef="{{ filter.headerKey }}"
*ngFor="let filter of tableViewConfig?.displayFilterColumnMappings">
Expand All @@ -82,7 +176,9 @@
[placeholderMultiple]="('multiSelect.multipleResults' | i18n)"
[tableType]="tableType"
ngDefaultControl
[formControl]="filterFormGroup.controls[filter.filterKey]"></app-multiselect>
[formControl]="filterFormGroup.controls[filter.filterKey]">

</app-multiselect>
</th>
</ng-container>

Expand Down Expand Up @@ -209,7 +305,8 @@ <h3>{{ 'table.noResultFound' | i18n }}</h3>

<ng-container matColumnDef="expandMenuActions" sticky>
<td mat-cell *matCellDef="let row" [attr.colspan]="tableConfig.displayedColumns.length">
<div [class.menuExpanded]="row === selectedRow" [class.collapsed]="row !== selectedRow" class="expand-element">
<div [class.menuExpanded]="row === selectedRow" [class.collapsed]="row !== selectedRow"
class="expand-element">
<ng-container *ngFor="let config of tableConfig.menuActionsConfig">
<button
*ngIf="!config.condition || config.condition(row)"
Expand Down Expand Up @@ -257,8 +354,8 @@ <h3>{{ 'table.noResultFound' | i18n }}</h3>

</th>
<td
*matCellDef="let element" mat-cell class="table--cell" data-testid="table-component--cell-data"
[ngClass]="{'max-width-column': labelId === 'contracts' && column === 'contractId' }">
*matCellDef="let element" mat-cell class="table--cell" data-testid="table-component--cell-data"
[ngClass]="{'max-width-column': labelId === 'contracts' && column === 'contractId' }">
<ng-container
[ngTemplateOutlet]="tableConfig?.cellRenderers?.[column] ? tableConfig?.cellRenderers?.[column] : autoFormat"
[ngTemplateOutletContext]="{ value: element[column], row: element }"
Expand Down
Loading