Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 1 addition & 1 deletion .commit
Original file line number Diff line number Diff line change
@@ -1 +1 @@
456872c2445b89a895c65ea2b00cb819b33779b9
9cea15b67ed3cf53ec30f75bf8e6a39cc233422b
1 change: 0 additions & 1 deletion .sync-history
Original file line number Diff line number Diff line change
@@ -1 +0,0 @@
a0b2454a2 2025-12-08 Merged PR 87103: #648563 - Fix create team role
Binary file not shown.
Binary file added imxweb/imx-modules/elemental-ui-core-18.0.14.tgz
Binary file not shown.
Binary file modified imxweb/imx-modules/imx-api-aad.tgz
Binary file not shown.
Binary file modified imxweb/imx-modules/imx-api-aob.tgz
Binary file not shown.
Binary file modified imxweb/imx-modules/imx-api-apc.tgz
Binary file not shown.
Binary file modified imxweb/imx-modules/imx-api-att.tgz
Binary file not shown.
Binary file modified imxweb/imx-modules/imx-api-cpl.tgz
Binary file not shown.
Binary file modified imxweb/imx-modules/imx-api-dpr.tgz
Binary file not shown.
Binary file modified imxweb/imx-modules/imx-api-hds.tgz
Binary file not shown.
Binary file modified imxweb/imx-modules/imx-api-o3e.tgz
Binary file not shown.
Binary file modified imxweb/imx-modules/imx-api-o3t.tgz
Binary file not shown.
Binary file modified imxweb/imx-modules/imx-api-olg.tgz
Binary file not shown.
Binary file modified imxweb/imx-modules/imx-api-pol.tgz
Binary file not shown.
Binary file modified imxweb/imx-modules/imx-api-qbm.tgz
Binary file not shown.
Binary file modified imxweb/imx-modules/imx-api-qer.tgz
Binary file not shown.
Binary file modified imxweb/imx-modules/imx-api-rmb.tgz
Binary file not shown.
Binary file modified imxweb/imx-modules/imx-api-rms.tgz
Binary file not shown.
Binary file modified imxweb/imx-modules/imx-api-rps.tgz
Binary file not shown.
Binary file modified imxweb/imx-modules/imx-api-sac.tgz
Binary file not shown.
Binary file modified imxweb/imx-modules/imx-api-tsb.tgz
Binary file not shown.
Binary file modified imxweb/imx-modules/imx-api-uci.tgz
Binary file not shown.
Binary file modified imxweb/imx-modules/imx-api.tgz
Binary file not shown.
Binary file modified imxweb/imx-modules/imx-qbm-dbts.tgz
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,11 @@
<mat-card>
<imx-decision-history-item *ngFor="let workflowHistoryEntity of workflowHistoryData" [workflowHistoryEntity]="workflowHistoryEntity"> </imx-decision-history-item>
<imx-approvers *ngIf="approvers" [approvers]="approvers"></imx-approvers>
<li *ngIf="!approvers?.canSeeSteps && case.AttestationState.value === 'pending'" class="imx-event imx-pending">
<mat-card>
{{ '#LDS#You do not have permission to view assigned attestors.' | translate }}
</mat-card>
</li>
</mat-card>
</div>
</ng-template>
Expand All @@ -44,12 +49,12 @@
{{ '#LDS#Download report' | translate }}
</button>

<button *ngIf="canDecide" mat-flat-button color="warn" data-imx-identifier="attestation-history-detail-button-deny" (click)="attestationAction.deny([case],false)">
<button *ngIf="canDecide" mat-flat-button color="warn" data-imx-identifier="attestation-history-detail-button-deny" (click)="attestationAction.deny([case], false)">
<mat-icon>not_interested</mat-icon>
<span translate>#LDS#Deny</span>
</button>

<button *ngIf="canDecide" mat-flat-button color="primary" data-imx-identifier="attestation-history-detail-button-approve" (click)="attestationAction.approve([case],false)">
<button *ngIf="canDecide" mat-flat-button color="primary" data-imx-identifier="attestation-history-detail-button-approve" (click)="attestationAction.approve([case], false)">
<eui-icon icon="check"></eui-icon>
<span translate>#LDS#Approve</span>
</button>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
@import "@elemental-ui/core/src/styles/_eui_palette.scss";
@import '@elemental-ui/core/src/styles/_eui_palette.scss';

:host {
overflow: hidden;
Expand Down Expand Up @@ -47,6 +47,38 @@
}
}

li {
max-width: 460px;
}

li.imx-event {
list-style-type: none;
padding: 0 0 20px 48px;
min-height: 32px;
}

