Skip to content

Commit

Permalink
chore(contracts): 985 implement contract reference to notification or…
Browse files Browse the repository at this point in the history
… part
  • Loading branch information
ds-mmaul committed Jun 27, 2024
1 parent d776afb commit 18ac028
Show file tree
Hide file tree
Showing 20 changed files with 288 additions and 41 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ _**For better traceability add the corresponding GitHub issue number in each cha
- XXX Added interceptor to EdcRestTemplates to log requests
- #915 Added section to documentation: EDC-BPN configuration
- #1037 Added link from contracts view to the corresponding filtered part table view
- #985 Added reference to part/notification under contract

### Removed

Expand Down
17 changes: 15 additions & 2 deletions frontend/src/app/mocks/services/admin-mock/admin.model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@
* SPDX-License-Identifier: Apache-2.0
********************************************************************************/

import {PaginationResponse} from '@core/model/pagination.model';
import {BpnConfigResponse, ContractResponse, ContractState} from '@page/admin/core/admin.model';
import { PaginationResponse } from '@core/model/pagination.model';
import { BpnConfigResponse, ContractResponse, ContractState, ContractType } from '@page/admin/core/admin.model';


export const getBpnConfig = (): BpnConfigResponse[] => [
Expand Down Expand Up @@ -221,6 +221,7 @@ export const getContracts = (): PaginationResponse<ContractResponse> => {
content: [
{
"contractId": "abc1",
'contractType': ContractType.ASSET_AS_BUILT,
"counterpartyAddress": "https://trace-x-edc-e2e-a.dev.demo.catena-x.net/api/v1/dsp",
"creationDate": "2024-02-26T13:38:07+01:00",
"endDate": null,
Expand All @@ -229,6 +230,7 @@ export const getContracts = (): PaginationResponse<ContractResponse> => {
},
{
"contractId": "abc2",
'contractType': ContractType.ASSET_AS_BUILT,
"counterpartyAddress": "https://trace-x-edc-e2e-a.dev.demo.catena-x.net/api/v1/dsp",
"creationDate": "2022-05-01T12:34:12",
"endDate": null,
Expand All @@ -237,6 +239,7 @@ export const getContracts = (): PaginationResponse<ContractResponse> => {
},
{
"contractId": "abc3",
'contractType': ContractType.ASSET_AS_BUILT,
"counterpartyAddress": "https://trace-x-edc-e2e-a.dev.demo.catena-x.net/api/v1/dsp",
"creationDate": "2022-05-01T12:34:12",
"endDate": null,
Expand All @@ -245,6 +248,7 @@ export const getContracts = (): PaginationResponse<ContractResponse> => {
},
{
"contractId": "abc4",
'contractType': ContractType.ASSET_AS_BUILT,
"counterpartyAddress": "https://trace-x-edc-e2e-a.dev.demo.catena-x.net/api/v1/dsp",
"creationDate": "2022-05-01T12:34:12",
"endDate": null,
Expand All @@ -253,6 +257,7 @@ export const getContracts = (): PaginationResponse<ContractResponse> => {
},
{
"contractId": "abc5",
'contractType': ContractType.ASSET_AS_PLANNED,
"counterpartyAddress": "https://trace-x-edc-e2e-a.dev.demo.catena-x.net/api/v1/dsp",
"creationDate": "2022-05-01T12:34:12",
"endDate": null,
Expand All @@ -261,6 +266,7 @@ export const getContracts = (): PaginationResponse<ContractResponse> => {
},
{
"contractId": "abc6",
'contractType': ContractType.ASSET_AS_PLANNED,
"counterpartyAddress": "https://trace-x-edc-e2e-a.dev.demo.catena-x.net/api/v1/dsp",
"creationDate": "2022-05-01T12:34:12",
"endDate": null,
Expand All @@ -269,6 +275,7 @@ export const getContracts = (): PaginationResponse<ContractResponse> => {
},
{
"contractId": "abc7",
'contractType': ContractType.ASSET_AS_PLANNED,
"counterpartyAddress": "https://trace-x-edc-e2e-a.dev.demo.catena-x.net/api/v1/dsp",
"creationDate": "2022-05-01T12:34:12",
"endDate": null,
Expand All @@ -277,6 +284,7 @@ export const getContracts = (): PaginationResponse<ContractResponse> => {
},
{
"contractId": "abc8",
'contractType': ContractType.ASSET_AS_PLANNED,
"counterpartyAddress": "https://trace-x-edc-e2e-a.dev.demo.catena-x.net/api/v1/dsp",
"creationDate": "2022-05-01T12:34:12",
"endDate": null,
Expand All @@ -285,6 +293,7 @@ export const getContracts = (): PaginationResponse<ContractResponse> => {
},
{
"contractId": "abc9",
'contractType': ContractType.NOTIFICATION,
"counterpartyAddress": "https://trace-x-edc-e2e-a.dev.demo.catena-x.net/api/v1/dsp",
"creationDate": "2022-05-01T12:34:12",
"endDate": null,
Expand All @@ -293,6 +302,7 @@ export const getContracts = (): PaginationResponse<ContractResponse> => {
},
{
"contractId": "abc10",
'contractType': ContractType.NOTIFICATION,
"counterpartyAddress": "https://trace-x-edc-e2e-a.dev.demo.catena-x.net/api/v1/dsp",
"creationDate": "2022-05-01T12:34:12",
"endDate": null,
Expand All @@ -301,6 +311,7 @@ export const getContracts = (): PaginationResponse<ContractResponse> => {
},
{
"contractId": "abc11",
'contractType': ContractType.NOTIFICATION,
"counterpartyAddress": "https://trace-x-edc-e2e-a.dev.demo.catena-x.net/api/v1/dsp",
"creationDate": "2022-05-01T12:34:12",
"endDate": null,
Expand All @@ -309,6 +320,7 @@ export const getContracts = (): PaginationResponse<ContractResponse> => {
},
{
"contractId": "abc12",
'contractType': ContractType.NOTIFICATION,
"counterpartyAddress": "https://trace-x-edc-e2e-a.dev.demo.catena-x.net/api/v1/dsp",
"creationDate": "2022-05-01T12:34:12",
"endDate": null,
Expand All @@ -317,6 +329,7 @@ export const getContracts = (): PaginationResponse<ContractResponse> => {
},
{
"contractId": "abc13",
'contractType': ContractType.NOTIFICATION,
"counterpartyAddress": "https://trace-x-edc-e2e-a.dev.demo.catena-x.net/api/v1/dsp",
"creationDate": "2022-05-01T12:34:12",
"endDate": null,
Expand Down
10 changes: 10 additions & 0 deletions frontend/src/app/modules/page/admin/core/admin.model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ export type BpnConfigFormGroup = FormGroup<{ bpnConfig: FormArray<FormControl<Bp

export interface Contract {
contractId: string,
contractType: ContractType,
counterpartyAddress: string,
creationDate: CalendarDateModel,
endDate: CalendarDateModel,
Expand All @@ -63,19 +64,28 @@ export interface Contract {

export interface ContractResponse {
contractId: string,
contractType: ContractType,
counterpartyAddress: string,
creationDate: string,
endDate: string,
state: ContractState,
policy: string
}

export enum ContractType {
ASSET_AS_BUILT = 'ASSET_AS_BUILT',
ASSET_AS_PLANNED = 'ASSET_AS_PLANNED',
NOTIFICATION = 'NOTIFICATION',
UNKNOWN = 'UNKNOWN'
}

export type ContractsResponse = PaginationResponse<ContractResponse>;
export type Contracts = Pagination<Contract>;
export function assembleContract(contractResponse: ContractResponse): Contract {

return {
contractId: contractResponse.contractId,
contractType: contractResponse.contractType,
counterpartyAddress: contractResponse.counterpartyAddress,
creationDate: new CalendarDateModel(contractResponse.creationDate),
endDate: new CalendarDateModel(contractResponse.endDate),
Expand Down
20 changes: 10 additions & 10 deletions frontend/src/app/modules/page/admin/core/admin.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,22 +19,22 @@
* SPDX-License-Identifier: Apache-2.0
********************************************************************************/

import {HttpParams} from '@angular/common/http';
import {Injectable} from '@angular/core';
import {ApiService} from '@core/api/api.service';
import {Pagination} from '@core/model/pagination.model';
import {environment} from '@env';
import {AdminAssembler} from '@page/admin/core/admin.assembler';
import { HttpParams } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { ApiService } from '@core/api/api.service';
import { Pagination } from '@core/model/pagination.model';
import { environment } from '@env';
import { AdminAssembler } from '@page/admin/core/admin.assembler';
import {
assembleContract,
BpnConfig,
BpnConfigResponse,
Contract,
ContractResponse,
} from '@page/admin/core/admin.model';
import {TableHeaderSort} from '@shared/components/table/table.model';
import {Observable} from 'rxjs';
import {map} from 'rxjs/operators';
import { TableHeaderSort } from '@shared/components/table/table.model';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';

@Injectable()
export class AdminService {
Expand Down Expand Up @@ -109,7 +109,7 @@ export class AdminService {
Object.entries(filter).forEach(([ entry, values ]) => {
if (values.length) {
values.forEach(value => {
filterList.push(`${ entry },EQUAL,${ value },AND`);
filterList.push(`${ entry },EQUAL,${ value },OR`);
});
}
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@
</mat-card-header>

<mat-card-content>
<div class="flex flex-row justify-end mb-2">
<div class="flex flex-row justify-between my-4">
<app-contracts-quick-filter (buttonClickEvent)="filterContractType($event)">
</app-contracts-quick-filter>
<div class="detail--action--button"
matTooltip="{{'pageAdmin.contracts.selectAtleastOne' | i18n}}"
matTooltipClass="table--header--tooltip"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,15 +90,15 @@ describe('ContractTableComponent', () => {
it('should navigate if viewAssets clicked', async () => {
const { fixture } = await renderContractTableComponent();
const { componentInstance } = fixture;
componentInstance.viewAssetsClicked.emit({ contractId: 'test' });
componentInstance.viewItemsClicked.emit({ contractId: 'test' });

expect(routerMock.navigate).toHaveBeenCalled();
});

it('should emit viewAssetsClicked', async () => {
const { fixture } = await renderContractTableComponent();
const { componentInstance } = fixture;
let spy = spyOn(componentInstance.viewAssetsClicked, 'emit');
let spy = spyOn(componentInstance.viewItemsClicked, 'emit');
const viewAssetsAction = componentInstance.tableConfig.menuActionsConfig.filter(action => action.label === 'actions.viewParts')[0];
viewAssetsAction.action(null);
expect(spy).toHaveBeenCalled();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,15 @@ import { Component, EventEmitter } from '@angular/core';
import { Router } from '@angular/router';
import { Pagination } from '@core/model/pagination.model';
import { AdminFacade } from '@page/admin/core/admin.facade';
import { Contract, KnownAdminRoutes } from '@page/admin/core/admin.model';
import { Contract, ContractType, KnownAdminRoutes } from '@page/admin/core/admin.model';
import { ContractsFacade } from '@page/admin/presentation/contracts/contracts.facade';
import { TableType } from '@shared/components/multi-select-autocomplete/table-type.model';
import { CreateHeaderFromColumns, TableConfig, TableEventConfig } from '@shared/components/table/table.model';
import { ToastService } from '@shared/components/toasts/toast.service';
import { View } from '@shared/model/view.model';
import { NotificationAction } from '@shared/modules/notification/notification-action.enum';
import { NotificationService } from '@shared/service/notification.service';
import { PartsService } from '@shared/service/parts.service';
import { Observable } from 'rxjs';
import { take } from 'rxjs/operators';

Expand All @@ -22,40 +25,73 @@ export class ContractsComponent {
selectedContracts: Contract[];
contractFilter: any;
pagination: TableEventConfig;
viewAssetsClicked: EventEmitter<any> = new EventEmitter;
viewItemsClicked: EventEmitter<any> = new EventEmitter;

constructor(public readonly adminFacade: AdminFacade, private readonly contractsFacade: ContractsFacade, private readonly router: Router) {}
constructor(public readonly adminFacade: AdminFacade, private readonly contractsFacade: ContractsFacade, private readonly router: Router, private readonly partsService: PartsService, private readonly notificationsService: NotificationService, private readonly toastService: ToastService) {
}

public ngOnInit() {
this.contractsView$ = this.contractsFacade.contracts$;
this.contractsView$.pipe(take(1)).subscribe(data => {
if(data?.data?.content.length) {
if (data?.data?.content.length) {
return;
} else {
this.contractsFacade.setContracts(0,10,[null,null]);
this.contractsFacade.setContracts(0, 10, [ null, null ]);
}

})
});

this.viewItemsClicked.subscribe((data) => {
const contractId = data?.contractId;

this.viewAssetsClicked.subscribe((data) => {
this.router.navigate([ 'parts' ], { queryParams: { contractId: data?.['contractId'] } });
if (data?.contractType === ContractType.NOTIFICATION) {
this.notificationsService.getNotifications(0, 1, [], undefined, undefined, { contractAgreementId: contractId }).subscribe({
next: data => {
data?.content?.length > 0 ? this.router.navigate([ 'inbox', data?.content[0]?.id ]) : this.toastService.error('pageAdmin.contracts.noItemsFoundError');
},
error: error => this.toastService.error(error),
},
);
} else {
this.partsService.getPartsByFilter({ contractAgreementId: contractId }, data?.contractType === ContractType.ASSET_AS_BUILT).subscribe({
next: data => data?.content?.length > 0 ? this.router.navigate([ 'parts', data?.content[0]?.id ], { queryParams: { isAsBuilt: data?.content[0]?.partId !== undefined } }) : this.toastService.error('pageAdmin.contracts.noItemsFoundError'),
error: error => this.toastService.error(error),

});
}
});

this.pagination = { page: 0, pageSize: 10, sorting: [ '', null ] };


this.tableConfig = {
displayedColumns: [ 'select', 'contractId', 'counterpartyAddress', 'creationDate', 'endDate', 'state', 'menu' ],
header: CreateHeaderFromColumns([ 'contractId', 'counterpartyAddress', 'creationDate', 'endDate', 'state', 'menu' ], 'pageAdmin.contracts'),
displayedColumns: [ 'select', 'contractId', 'contractType', 'counterpartyAddress', 'creationDate', 'endDate', 'state', 'menu' ],
header: CreateHeaderFromColumns([ 'contractId', 'contractType', 'counterpartyAddress', 'creationDate', 'endDate', 'state', 'menu' ], 'pageAdmin.contracts'),
menuActionsConfig: [
{
label: 'actions.viewParts',
icon: 'build',
action: (data: Record<string, unknown>) => {
this.viewAssetsClicked.emit(data);
this.viewItemsClicked.emit(data);
},
condition: (data: Contract) => {
return (data?.contractType === ContractType.ASSET_AS_BUILT || data?.contractType === ContractType.ASSET_AS_PLANNED);
},
},
{
label: 'actions.viewNotifications',
icon: 'announcement',
action: (data: Record<string, unknown>) => {
this.viewItemsClicked.emit(data);
},
condition: (data: Contract) => {
return (data?.contractType === ContractType.NOTIFICATION);
},
},
],
sortableColumns: {
select: false,
contractType: false,
contractId: true,
counterpartyAddress: false,
creationDate: false,
Expand All @@ -72,7 +108,7 @@ export class ContractsComponent {

public onTableConfigChange(pagination: TableEventConfig): void {
this.pagination = pagination;
this.contractsFacade.setContracts(pagination.page, pagination.pageSize,[pagination.sorting]);
this.contractsFacade.setContracts(pagination.page, pagination.pageSize, [ pagination.sorting ], this.contractFilter);
}

multiSelection(selectedContracts: Contract[]) {
Expand Down Expand Up @@ -114,7 +150,15 @@ export class ContractsComponent {

openDetailedView(selectedContract: Record<string, unknown>) {
this.contractsFacade.selectedContract = selectedContract as unknown as Contract;
this.router.navigate(['admin/'+KnownAdminRoutes.CONTRACT+'/'+this.contractsFacade.selectedContract.contractId]);
this.router.navigate([ 'admin/' + KnownAdminRoutes.CONTRACT + '/' + this.contractsFacade.selectedContract.contractId ]);
}

filterContractType(filterList: any) {
this.contractFilter = {
...this.contractFilter,
contractType: filterList,
};
this.contractsFacade.setContracts(this.pagination.page, this.pagination.pageSize, [ this.pagination.sorting ], this.contractFilter);
}

ngOnDestroy() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,9 @@ export class ContractsFacade {
return this.contractsState.contracts$
}

public setContracts(page, pageSize = 50, sorting: TableHeaderSort[]): void {
public setContracts(page, pageSize = 50, sorting: TableHeaderSort[], filter?: any): void {
this.contractsSubscription?.unsubscribe();
this.contractsSubscription = this.adminService.getContracts(page,pageSize,sorting).subscribe({
this.contractsSubscription = this.adminService.getContracts(page, pageSize, sorting, filter).subscribe({
next: data => (this.contractsState.contracts = { data: provideDataObject(data) }),
error: error => (this.contractsState.contracts = { error})
})
Expand Down
Loading

0 comments on commit 18ac028

Please sign in to comment.