Skip to content

Commit

Permalink
Merge pull request #1207 from eclipse-tractusx/chore/#999-notificatio…
Browse files Browse the repository at this point in the history
…n-processing-feedback

Chore/#999 notification processing feedback
  • Loading branch information
ds-mwesener authored Jul 12, 2024
2 parents 1df86ad + 4f8de74 commit 252757c
Show file tree
Hide file tree
Showing 22 changed files with 198 additions and 59 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@ to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

_**For better traceability add the corresponding GitHub issue number in each changelog entry, please.**_
## [UNRELEASED - DD.MM.YYYY]

### Added

- #999 Added notification processing feedback in FE

### Changed
- #1173 Update IRS-Helm from 7.1.4 to 7.2.0 - updated Compatibility Matrix
- #1082 fix duplicate key errors when synchronizing assets with IRS
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,6 @@ const mockPolicyResponse: PolicyResponseMap = {
describe('PoliciesAssembler', () => {
it('should assemble policy', () => {
const assembledPolicy = PoliciesAssembler.assemblePolicy(mockPolicy2);
console.log(assembledPolicy.constraints);
expect(assembledPolicy.policyName).toBe(mockPolicy2.policyId);
expect(assembledPolicy.createdOn).toBe('2024-01-01T00:00');
expect(assembledPolicy.validUntil).toBe('2024-12-31T23:59');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,6 @@ export class PoliciesComponent {
this.selectedPoliciesInfoLabel = selectedPolicies.length === 1 ? 'pageAdmin.policyManagement.selectedPolicy' : 'pageAdmin.policyManagement.selectedPolicies';
this.selectedPolicies = selectedPolicies;
this.isDefaultSelected = this.selectedPolicies.filter(policy => policy?.policyId === 'default-policy').length > 0;
console.log(this.isDefaultSelected);
}

openDetailedView(selectedPolicy: Record<string, unknown>) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,6 @@ export class PolicyEditorComponent {
this.selectedPolicySubscription = this.policyFacade.selectedPolicy$.subscribe(next => {
this.selectedPolicy = next?.data;
if (next?.data) {
console.log(next.data);
this.updatePolicyForm(this.selectedPolicy);
}
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,19 +32,19 @@
</div>
<div class="detail--action">
<div class="detail--action--button"
matTooltip="{{'routing.unauthorized' | i18n}}"
matTooltip="{{ (isProcessing() ? 'routing.notificationInProcess': 'routing.unauthorized') | i18n}}"
matTooltipClass="table--header--tooltip"
matTooltipPosition="above"
[class.mdc-tooltip--multiline]="true"
[matTooltipShowDelay]="1000"
[matTooltipDisabled]="actionHelperService.isAuthorizedForButton(NotificationAction.APPROVE)"
[matTooltipDisabled]="actionHelperService.isAuthorizedForButton(NotificationAction.APPROVE) && !isProcessing()"
>
<app-button
*ngIf="actionHelperService.showEditButton(selectedNotification)"
onkeydown="navigateToEditView()"
(click)="navigateToEditView()"
[color]="'primary'"
[isDisabled]="!actionHelperService.isAllowedToEdit()"
[isDisabled]="!actionHelperService.isAllowedToEdit() || isProcessing()"
>
<div class="flex justify-between items-center">
<mat-icon class="mr-2" [attr.data-testid]="'edit-button-icon'">edit</mat-icon>
Expand All @@ -57,7 +57,7 @@
onkeydown="notificationCommonModalComponent?.show(NotificationStatus.APPROVED)"
(click)="notificationCommonModalComponent?.show(NotificationStatus.APPROVED)"
[color]="'primary'"
[isDisabled]="!actionHelperService.isAuthorizedForButton(NotificationAction.APPROVE)"
[isDisabled]="!actionHelperService.isAuthorizedForButton(NotificationAction.APPROVE) || isProcessing()"
>
<div class="flex justify-between items-center">
<mat-icon class="mr-2" [attr.data-testid]="'approve-button-icon'">share</mat-icon>
Expand All @@ -66,19 +66,19 @@
</app-button>
</div>
<div class="detail--action--button"
matTooltip="{{'routing.unauthorized' | i18n}}"
matTooltip="{{ (isProcessing() ? 'routing.notificationInProcess': 'routing.unauthorized') | i18n}}"
matTooltipClass="table--header--tooltip"
matTooltipPosition="above"
[class.mdc-tooltip--multiline]="true"
[matTooltipShowDelay]="1000"
[matTooltipDisabled]="actionHelperService.isAuthorizedForButton(NotificationAction.CANCEL)"
[matTooltipDisabled]="actionHelperService.isAuthorizedForButton(NotificationAction.CANCEL) || isProcessing()"
>
<app-button
*ngIf="actionHelperService.showCancelButton(selectedNotification)"
onkeydown="notificationCommonModalComponent?.show(NotificationStatus.CANCELED)"
(click)="notificationCommonModalComponent?.show(NotificationStatus.CANCELED)"
[color]="'primary'"
[isDisabled]="!actionHelperService.isAuthorizedForButton(NotificationAction.CANCEL)"
[isDisabled]="!actionHelperService.isAuthorizedForButton(NotificationAction.CANCEL) || isProcessing()"
>
<div class="flex justify-between items-center">
<mat-icon class="mr-2" [attr.data-testid]="'cancel-button-icon'">cancel</mat-icon>
Expand All @@ -87,19 +87,19 @@
</app-button>
</div>
<div class="detail--action--button"
matTooltip="{{'routing.unauthorized' | i18n}}"
matTooltip="{{ (isProcessing() ? 'routing.notificationInProcess': 'routing.unauthorized') | i18n}}"
matTooltipClass="table--header--tooltip"
matTooltipPosition="above"
[class.mdc-tooltip--multiline]="true"
[matTooltipShowDelay]="1000"
[matTooltipDisabled]="actionHelperService.isAuthorizedForButton(NotificationAction.CLOSE)"
[matTooltipDisabled]="actionHelperService.isAuthorizedForButton(NotificationAction.CLOSE) && !isProcessing()"
>
<app-button
*ngIf="actionHelperService.showCloseButton(selectedNotification)"
onkeydown="notificationCommonModalComponent?.show(NotificationStatus.CLOSED)"
(click)="notificationCommonModalComponent?.show(NotificationStatus.CLOSED)"
[color]="'primary'"
[isDisabled]="!actionHelperService.isAuthorizedForButton(NotificationAction.CLOSE)"
[isDisabled]="!actionHelperService.isAuthorizedForButton(NotificationAction.CLOSE) || isProcessing()"
>
<div class="flex justify-between items-center">
<mat-icon class="mr-2" [attr.data-testid]="'close-button-icon'">close</mat-icon>
Expand All @@ -108,19 +108,19 @@
</app-button>
</div>
<div class="detail--action--button"
matTooltip="{{'routing.unauthorized' | i18n}}"
matTooltip="{{ (isProcessing() ? 'routing.notificationInProcess': 'routing.unauthorized') | i18n}}"
matTooltipClass="table--header--tooltip"
matTooltipPosition="above"
[class.mdc-tooltip--multiline]="true"
[matTooltipShowDelay]="1000"
[matTooltipDisabled]="actionHelperService.isAuthorizedForButton(NotificationAction.ACCEPT)"
[matTooltipDisabled]="actionHelperService.isAuthorizedForButton(NotificationAction.ACCEPT) && !isProcessing()"
>
<app-button
*ngIf="actionHelperService.showAcceptButton(selectedNotification)"
onkeydown="notificationCommonModalComponent?.show(NotificationStatus.ACCEPTED)"
(click)="notificationCommonModalComponent?.show(NotificationStatus.ACCEPTED)"
[color]="'primary'"
[isDisabled]="!actionHelperService.isAuthorizedForButton(NotificationAction.ACCEPT)"
[isDisabled]="!actionHelperService.isAuthorizedForButton(NotificationAction.ACCEPT) || isProcessing()"
>
<div class="flex justify-between items-center">
<mat-icon class="mr-2" [attr.data-testid]="'accept-button-icon'">assignment_turned_in</mat-icon>
Expand All @@ -129,19 +129,19 @@
</app-button>
</div>
<div class="detail--action--button"
matTooltip="{{'routing.unauthorized' | i18n}}"
matTooltip="{{ (isProcessing() ? 'routing.notificationInProcess': 'routing.unauthorized') | i18n}}"
matTooltipClass="table--header--tooltip"
matTooltipPosition="above"
[class.mdc-tooltip--multiline]="true"
[matTooltipShowDelay]="1000"
[matTooltipDisabled]="actionHelperService.isAuthorizedForButton(NotificationAction.ACKNOWLEDGE)"
[matTooltipDisabled]="actionHelperService.isAuthorizedForButton(NotificationAction.ACKNOWLEDGE) && !isProcessing()"
>
<app-button
*ngIf="actionHelperService.showAcknowledgeButton(selectedNotification)"
onkeydown="notificationCommonModalComponent?.show(NotificationStatus.ACKNOWLEDGED)"
(click)="notificationCommonModalComponent?.show(NotificationStatus.ACKNOWLEDGED)"
[color]="'primary'"
[isDisabled]="!actionHelperService.isAuthorizedForButton(NotificationAction.ACKNOWLEDGE)"
[isDisabled]="!actionHelperService.isAuthorizedForButton(NotificationAction.ACKNOWLEDGE) || isProcessing()"
>
<div class="flex justify-between items-center">
<mat-icon class="mr-2" [attr.data-testid]="'acknowledge-button-icon'">work</mat-icon>
Expand All @@ -150,19 +150,19 @@
</app-button>
</div>
<div class="detail--action--button"
matTooltip="{{'routing.unauthorized' | i18n}}"
matTooltip="{{ (isProcessing() ? 'routing.notificationInProcess': 'routing.unauthorized') | i18n}}"
matTooltipClass="table--header--tooltip"
matTooltipPosition="above"
[class.mdc-tooltip--multiline]="true"
[matTooltipShowDelay]="1000"
[matTooltipDisabled]="actionHelperService.isAuthorizedForButton(NotificationAction.DECLINE)"
[matTooltipDisabled]="actionHelperService.isAuthorizedForButton(NotificationAction.DECLINE) && !isProcessing()"
>
<app-button
*ngIf="actionHelperService.showDeclineButton(selectedNotification)"
onkeydown="notificationCommonModalComponent?.show(NotificationStatus.DECLINED)"
(click)="notificationCommonModalComponent?.show(NotificationStatus.DECLINED)"
[color]="'primary'"
[isDisabled]="!actionHelperService.isAuthorizedForButton(NotificationAction.DECLINE)"
[isDisabled]="!actionHelperService.isAuthorizedForButton(NotificationAction.DECLINE) || isProcessing()"
>
<div class="flex justify-between items-center">
<mat-icon class="mr-2" [attr.data-testid]="'decline-button-icon'">assignment_late</mat-icon>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import { ToastService } from '@shared/components/toasts/toast.service';
import { Notification, NotificationStatus, NotificationType } from '@shared/model/notification.model';
import { View } from '@shared/model/view.model';
import { NotificationAction } from '@shared/modules/notification/notification-action.enum';
import { NotificationProcessingService } from '@shared/service/notification-processing.service';
import { StaticIdService } from '@shared/service/staticId.service';
import { BehaviorSubject, Observable, Subject, Subscription } from 'rxjs';
import { filter, first, tap } from 'rxjs/operators';
Expand Down Expand Up @@ -78,18 +79,20 @@ export class NotificationDetailComponent implements AfterViewInit, OnDestroy {
private router: Router,
private readonly route: ActivatedRoute,
private readonly toastService: ToastService,
private readonly notificationProcessingService: NotificationProcessingService,
) {
this.notificationPartsInformation$ = this.notificationDetailFacade.notificationPartsInformation$;
this.supplierPartsDetailInformation$ = this.notificationDetailFacade.supplierPartsInformation$;

this.toastActionSubscription = this.toastService.retryAction.subscribe({
next: result => {
const formattedStatus = result?.context?.charAt(0)?.toUpperCase() + result?.context?.slice(1)?.toLowerCase();
const formattedStatus = result?.context?.notificationStatus?.charAt(0)?.toUpperCase() + result?.context?.notificationStatus?.slice(1)?.toLowerCase();
if (result?.success) {
this.toastService.success(`requestNotification.successfully${ formattedStatus }`);
} else if (result?.error) {
this.toastService.error(`requestNotification.failed${ formattedStatus }`, 15000, true);
}
this.notificationProcessingService.notificationIdsInLoadingState.delete(result?.context?.notificationId);
this.ngAfterViewInit();
},
});
Expand Down Expand Up @@ -228,6 +231,10 @@ export class NotificationDetailComponent implements AfterViewInit, OnDestroy {
.subscribe();
}

isProcessing() {
return this.notificationProcessingService.isInLoadingProcess(this.selectedNotification);
}

protected readonly NotificationType = NotificationType;
protected readonly NotificationAction = NotificationAction;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ import {
NotificationType,
} from '@shared/model/notification.model';
import { TranslationContext } from '@shared/model/translation-context.model';
import { NotificationProcessingService } from '@shared/service/notification-processing.service';
import { Subscription } from 'rxjs';

@Component({
Expand Down Expand Up @@ -74,6 +75,7 @@ export class NotificationsComponent {
private readonly route: ActivatedRoute,
private readonly cd: ChangeDetectorRef,
private readonly toastService: ToastService,
private readonly notificationProcessingService: NotificationProcessingService,
) {
this.notificationsReceived$ = this.notificationsFacade.notificationsReceived$;
this.notificationsQueuedAndRequested$ = this.notificationsFacade.notificationsQueuedAndRequested$;
Expand All @@ -87,13 +89,14 @@ export class NotificationsComponent {

this.toastActionSubscription = this.toastService.retryAction.subscribe({
next: result => {
const formatted = result?.context?.charAt(0)?.toUpperCase() + result?.context?.slice(1)?.toLowerCase();
const formatted = result?.context?.notificationStatus?.charAt(0)?.toUpperCase() + result?.context?.notificationStatus?.slice(1)?.toLowerCase();
if (result?.success) {
this.toastService.success(`requestNotification.successfully${ formatted }`);
} else if (result?.error) {
this.toastService.error(`requestNotification.failed${ formatted }`, 15000, true);
}
this.handleConfirmActionCompletedEvent();
this.notificationProcessingService.notificationIdsInLoadingState.delete(result?.context?.notificationId);
},
});
}
Expand All @@ -114,6 +117,7 @@ export class NotificationsComponent {
this.menuActionsConfig = NotificationMenuActionsAssembler.getMenuActions(
this.actionHelperService,
this.notificationCommonModalComponent,
this.notificationProcessingService,
);
this.cd.detectChanges();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,14 @@ import { NotificationMenuActionsAssembler } from '@shared/assembler/notification
import { NotificationCommonModalComponent } from '@shared/components/notification-common-modal/notification-common-modal.component';
import { Notification, NotificationStatus, NotificationType } from '@shared/model/notification.model';
import { Severity } from '@shared/model/severity.model';
import { NotificationProcessingService } from '@shared/service/notification-processing.service';
import { KeycloakService } from 'keycloak-angular';

describe('NotificationMenuActionsAssembler', () => {
let helperService: NotificationHelperService;
let notificationCommonModalComponent: NotificationCommonModalComponent;
let notificationActionHelperService: NotificationActionHelperService;
let notificationProcessingService: NotificationProcessingService;

beforeEach(function() {
TestBed.configureTestingModule({
Expand All @@ -56,11 +58,13 @@ describe('NotificationMenuActionsAssembler', () => {
notificationCommonModalComponent = TestBed.inject(NotificationCommonModalComponent);
helperService = TestBed.inject(NotificationHelperService);
notificationActionHelperService = TestBed.inject(NotificationActionHelperService);
notificationProcessingService = TestBed.inject(NotificationProcessingService);
});

it('should return menuActions', function() {
// Arrange
let showSpy = spyOn(notificationCommonModalComponent, 'show').and.returnValue(undefined);
let isLoadingSpy = spyOn(notificationProcessingService, 'isInLoadingProcess');

const notificationTemplate: Notification = {
id: 'id-1',
Expand All @@ -80,7 +84,7 @@ describe('NotificationMenuActionsAssembler', () => {
};

// Act
let menuActions = NotificationMenuActionsAssembler.getMenuActions(notificationActionHelperService, notificationCommonModalComponent);
let menuActions = NotificationMenuActionsAssembler.getMenuActions(notificationActionHelperService, notificationCommonModalComponent, notificationProcessingService);

// Assert
menuActions.map(item => {
Expand All @@ -89,6 +93,10 @@ describe('NotificationMenuActionsAssembler', () => {
expect(showSpy).toHaveBeenCalled();
let conditionAction = item.condition(notificationTemplate);
expect(conditionAction).not.toBe(undefined);
expect(item.isLoading).toBeDefined();
item.isLoading(notificationTemplate);
expect(isLoadingSpy).toHaveBeenCalled();

});
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,51 +21,59 @@ import { NotificationCommonModalComponent } from '@shared/components/notificatio
import { MenuActionConfig } from '@shared/components/table/table.model';
import { Notification, NotificationStatus } from '@shared/model/notification.model';
import { NotificationAction } from '@shared/modules/notification/notification-action.enum';
import { NotificationProcessingService } from '@shared/service/notification-processing.service';

export class NotificationMenuActionsAssembler {
public static getMenuActions(helperService: NotificationActionHelperService, modal: NotificationCommonModalComponent): MenuActionConfig<Notification>[] {
public static getMenuActions(helperService: NotificationActionHelperService, modal: NotificationCommonModalComponent, notificationProcessingService: NotificationProcessingService): MenuActionConfig<Notification>[] {
return [
{
label: 'actions.close',
icon: 'close',
action: data => modal.show(NotificationStatus.CLOSED, data),
condition: data => helperService.showCloseButton(data),
isAuthorized: helperService.isAuthorizedForButton(NotificationAction.CLOSE),
isLoading: data => notificationProcessingService.isInLoadingProcess(data),
},
{
label: 'actions.approve',
icon: 'share',
action: data => modal.show(NotificationStatus.APPROVED, data),
condition: data => helperService.showApproveButton(data),
isAuthorized: helperService.isAuthorizedForButton(NotificationAction.APPROVE),
isLoading: data => notificationProcessingService.isInLoadingProcess(data),

},
{
label: 'actions.cancel',
icon: 'cancel',
action: data => modal.show(NotificationStatus.CANCELED, data),
condition: data => helperService.showCancelButton(data),
isAuthorized: helperService.isAuthorizedForButton(NotificationAction.CANCEL),
isLoading: data => notificationProcessingService.isInLoadingProcess(data),
},
{
label: 'actions.acknowledge',
icon: 'work',
action: data => modal.show(NotificationStatus.ACKNOWLEDGED, data),
condition: data => helperService.showAcknowledgeButton(data),
isAuthorized: helperService.isAuthorizedForButton(NotificationAction.ACKNOWLEDGE),
isLoading: data => notificationProcessingService.isInLoadingProcess(data),
},
{
label: 'actions.accept',
icon: 'assignment_turned_in',
action: data => modal.show(NotificationStatus.ACCEPTED, data),
condition: data => helperService.showAcceptButton(data),
isAuthorized: helperService.isAuthorizedForButton(NotificationAction.ACCEPT),
isLoading: data => notificationProcessingService.isInLoadingProcess(data),
},
{
label: 'actions.decline',
icon: 'assignment_late',
action: data => modal.show(NotificationStatus.DECLINED, data),
condition: data => helperService.showDeclineButton(data),
isAuthorized: helperService.isAuthorizedForButton(NotificationAction.DECLINE),
isLoading: data => notificationProcessingService.isInLoadingProcess(data),
},
];
}
Expand Down
Loading

0 comments on commit 252757c

Please sign in to comment.