Skip to content

Commit

Permalink
Merge pull request #1124 from eclipse-tractusx/feature/#832-enable-po…
Browse files Browse the repository at this point in the history
…licy-management

chore(policy): 832 layout feedback
  • Loading branch information
ds-mwesener authored Jun 27, 2024
2 parents 00ddfb5 + c698f5b commit f3a3c4d
Show file tree
Hide file tree
Showing 13 changed files with 119 additions and 23 deletions.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
29 changes: 25 additions & 4 deletions frontend/src/app/mocks/services/policy-mock/policy.model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ import { OperatorType, Policy, PolicyAction, PolicyResponseMap } from '@page/pol
* SPDX-License-Identifier: Apache-2.0
********************************************************************************/
// For now Mocks are built by current response (any). This is because Policy Model changes frequently
export const getPolicies = (): Policy[] => {
return mockedPolicyList;
export const getPolicies = (): PolicyResponseMap => {
return MockPolicyResponseMap;
};

export const getPolicyById = (policyId: string | ReadonlyArray<string>): Policy => {
Expand Down Expand Up @@ -183,11 +183,32 @@ export const MockPolicyResponseMap: PolicyResponseMap = {
'and': null,
'or': [
{
'leftOperand': 'asd',
'leftOperand': 'cx-policy:FrameworkAgreement',
'operator': {
'@id': OperatorType.EQ,
},
'odrl:rightOperand': 'dsa',
'odrl:rightOperand': 'traceability:1.0',
},
{
'leftOperand': 'cx-policy:FrameworkAgreement',
'operator': {
'@id': OperatorType.EQ,
},
'odrl:rightOperand': 'traceability:1.0',
},
{
'leftOperand': 'cx-policy:FrameworkAgreement',
'operator': {
'@id': OperatorType.EQ,
},
'odrl:rightOperand': 'traceability:1.0',
},
{
'leftOperand': 'cx-policy:FrameworkAgreement',
'operator': {
'@id': OperatorType.EQ,
},
'odrl:rightOperand': 'traceability:1.0',
},
],
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ describe('PoliciesAssembler', () => {
expect(assembledPolicy.createdOn).toBe('2024-01-01T00:00');
expect(assembledPolicy.validUntil).toBe('2024-12-31T23:59');
expect(assembledPolicy.accessType).toBe('USE');
expect(assembledPolicy.constraints).toEqual([ 'left1', '=', 'right1', 'left2', '!=', 'right2' ]);
expect(assembledPolicy.constraints).toEqual('left1=right1left2!=right2');

});

Expand All @@ -107,15 +107,21 @@ describe('PoliciesAssembler', () => {
},
};
const constraints = PoliciesAssembler.mapDisplayPropsToPolicyRootLevelFromPolicyEntry(policyEntry);
expect(constraints).toEqual([
'left1', '=', 'right1', 'left2', '!=', 'right2',
]);
expect(constraints).toEqual('left1=right1left2!=right2');
});

it('should map display props to policy root level from policy', () => {
const constraints = PoliciesAssembler.mapDisplayPropsToPolicyRootLevelFromPolicy(mockPolicy2);
expect(constraints).toEqual([
'left1', '=', 'right1', 'left2', '!=', 'right2',
]);
expect(constraints).toEqual('left1=right1left2!=right2');
});

it('should remove everything after the third symbol', () => {
const testString = 'a,b,c,d,e';
const result = PoliciesAssembler.removeAfterThird(',', testString);
expect(result).toEqual('a,b,c,');
const testString2 = 'a,b,c';
const resul2 = PoliciesAssembler.removeAfterThird(',', testString2);
expect(resul2).toEqual('a,b,c');
});

});
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
[showHover]="false"
[tableType]="TableType.POLICIES"
[tableSettingsEnabled]="true"
[selectedPoliciesInfoLabel]="selectedPoliciesInfoLabel"
[deselectTrigger]="deselectPartTrigger$ | async"
(selected)="openDetailedView($event)"
(editClicked)="openEditView($event)"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,21 @@ describe('PoliciesComponent', () => {
expect(policyFacadeMock.setPolicies).toHaveBeenCalled();
}));