li.imx-event::before {
margin-left: -50px;
background-color: $color-gray-0;
height: 24px;
width: 28px;
content: '';
float: left;
margin-top: -2px;
}

li.imx-event.imx-pending {
background: linear-gradient($color-gray-30, $color-gray-30) no-repeat scroll 9px 0 transparent;
background-size: 2px 1000px;
}

li.imx-event.imx-pending::before {
font-family: Cadence-Icon;
font-size: 24px;
color: $color-gray-30;
content: '\e009';
}

.eui-dark-theme {
:host {
.imx-button-bar {
Expand All @@ -56,6 +88,15 @@
.mat-tab-labels {
background-color: $color-gray-70;
}
li.imx-event::before {
background-color: $color-gray-70;
}

li {
.mat-card {
background-color: $color-gray-60;
}
}
}
}

Expand All @@ -68,5 +109,14 @@
.mat-tab-labels {
background-color: $color-gray-90;
}
li.imx-event::before {
background-color: $color-gray-70;
}

li {
.mat-card {
background-color: $color-gray-60;
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@
</ng-template>
</mat-tab>

<mat-tab [label]="'#LDS#History' | translate">
<mat-tab [label]="'#LDS#History' | translate" *ngIf="isHistoryAvailable">
<ng-template matTabContent>
<div eui-sidesheet-content class="imx-attestation-case-hyperview">
<imx-attestation-case-history [case]="case"></imx-attestation-case-history>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ import {
ColumnDependentReference,
MetadataService,
SnackBarService,
SqlWizardApiService,
SystemInfoService,
} from 'qbm';
import {
Expand Down Expand Up @@ -84,6 +85,7 @@ export class AttestationCaseComponent implements OnDestroy, OnInit {
public selectedHyperviewUID: string;
public selectedOption: AttestationRelatedObject;
public relatedOptions: AttestationRelatedObject[] = [];
public isHistoryAvailable = false;

private readonly subscriptions$: Subscription[] = [];

Expand All @@ -110,7 +112,8 @@ export class AttestationCaseComponent implements OnDestroy, OnInit {
private readonly systemInfoService: SystemInfoService,
private readonly logger: ClassloggerService,
private readonly metadataService: MetadataService,
authentication: AuthenticationService
private readonly sqlService: SqlWizardApiService,
authentication: AuthenticationService,
) {
this.case = data.case;
this.approvers = data.approvers;
Expand Down Expand Up @@ -143,7 +146,9 @@ export class AttestationCaseComponent implements OnDestroy, OnInit {
this.policyTabTitle = await this.translate.get('#LDS#Heading Policy Violations').toPromise();
const info = await this.systemInfoService.get();
this.canAnalyzeRisk = info.PreProps.includes('RISKINDEX') && this.case.RiskIndex.value > 0;
} finally {
const filterProperties = await this.sqlService.getFilterProperties('AttestationCase');
this.isHistoryAvailable = ['UID_AttestationPolicy','ObjectKeyBase','UID_AttestationCase'].every((col) => filterProperties.findIndex((prop) => prop.PropertyId === col) !== -1);
}finally {
this.busyService.hide(overlay);
}
}
Expand Down Expand Up @@ -243,7 +248,7 @@ export class AttestationCaseComponent implements OnDestroy, OnInit {
ObjectKey: relatedObject.ObjectKey,
Display: `${relatedObject.Display} - ${this.metadataService.tables[objectType.TableName].DisplaySingular}`,
};
})
}),
)) || [];
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -118,12 +118,31 @@ export class ApproverContainer {
public getApproverAdditionalInfo(approver: { display: string, data: EntityData[] }[], additionalInfoDisplay: string):{[key:string]: {[key:string]: {string}}}
{
const returnValue = {};

for (const elem of approver) {
returnValue[elem.display] = {};
for(const data of elem.data){
if(data.Columns.UID_ComplianceRule?.Value)
returnValue[elem.display][data.Columns.UID_PersonHead.DisplayValue] = `(${additionalInfoDisplay}: ${(data.Columns.UID_ComplianceRule?.DisplayValue ?? '')})`;
}
for (const data of elem.data) {
// Find all entries for the same approver in the given working step without a decision yet
const elements =
this.request.pwoData.WorkflowData?.Entities?.filter(
(elem) =>
elem.Columns?.UID_PersonHead?.Value === data.Columns?.UID_PersonHead?.Value &&
elem.Columns?.UID_QERWorkingStep?.Value === data.Columns?.UID_QERWorkingStep?.Value &&
(elem.Columns?.Decision?.Value ?? '') === '',
) ?? [];

if (!!elements.length) {
// Get the one with the lowest sublevel number, that has a compliance rule assigned
const lowestElement = elements
.filter((elem) => elem.Columns?.SubLevelNumber && elem.Columns?.UID_ComplianceRule?.Value !== '')
.reduce((min, e) => (e.Columns!.SubLevelNumber!.Value < min.Columns!.SubLevelNumber!.Value ? e : min), elements[0]);
if (lowestElement && lowestElement.Columns?.UID_ComplianceRule?.Value !== '') {
// Assign the compliance rule display value to the return object
returnValue[elem.display][data.Columns?.UID_PersonHead?.DisplayValue ?? ''] =
`(${additionalInfoDisplay}: ${lowestElement.Columns?.UID_ComplianceRule?.DisplayValue ?? ''})`;
}
}
}
}
return returnValue;
}
Expand Down
36 changes: 24 additions & 12 deletions imxweb/projects/qer/src/lib/itshopapprove/decision-step.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,12 @@ import { EntityService, AuthenticationService, ColumnDependentReference, BaseRea
providedIn: 'root',
})
export class DecisionStepSevice {

public isEscalationApprover: boolean = false;
private uidUser: string;
constructor(private readonly entityService: EntityService, authentication: AuthenticationService) {
constructor(
private readonly entityService: EntityService,
authentication: AuthenticationService,
) {
authentication.onSessionResponse.subscribe((session) => (this.uidUser = session.UserUid));
}

Expand All @@ -48,7 +50,7 @@ export class DecisionStepSevice {
}

public getAdditionalInfoCdr(entity: TypedEntity, extended: any, display: string): ColumnDependentReference {
const step = getWorkflowDataWithSmallestSublevel(extended, entity, this.uidUser, this.isEscalationApprover);
const step = getWorkflowDataWithSmallestSublevel(extended, entity, this.uidUser, this.isEscalationApprover);

if (!step) {
return undefined;
Expand All @@ -74,7 +76,7 @@ export class DecisionStepSevice {
const smallest = getWorkflowDataWithSmallestSublevel(extended, entity, uidUser, this.isEscalationApprover);
const uniqueUsersMap =
extended?.WorkflowSteps?.Entities?.filter(
(elem: EntityData) => elem.Columns.UID_QERWorkingStep.Value === smallest?.Columns?.UID_QERWorkingStep.Value
(elem: EntityData) => elem.Columns.UID_QERWorkingStep.Value === smallest?.Columns?.UID_QERWorkingStep.Value,
)?.reduce((acc, current) => {
return { ...acc, [current.Keys[0]]: current };
}, {}) ?? [];
Expand Down Expand Up @@ -108,14 +110,24 @@ export function getSubLevel(entity: TypedEntity, extended: any, uidUser: string,
* @returns The step with the smallest sublevel in the current main level, that needs to be approved by the current user.
* If no such step exists, the value is undefined.
*/

export function getWorkflowDataWithSmallestSublevel(extended: any, entity: TypedEntity, uidUser: string, isEscalationApprover: boolean): EntityData | undefined {
return extended?.WorkflowData?.Entities?.filter(
export function getWorkflowDataWithSmallestSublevel(
extended: any,
entity: TypedEntity,
uidUser: string,
isEscalationApprover: boolean,
): EntityData | undefined {
const filteredData = extended?.WorkflowData?.Entities?.filter(
(data: EntityData) =>
(isEscalationApprover || data?.Columns?.UID_PersonHead.Value === uidUser) &&
(isEscalationApprover || data?.Columns?.UID_PersonHead.Value === uidUser) &&
(data?.Columns?.Decision?.Value ?? '') === '' &&
data.Columns?.LevelNumber.Value === entity.GetEntity().GetColumn('DecisionLevel').GetValue()
)?.reduce((lowestSublevel, current) => {
return current.Columns.SubLevelNumber.Value < lowestSublevel.Columns.SubLevelNumber.Value ? current : lowestSublevel;
});
data.Columns?.LevelNumber.Value === entity.GetEntity().GetColumn('DecisionLevel').GetValue(),
);

if (filteredData && filteredData.length > 0) {
return filteredData.reduce((lowestSublevel, current) => {
return current.Columns.SubLevelNumber.Value < lowestSublevel.Columns.SubLevelNumber.Value ? current : lowestSublevel;
});
}

return undefined;
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,18 +30,18 @@ import { Subscription } from 'rxjs';
import { TranslateService } from '@ngx-translate/core';

import { PwoExtendedData, ViewConfigData } from 'imx-api-qer';
import { ValType, ExtendedTypedEntityCollection, TypedEntity, EntitySchema, DataModel, EntityData } from 'imx-qbm-dbts';
import { DataModel, EntitySchema, ExtendedTypedEntityCollection, TypedEntity, ValType } from 'imx-qbm-dbts';
import {
DataSourceToolbarSettings,
ClassloggerService,
AuthenticationService,
BusyService,
ClassloggerService,
ClientPropertyForTableColumns,
ConfirmationService,
DataSourceToolbarSettings,
DataSourceToolbarViewConfig,
DataTableComponent,
SettingsService,
SnackBarService,
ClientPropertyForTableColumns,
BusyService,
DataSourceToolbarViewConfig,
ConfirmationService,
} from 'qbm';
import { ApprovalsSidesheetComponent } from '../approvals-sidesheet/approvals-sidesheet.component';
import { Approval } from '../approval';
Expand Down Expand Up @@ -124,7 +124,7 @@ export class InquiriesComponent implements OnInit, OnDestroy {
}
this.getData();
this.table.clearSelection();
})
}),
);
this.approvalsService.isChiefApproval = false;
this.subscriptions.push(authentication.onSessionResponse.subscribe((session) => (this.userUid = session.UserUid)));
Expand All @@ -139,7 +139,6 @@ export class InquiriesComponent implements OnInit, OnDestroy {
this.viewConfig = await this.viewConfigService.getInitialDSTExtension(this.dataModel, this.viewConfigPath);

await this.getData(undefined, true);

} finally {
isBusy.endBusy();
}
Expand All @@ -164,7 +163,6 @@ export class InquiriesComponent implements OnInit, OnDestroy {
try {
this.approvalsCollection = isInitialLoad ? { totalCount: 0, Data: [] } : await this.getDataFromService();
this.hasData = this.approvalsCollection?.totalCount > 0 || (this.navigationState.search ?? '') !== '';


this.updateTable();
} finally {
Expand All @@ -178,8 +176,8 @@ export class InquiriesComponent implements OnInit, OnDestroy {
*/
private async getDataFromService(): Promise<ExtendedTypedEntityCollection<Approval, PwoExtendedData>> {
const result = await this.approvalsService.get(this.navigationState);
if(this.uidHelperPwo && result.totalCount === 0 && !this.isInitialLoadedWithServer){
this.confirmation.confirm({Message: '#LDS#The request could not be found. You may not have permission to view this request.'});
if (this.uidHelperPwo && result.totalCount === 0 && !this.isInitialLoadedWithServer) {
this.confirmation.confirm({ Message: '#LDS#The request could not be found. You may not have permission to view this request.' });
}
// checks, if the data is loaded from the server for the first time
this.isInitialLoadedWithServer = true;
Expand Down Expand Up @@ -226,16 +224,6 @@ export class InquiriesComponent implements OnInit, OnDestroy {
}
}

public getInquiryText(pwo: Approval): string {
return this.getPwoData(pwo).Columns.ReasonHead.Value;
}
public getInquirer(pwo: Approval): string {
return this.getPwoData(pwo).Columns.DisplayPersonHead.Value;
}
public getQueryDate(pwo: Approval): Date {
return new Date(this.getPwoData(pwo).Columns.DateHead.Value);
}

public onSearch(keywords: string): Promise<void> {
const navigationState = {
...this.navigationState,
Expand All @@ -248,23 +236,14 @@ export class InquiriesComponent implements OnInit, OnDestroy {
return this.getData(navigationState);
}

private getPwoData(pwo: Approval): EntityData {
const questionHistory = pwo.pwoData.WorkflowHistory.Entities.filter(
(entityData) => entityData.Columns.DecisionLevel.Value === pwo.DecisionLevel.value
).sort((item1, item2) => this.ascendingDate(item1.Columns.XDateInserted?.Value, item2.Columns.XDateInserted?.Value));
return questionHistory[0];
public getInquiryText(pwo: Approval): string {
return this.actionService.getPwoData(pwo, this.userUid)?.Columns?.ReasonHead.Value || '';
}

private ascendingDate(value1: Date, value2: Date): number {
if (value1 < value2) {
return 1;
}

if (value1 > value2) {
return -1;
}

return 0;
public getInquirer(pwo: Approval): string {
return this.actionService.getPwoData(pwo, this.userUid)?.Columns?.DisplayPersonHead.Value || '';
}
public getQueryDate(pwo: Approval): string {
return this.actionService.getPwoData(pwo, this.userUid)?.Columns?.DateHead.Value ?? '';
}

private updateTable(): void {
Expand Down
Loading