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 13 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
1 change: 1 addition & 0 deletions .github/workflows/unit-test_frontend.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ on:
paths:
- 'frontend/**'
pull_request:
workflow_dispatch:

jobs:
build:
Expand Down
43 changes: 43 additions & 0 deletions frontend/src/app/modules/core/user/table-settings.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,16 @@

import { Injectable } from '@angular/core';
import { TableType } from '@shared/components/multi-select-autocomplete/table-type.model';
import { NotificationsReceivedConfigurationModel } from '@shared/components/parts-table/notifications-received-configuration.model';
import { NotificationsSentConfigurationModel } from '@shared/components/parts-table/notifications-sent-configuration.model';
import { PartsAsBuiltConfigurationModel } from '@shared/components/parts-table/parts-as-built-configuration.model';
import { PartsAsBuiltCustomerConfigurationModel } from '@shared/components/parts-table/parts-as-built-customer-configuration.model';
import { PartsAsBuiltSupplierConfigurationModel } from '@shared/components/parts-table/parts-as-built-supplier-configuration.model';
import { PartsAsPlannedConfigurationModel } from '@shared/components/parts-table/parts-as-planned-configuration.model';
import { PartsAsPlannedCustomerConfigurationModel } from '@shared/components/parts-table/parts-as-planned-customer-configuration.model';
import { PartsAsPlannedSupplierConfigurationModel } from '@shared/components/parts-table/parts-as-planned-supplier-configuration.model';
import { TableViewConfig } from '@shared/components/parts-table/table-view-config.model';
import { ToastService } from '@shared/components/toasts/toast.service';
import { Subject } from 'rxjs';

@Injectable({
Expand All @@ -29,6 +38,9 @@ export class TableSettingsService {
private settingsKey = 'TableViewSettings';
private changeEvent = new Subject<void>();

constructor(private readonly toastService: ToastService) {
}

storeTableSettings(tableSettingsList: any): void {
// before setting anything, all maps in new tableSettingList should be stringified
Object.keys(tableSettingsList).forEach(tableSetting => {
Expand Down Expand Up @@ -80,6 +92,7 @@ export class TableSettingsService {
}
}
if (isInvalid) {
this.toastService.warning('table.tableSettings.invalid', 10000);
localStorage.removeItem(this.settingsKey);
}
return isInvalid;
Expand All @@ -92,4 +105,34 @@ export class TableSettingsService {
getEvent() {
return this.changeEvent.asObservable();
}

initializeTableViewSettings(tableType: TableType): TableViewConfig {
switch (tableType) {
case TableType.AS_PLANNED_CUSTOMER:
return new PartsAsPlannedCustomerConfigurationModel().filterConfiguration();
break;
case TableType.AS_PLANNED_OWN:
return new PartsAsPlannedConfigurationModel().filterConfiguration();
break;
case TableType.AS_PLANNED_SUPPLIER:
return new PartsAsPlannedSupplierConfigurationModel().filterConfiguration();
break;
case TableType.AS_BUILT_OWN:
return new PartsAsBuiltConfigurationModel().filterConfiguration();
break;
case TableType.AS_BUILT_CUSTOMER:
return new PartsAsBuiltCustomerConfigurationModel().filterConfiguration();
break;
case TableType.AS_BUILT_SUPPLIER:
return new PartsAsBuiltSupplierConfigurationModel().filterConfiguration();
break;
case TableType.SENT_NOTIFICATION:
return new NotificationsSentConfigurationModel().filterConfiguration();
break;
case TableType.RECEIVED_NOTIFICATION:
return new NotificationsReceivedConfigurationModel().filterConfiguration();
break;
}
}

}
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 @@ -66,4 +66,5 @@ export class PartsTableConfigUtils {
return [ first, ...filterColumnsMapping, last ].filter(value => value !== null);

}

}
Original file line number Diff line number Diff line change
Expand Up @@ -41,12 +41,6 @@ import { TableSettingsService } from '@core/user/table-settings.service';
import { MainAspectType } from '@page/parts/model/mainAspectType.enum';
import { MultiSelectAutocompleteComponent } from '@shared/components/multi-select-autocomplete/multi-select-autocomplete.component';
import { TableType } from '@shared/components/multi-select-autocomplete/table-type.model';
import { PartsAsBuiltConfigurationModel } from '@shared/components/parts-table/parts-as-built-configuration.model';
import { PartsAsBuiltCustomerConfigurationModel } from '@shared/components/parts-table/parts-as-built-customer-configuration.model';
import { PartsAsBuiltSupplierConfigurationModel } from '@shared/components/parts-table/parts-as-built-supplier-configuration.model';
import { PartsAsPlannedConfigurationModel } from '@shared/components/parts-table/parts-as-planned-configuration.model';
import { PartsAsPlannedCustomerConfigurationModel } from '@shared/components/parts-table/parts-as-planned-customer-configuration.model';
import { PartsAsPlannedSupplierConfigurationModel } from '@shared/components/parts-table/parts-as-planned-supplier-configuration.model';
import { TableViewConfig } from '@shared/components/parts-table/table-view-config.model';
import { TableSettingsComponent } from '@shared/components/table-settings/table-settings.component';
import {
Expand Down Expand Up @@ -176,34 +170,11 @@ export class PartsTableComponent implements OnInit {
return isDateFilter(key);
}

private initializeTableViewSettings(): void {
switch (this.tableType) {
case TableType.AS_PLANNED_CUSTOMER:
this.tableViewConfig = new PartsAsPlannedCustomerConfigurationModel().filterConfiguration();
break;
case TableType.AS_PLANNED_OWN:
this.tableViewConfig = new PartsAsPlannedConfigurationModel().filterConfiguration();
break;
case TableType.AS_PLANNED_SUPPLIER:
this.tableViewConfig = new PartsAsPlannedSupplierConfigurationModel().filterConfiguration();
break;
case TableType.AS_BUILT_OWN:
this.tableViewConfig = new PartsAsBuiltConfigurationModel().filterConfiguration();
break;
case TableType.AS_BUILT_CUSTOMER:
this.tableViewConfig = new PartsAsBuiltCustomerConfigurationModel().filterConfiguration();
break;
case TableType.AS_BUILT_SUPPLIER:
this.tableViewConfig = new PartsAsBuiltSupplierConfigurationModel().filterConfiguration();
break;
}
}

private pageSize: number;
private sorting: TableHeaderSort;

ngOnInit() {
this.initializeTableViewSettings();
this.tableViewConfig = this.tableSettingsService.initializeTableViewSettings(this.tableType);
this.tableSettingsService.getEvent().subscribe(() => {
this.setupTableViewSettings();
});
Expand All @@ -216,9 +187,6 @@ export class PartsTableComponent implements OnInit {

private setupTableViewSettings() {

if (this.tableSettingsService.storedTableSettingsInvalid(this.tableViewConfig, this.tableType)) {
this.toastService.warning('table.tableSettings.invalid', 10000);
}
const tableSettingsList = this.tableSettingsService.getStoredTableSettings();
// check if there are table settings list
if (tableSettingsList) {
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
Loading