it('should call deletePolicies and handle success', fakeAsync(async () => {
const { fixture } = await renderPoliciesComponent();
const componentInstance = fixture.componentInstance;
componentInstance.selectedPolicies = [ { policyId: '1' }, { policyId: '2' } ] as Policy[];

componentInstance.multiSelection(componentInstance.selectedPolicies);
expect(componentInstance.selectedPoliciesInfoLabel).toEqual('pageAdmin.policyManagement.selectedPolicies');

componentInstance.selectedPolicies = [ { policyId: '1' } ] as Policy[];

componentInstance.multiSelection(componentInstance.selectedPolicies);
expect(componentInstance.selectedPoliciesInfoLabel).toEqual('pageAdmin.policyManagement.selectedPolicy');

}));

it('should call deletePolicies and handle error', fakeAsync(async () => {
policyFacadeMock.deletePolicies.and.returnValue(throwError('error'));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ export class PoliciesComponent {
multiSortList: TableHeaderSort[] = [];
ctrlKeyState: boolean = false;
deselectPartTrigger$ = new Subject<Policy[]>();
selectedPoliciesInfoLabel: string = 'pageAdmin.policyManagement.selectedPolicies';

constructor(public readonly policyFacade: PoliciesFacade, private readonly router: Router, private readonly toastService: ToastService, public dialog: MatDialog, private readonly roleService: RoleService) {
window.addEventListener('keydown', (event) => {
Expand Down Expand Up @@ -82,6 +83,7 @@ export class PoliciesComponent {
}

multiSelection(selectedPolicies: Policy[]) {
this.selectedPoliciesInfoLabel = selectedPolicies.length === 1 ? 'pageAdmin.policyManagement.selectedPolicy' : 'pageAdmin.policyManagement.selectedPolicies';
this.selectedPolicies = selectedPolicies;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ export class PoliciesAssembler {
return list;
}

public static mapDisplayPropsToPolicyRootLevelFromPolicyEntry(entry: PolicyEntry): string[] {
public static mapDisplayPropsToPolicyRootLevelFromPolicyEntry(entry: PolicyEntry): string {
entry.payload.policy.policyName = entry.payload['@id'];
entry.payload.policy.accessType = entry.payload.policy.permissions[0].action;
let constrainsList = [];
Expand All @@ -45,42 +45,68 @@ export class PoliciesAssembler {
constrainsList.push(getOperatorTypeSign(OperatorType[andConstraint.operator['@id'].toUpperCase()]));
constrainsList.push(andConstraint['odrl:rightOperand']);
if (index !== permission.constraint.and.length - 1) {
constrainsList.push(' AND ');
constrainsList.push('*AND ');
}
});
permission.constraint?.or?.forEach((orConstraint, index) => {
constrainsList.push(orConstraint.leftOperand);
constrainsList.push(getOperatorTypeSign(OperatorType[orConstraint.operator['@id'].toUpperCase()]));
constrainsList.push(orConstraint['odrl:rightOperand']);
if (index !== permission.constraint.or.length - 1) {
constrainsList.push(' OR ');
constrainsList.push('*OR ');
}
});
});
return constrainsList;
return this.formatConstraintsListForTable(constrainsList);
}

public static mapDisplayPropsToPolicyRootLevelFromPolicy(policy: Policy): string[] {
public static mapDisplayPropsToPolicyRootLevelFromPolicy(policy: Policy): string {
let constrainsList = [];
policy.permissions.forEach((permission) => {
permission.constraints?.and?.forEach((andConstraint, index) => {
constrainsList.push(andConstraint.leftOperand);
constrainsList.push(getOperatorTypeSign(andConstraint.operatorTypeResponse));
constrainsList.push(andConstraint.rightOperand);
if (index !== permission.constraints.and.length - 1) {
constrainsList.push(' AND ');
constrainsList.push('*AND ');
}
});
permission.constraints?.or?.forEach((orConstraint, index) => {
constrainsList.push(orConstraint.leftOperand);
constrainsList.push(getOperatorTypeSign(orConstraint.operatorTypeResponse));
constrainsList.push(orConstraint.rightOperand);
if (index !== permission.constraints.or.length - 1) {
constrainsList.push(' OR ');
constrainsList.push('*OR ');
}
});
});
return constrainsList;
return this.formatConstraintsListForTable(constrainsList);
}

public static formatConstraintsListForTable(constrainsList: string[]): string {
let formattedString = constrainsList.toString().replaceAll(',', '');
formattedString = formattedString.replaceAll('*', '<br>');
formattedString = this.removeAfterThird('<br>', formattedString);
return formattedString;
}

public static removeAfterThird(substring: string, text: string): string {
let index = 0;
let count = 0;

// Continuously update the index to the next occurrence of the substring
while ((index = text.indexOf(substring, index)) !== -1) {
count++;
if (count === 3) {
// Return the substring up to and including the third occurrence
return text.substring(0, index + substring.length);
}
// Advance index past the current match
index += substring.length;
}

// Return the original text if less than three occurrences are found
return text;
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ describe('PolicyEditorComponent', () => {
},
},
],
constraints: [],
constraints: null,
};

beforeEach(() => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ export interface Policy {
// additional props
policyName?: string;
bpn?: string;
constraints?: string[]
constraints?: string,
accessType?: PolicyAction,
businessPartnerNumber?: string | string[]

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
</div>
<div *ngIf="tableHeaderMenuEnabled || basicTableHeaderMenuEnabled"
class="table-header--action--container flex mt-1">
<div class="table-header--action--container--left-section flex">
<div class="mr-0.5"
*ngIf="tableHeaderMenuEnabled"
matTooltip="{{ (roleService.isAdmin() ? 'routing.unauthorized':'table.createNotification') | i18n}}"
Expand Down Expand Up @@ -158,6 +159,11 @@
</button>
</div>
</mat-menu>
</div>
<div class="table-header--action--container--right-section flex items-center">
<p *ngIf="selectedPoliciesInfoLabel"
class="regular-text table&#45;&#45;selected&#45;&#45;label">{{ selectedPoliciesInfoLabel | i18n : {count: selection?.selected?.length || 0} }}</p>
</div>
</div>
</div>
</div>
Expand Down Expand Up @@ -415,7 +421,7 @@ <h3>{{ 'table.noResultFound' | i18n }}</h3>
*matCellDef="let element" mat-cell class="table--cell" data-testid="table-component--cell-data"
[ngClass]="{'max-width-column': labelId === 'contracts' && column === 'contractId' }">
<ng-container *ngIf="!isDateElement(column)"
[ngTemplateOutlet]="tableConfig?.cellRenderers?.[column] ? tableConfig?.cellRenderers?.[column] : autoFormat"
[ngTemplateOutlet]="tableConfig?.cellRenderers?.[column] ? tableConfig?.cellRenderers?.[column] : (column === 'constraints' ? constraintsFormat : autoFormat)"
[ngTemplateOutletContext]="{ value: element[column], row: element }"
>
</ng-container>
Expand Down Expand Up @@ -446,3 +452,10 @@ <h3>{{ 'table.noResultFound' | i18n }}</h3>
<ng-template #autoFormat let-value="value">
{{ value | autoFormat | i18n }}
</ng-template>

<ng-template #constraintsFormat let-value="value">
<div [innerHTML]="value" class="cellFormat-constrains-container">

</div>

</ng-template>
Original file line number Diff line number Diff line change
Expand Up @@ -266,3 +266,12 @@ tr.error {
height: 63vh !important;
}

.table-header--action--container {
display: flex;
justify-content: space-between;
}

.cellFormat-constrains-container {
word-break: keep-all;
}

Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ export class TableComponent {
@Input() showHover = true;

@Input() selectedPartsInfoLabel: string;
@Input() selectedPoliciesInfoLabel: string;
@Input() selectedPartsActionLabel: string;

@Input() tableHeader: string;
Expand Down
4 changes: 3 additions & 1 deletion frontend/src/assets/locales/de/page.admin.json
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,9 @@
"bpnsHint" : "Liste von BPNs separiert durch ein Kommazeichen",
"bpnHint" : "",
"savePolicy" : "Richtlinie speichern",
"addConstraint" : "Regel hinzufügen"
"addConstraint" : "Regel hinzufügen",
"selectedPolicy" : "{{count}} Richtlinie für diese Seite ausgewählt.",
"selectedPolicies" : "{{count}} Richtlinien für diese Seite ausgewählt."
}
}
}

0 comments on commit f3a3c4d

Please sign in to comment.