diff --git a/.commit b/.commit index 285ac8d23..1781ec2d6 100644 --- a/.commit +++ b/.commit @@ -1 +1 @@ -456872c2445b89a895c65ea2b00cb819b33779b9 +9cea15b67ed3cf53ec30f75bf8e6a39cc233422b diff --git a/.sync-history b/.sync-history index a94356b10..e69de29bb 100644 --- a/.sync-history +++ b/.sync-history @@ -1 +0,0 @@ -a0b2454a2 2025-12-08 Merged PR 87103: #648563 - Fix create team role \ No newline at end of file diff --git a/imxweb/imx-modules/elemental-ui-cadence-icon-3.1.107.tgz b/imxweb/imx-modules/elemental-ui-cadence-icon-3.1.107.tgz new file mode 100644 index 000000000..41db7489e Binary files /dev/null and b/imxweb/imx-modules/elemental-ui-cadence-icon-3.1.107.tgz differ diff --git a/imxweb/imx-modules/elemental-ui-core-18.0.14.tgz b/imxweb/imx-modules/elemental-ui-core-18.0.14.tgz new file mode 100644 index 000000000..3b35826d9 Binary files /dev/null and b/imxweb/imx-modules/elemental-ui-core-18.0.14.tgz differ diff --git a/imxweb/imx-modules/imx-api-aad.tgz b/imxweb/imx-modules/imx-api-aad.tgz index 3c193c948..07663cb9a 100644 Binary files a/imxweb/imx-modules/imx-api-aad.tgz and b/imxweb/imx-modules/imx-api-aad.tgz differ diff --git a/imxweb/imx-modules/imx-api-aob.tgz b/imxweb/imx-modules/imx-api-aob.tgz index cf0a1e8ae..c5fffdb9b 100644 Binary files a/imxweb/imx-modules/imx-api-aob.tgz and b/imxweb/imx-modules/imx-api-aob.tgz differ diff --git a/imxweb/imx-modules/imx-api-apc.tgz b/imxweb/imx-modules/imx-api-apc.tgz index 39d7980bd..08caf51e5 100644 Binary files a/imxweb/imx-modules/imx-api-apc.tgz and b/imxweb/imx-modules/imx-api-apc.tgz differ diff --git a/imxweb/imx-modules/imx-api-att.tgz b/imxweb/imx-modules/imx-api-att.tgz index ba54a1b97..b5381c7b6 100644 Binary files a/imxweb/imx-modules/imx-api-att.tgz and b/imxweb/imx-modules/imx-api-att.tgz differ diff --git a/imxweb/imx-modules/imx-api-cpl.tgz b/imxweb/imx-modules/imx-api-cpl.tgz index b9f3eb337..ab97daab8 100644 Binary files a/imxweb/imx-modules/imx-api-cpl.tgz and b/imxweb/imx-modules/imx-api-cpl.tgz differ diff --git a/imxweb/imx-modules/imx-api-dpr.tgz b/imxweb/imx-modules/imx-api-dpr.tgz index 7b3aada39..20c663330 100644 Binary files a/imxweb/imx-modules/imx-api-dpr.tgz and b/imxweb/imx-modules/imx-api-dpr.tgz differ diff --git a/imxweb/imx-modules/imx-api-hds.tgz b/imxweb/imx-modules/imx-api-hds.tgz index a84b2779d..74899deb5 100644 Binary files a/imxweb/imx-modules/imx-api-hds.tgz and b/imxweb/imx-modules/imx-api-hds.tgz differ diff --git a/imxweb/imx-modules/imx-api-o3e.tgz b/imxweb/imx-modules/imx-api-o3e.tgz index 0bca2e2c9..ce2c03ad9 100644 Binary files a/imxweb/imx-modules/imx-api-o3e.tgz and b/imxweb/imx-modules/imx-api-o3e.tgz differ diff --git a/imxweb/imx-modules/imx-api-o3t.tgz b/imxweb/imx-modules/imx-api-o3t.tgz index 9cc83aad1..64b096ff8 100644 Binary files a/imxweb/imx-modules/imx-api-o3t.tgz and b/imxweb/imx-modules/imx-api-o3t.tgz differ diff --git a/imxweb/imx-modules/imx-api-olg.tgz b/imxweb/imx-modules/imx-api-olg.tgz index 23dd57e2d..1c146da2c 100644 Binary files a/imxweb/imx-modules/imx-api-olg.tgz and b/imxweb/imx-modules/imx-api-olg.tgz differ diff --git a/imxweb/imx-modules/imx-api-pol.tgz b/imxweb/imx-modules/imx-api-pol.tgz index 56b533ccc..e7ee62e7e 100644 Binary files a/imxweb/imx-modules/imx-api-pol.tgz and b/imxweb/imx-modules/imx-api-pol.tgz differ diff --git a/imxweb/imx-modules/imx-api-qbm.tgz b/imxweb/imx-modules/imx-api-qbm.tgz index 1c30ba7a4..83cb08a4e 100644 Binary files a/imxweb/imx-modules/imx-api-qbm.tgz and b/imxweb/imx-modules/imx-api-qbm.tgz differ diff --git a/imxweb/imx-modules/imx-api-qer.tgz b/imxweb/imx-modules/imx-api-qer.tgz index ee5245ab4..e77e1d20f 100644 Binary files a/imxweb/imx-modules/imx-api-qer.tgz and b/imxweb/imx-modules/imx-api-qer.tgz differ diff --git a/imxweb/imx-modules/imx-api-rmb.tgz b/imxweb/imx-modules/imx-api-rmb.tgz index dba8358ca..25f0f8dd3 100644 Binary files a/imxweb/imx-modules/imx-api-rmb.tgz and b/imxweb/imx-modules/imx-api-rmb.tgz differ diff --git a/imxweb/imx-modules/imx-api-rms.tgz b/imxweb/imx-modules/imx-api-rms.tgz index d9b962b17..77cadc4b6 100644 Binary files a/imxweb/imx-modules/imx-api-rms.tgz and b/imxweb/imx-modules/imx-api-rms.tgz differ diff --git a/imxweb/imx-modules/imx-api-rps.tgz b/imxweb/imx-modules/imx-api-rps.tgz index 5ee40683c..b9b55e857 100644 Binary files a/imxweb/imx-modules/imx-api-rps.tgz and b/imxweb/imx-modules/imx-api-rps.tgz differ diff --git a/imxweb/imx-modules/imx-api-sac.tgz b/imxweb/imx-modules/imx-api-sac.tgz index 0cfee9266..91ecf5923 100644 Binary files a/imxweb/imx-modules/imx-api-sac.tgz and b/imxweb/imx-modules/imx-api-sac.tgz differ diff --git a/imxweb/imx-modules/imx-api-tsb.tgz b/imxweb/imx-modules/imx-api-tsb.tgz index a676c566d..9b4befcc0 100644 Binary files a/imxweb/imx-modules/imx-api-tsb.tgz and b/imxweb/imx-modules/imx-api-tsb.tgz differ diff --git a/imxweb/imx-modules/imx-api-uci.tgz b/imxweb/imx-modules/imx-api-uci.tgz index ffa01c0e8..772954d02 100644 Binary files a/imxweb/imx-modules/imx-api-uci.tgz and b/imxweb/imx-modules/imx-api-uci.tgz differ diff --git a/imxweb/imx-modules/imx-api.tgz b/imxweb/imx-modules/imx-api.tgz index 5c25f5089..770d6074e 100644 Binary files a/imxweb/imx-modules/imx-api.tgz and b/imxweb/imx-modules/imx-api.tgz differ diff --git a/imxweb/imx-modules/imx-qbm-dbts.tgz b/imxweb/imx-modules/imx-qbm-dbts.tgz index 23fdad597..efae3cbcb 100644 Binary files a/imxweb/imx-modules/imx-qbm-dbts.tgz and b/imxweb/imx-modules/imx-qbm-dbts.tgz differ diff --git a/imxweb/projects/att/src/lib/attestation-history/attestation-history-details/attestation-history-details.component.html b/imxweb/projects/att/src/lib/attestation-history/attestation-history-details/attestation-history-details.component.html index 820dbaddc..849576400 100644 --- a/imxweb/projects/att/src/lib/attestation-history/attestation-history-details/attestation-history-details.component.html +++ b/imxweb/projects/att/src/lib/attestation-history/attestation-history-details/attestation-history-details.component.html @@ -22,6 +22,11 @@ +
  • + + {{ '#LDS#You do not have permission to view assigned attestors.' | translate }} + +
  • @@ -44,12 +49,12 @@ {{ '#LDS#Download report' | translate }} - - diff --git a/imxweb/projects/att/src/lib/attestation-history/attestation-history-details/attestation-history-details.component.scss b/imxweb/projects/att/src/lib/attestation-history/attestation-history-details/attestation-history-details.component.scss index 3d43f3536..bacfbb8f6 100644 --- a/imxweb/projects/att/src/lib/attestation-history/attestation-history-details/attestation-history-details.component.scss +++ b/imxweb/projects/att/src/lib/attestation-history/attestation-history-details/attestation-history-details.component.scss @@ -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; @@ -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 { @@ -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; + } + } } } @@ -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; + } + } } } diff --git a/imxweb/projects/att/src/lib/decision/attestation-case.component.html b/imxweb/projects/att/src/lib/decision/attestation-case.component.html index 09407ec5f..fa646945e 100644 --- a/imxweb/projects/att/src/lib/decision/attestation-case.component.html +++ b/imxweb/projects/att/src/lib/decision/attestation-case.component.html @@ -80,7 +80,7 @@ - +
    diff --git a/imxweb/projects/att/src/lib/decision/attestation-case.component.ts b/imxweb/projects/att/src/lib/decision/attestation-case.component.ts index 71cfcee1a..4c6626eb1 100644 --- a/imxweb/projects/att/src/lib/decision/attestation-case.component.ts +++ b/imxweb/projects/att/src/lib/decision/attestation-case.component.ts @@ -41,6 +41,7 @@ import { ColumnDependentReference, MetadataService, SnackBarService, + SqlWizardApiService, SystemInfoService, } from 'qbm'; import { @@ -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[] = []; @@ -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; @@ -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); } } @@ -243,7 +248,7 @@ export class AttestationCaseComponent implements OnDestroy, OnInit { ObjectKey: relatedObject.ObjectKey, Display: `${relatedObject.Display} - ${this.metadataService.tables[objectType.TableName].DisplaySingular}`, }; - }) + }), )) || []; } diff --git a/imxweb/projects/qer/src/lib/itshop/request-info/approver-container.ts b/imxweb/projects/qer/src/lib/itshop/request-info/approver-container.ts index ce79a1af4..9e8d77c2b 100644 --- a/imxweb/projects/qer/src/lib/itshop/request-info/approver-container.ts +++ b/imxweb/projects/qer/src/lib/itshop/request-info/approver-container.ts @@ -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; } diff --git a/imxweb/projects/qer/src/lib/itshopapprove/decision-step.service.ts b/imxweb/projects/qer/src/lib/itshopapprove/decision-step.service.ts index d78173576..ad762bcee 100644 --- a/imxweb/projects/qer/src/lib/itshopapprove/decision-step.service.ts +++ b/imxweb/projects/qer/src/lib/itshopapprove/decision-step.service.ts @@ -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)); } @@ -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; @@ -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 }; }, {}) ?? []; @@ -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; } diff --git a/imxweb/projects/qer/src/lib/itshopapprove/inquiries/inquiries.component.ts b/imxweb/projects/qer/src/lib/itshopapprove/inquiries/inquiries.component.ts index e2cdcffaa..98f6fcee7 100644 --- a/imxweb/projects/qer/src/lib/itshopapprove/inquiries/inquiries.component.ts +++ b/imxweb/projects/qer/src/lib/itshopapprove/inquiries/inquiries.component.ts @@ -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'; @@ -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))); @@ -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(); } @@ -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 { @@ -178,8 +176,8 @@ export class InquiriesComponent implements OnInit, OnDestroy { */ private async getDataFromService(): Promise> { 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; @@ -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 { const navigationState = { ...this.navigationState, @@ -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 { diff --git a/imxweb/projects/qer/src/lib/itshopapprove/workflow-action/workflow-action.service.ts b/imxweb/projects/qer/src/lib/itshopapprove/workflow-action/workflow-action.service.ts index 9c35848c8..561023c4c 100644 --- a/imxweb/projects/qer/src/lib/itshopapprove/workflow-action/workflow-action.service.ts +++ b/imxweb/projects/qer/src/lib/itshopapprove/workflow-action/workflow-action.service.ts @@ -64,7 +64,7 @@ export class WorkflowActionService { private readonly approvalsService: ApprovalsService, private readonly justificationService: JustificationService, private readonly userService: UserModelService, - private readonly extService: ExtService + private readonly extService: ExtService, ) {} public async directDecisions(requests: Approval[], userUid: string): Promise { @@ -89,7 +89,7 @@ export class WorkflowActionService { if (workFlowDataCollection && workFlowDataCollection.Data) { const levelNumbers = request.getLevelNumbers(userUid); workflow.data[request.key] = workFlowDataCollection.Data.filter((item) => levelNumbers.includes(item.LevelNumber.value)).map( - (item) => item.GetEntity() + (item) => item.GetEntity(), ); } } @@ -360,7 +360,7 @@ export class WorkflowActionService { Reason: actionParameters.reason.column.GetValue(), UidJustification: actionParameters.justification?.column?.GetValue(), Decision: true, - SubLevel: getSubLevel(request, request.pwoData, user,isEscalation), + SubLevel: getSubLevel(request, request.pwoData, user, isEscalation), }); }, }); @@ -487,22 +487,22 @@ export class WorkflowActionService { this.entityService.createLocalEntityColumn( { Type: ValType.Date, ColumnName: 'DateHead', Display: '#LDS#Inquiry made on' }, undefined, - pwo.Columns.DateHead - ) + pwo.Columns.DateHead, + ), ), new BaseReadonlyCdr( this.entityService.createLocalEntityColumn( { Type: ValType.String, ColumnName: 'ReasonHead', Display: '#LDS#Inquiry' }, undefined, - pwo.Columns.ReasonHead - ) + pwo.Columns.ReasonHead, + ), ), new BaseReadonlyCdr( this.entityService.createLocalEntityColumn( { Type: ValType.String, ColumnName: 'DisplayPersonHead', Display: '#LDS#Inquiry made by' }, undefined, - pwo.Columns.DisplayPersonHead - ) + pwo.Columns.DisplayPersonHead, + ), ), ]; @@ -518,13 +518,21 @@ export class WorkflowActionService { }); } - public getPwoData(pwo: Approval, userUid: string): EntityData { - return pwo.pwoData.WorkflowHistory.Entities.find( + public getPwoData(pwo: Approval, userUid: string): EntityData | undefined { + const questionHistory = pwo.pwoData.WorkflowHistory?.Entities?.filter( (entityData) => - entityData.Columns.DecisionType.Value === 'Query' && - entityData.Columns.UID_PersonRelated.Value === userUid && - entityData.Columns.DecisionLevel.Value === pwo.DecisionLevel.value - ); + entityData.Columns?.DecisionType.Value === 'Query' && + entityData.Columns?.UID_PersonRelated.Value === userUid && + entityData.Columns?.DecisionLevel.Value === pwo.DecisionLevel.value, + ).sort((a, b) => { + const d1 = a.Columns?.XDateInserted?.Value; + const d2 = b.Columns?.XDateInserted?.Value; + + if (!d1 || !d2) return 0; + // Sort descending + return new Date(d2).getTime() - new Date(d1).getTime(); + }); + return questionHistory?.[0]; } private async editAction(config: WorkflowActionEditWrapper): Promise { @@ -612,7 +620,7 @@ export class WorkflowActionService { FkRelation: fkRelation, MinLen: 1, }, - [this.person.createFkProviderItem(fkRelation)] + [this.person.createFkProviderItem(fkRelation)], ); return new BaseCdr(column, display); @@ -637,7 +645,7 @@ export class WorkflowActionService { this.person.createFkProviderItem(fkRelation, [ { ColumnName: 'UID_Person', CompareOp: CompareOperator.NotEqual, Type: FilterType.Compare, Value1: uidPerson }, ]), - ] + ], ); return new BaseCdr(column, '#LDS#Recipient of the inquiry'); @@ -646,13 +654,13 @@ export class WorkflowActionService { private async checkTermsOfUse(requests: Approval[]): Promise<{ isChecked: boolean; isAuthenticated: boolean }> { // get all cart items with terms of uses const approvalItemsWithTermsOfUseToAccept = requests.filter( - (item) => item.UID_QERTermsOfUse?.value !== null && item.UID_QERTermsOfUse?.value !== '' + (item) => item.UID_QERTermsOfUse?.value !== null && item.UID_QERTermsOfUse?.value !== '', ); if (approvalItemsWithTermsOfUseToAccept.length > 0) { this.logger.debug( this, - `There are ${approvalItemsWithTermsOfUseToAccept.length} service items with terms of use the user have to accepted.` + `There are ${approvalItemsWithTermsOfUseToAccept.length} service items with terms of use the user have to accepted.`, ); const termsOfUseAccepted = await this.sideSheet diff --git a/imxweb/projects/qer/src/lib/service-items-edit/service-items-edit-form/service-items-edit-form.component.html b/imxweb/projects/qer/src/lib/service-items-edit/service-items-edit-form/service-items-edit-form.component.html index f31f65050..548c086a0 100644 --- a/imxweb/projects/qer/src/lib/service-items-edit/service-items-edit-form/service-items-edit-form.component.html +++ b/imxweb/projects/qer/src/lib/service-items-edit/service-items-edit-form/service-items-edit-form.component.html @@ -14,7 +14,7 @@ diff --git a/imxweb/projects/qer/src/lib/service-items-edit/service-items-edit-form/service-items-edit-form.component.ts b/imxweb/projects/qer/src/lib/service-items-edit/service-items-edit-form/service-items-edit-form.component.ts index 7b41bf7d5..8462055a2 100644 --- a/imxweb/projects/qer/src/lib/service-items-edit/service-items-edit-form/service-items-edit-form.component.ts +++ b/imxweb/projects/qer/src/lib/service-items-edit/service-items-edit-form/service-items-edit-form.component.ts @@ -35,7 +35,7 @@ import { MatSlideToggleChange } from '@angular/material/slide-toggle'; import { TranslateService } from '@ngx-translate/core'; import { IEntity, IEntityColumn, TypedEntity } from 'imx-qbm-dbts'; -import { BaseCdr, ClassloggerService, ColumnDependentReference, CdrFactoryService, ExtService, BusyService } from 'qbm'; +import { BaseCdr, BusyService, CdrFactoryService, ClassloggerService, ColumnDependentReference, ExtService } from 'qbm'; import { QerPermissionsService } from '../../admin/qer-permissions.service'; import { OwnerControlComponent } from '../../owner-control/owner-control.component'; import { ProjectConfigurationService } from '../../project-configuration/project-configuration.service'; @@ -90,8 +90,8 @@ export class ServiceItemsEditFormComponent implements OnInit, OnChanges { private readonly translate: TranslateService, private readonly permission: QerPermissionsService, private readonly projectConfig: ProjectConfigurationService, - private readonly cdrFactoryService: CdrFactoryService - ) {} + private readonly cdrFactoryService: CdrFactoryService, + ) { } get getSelectedUidPerson(): string { return this.ownercontrol?.uidPersonSelected; @@ -187,7 +187,11 @@ export class ServiceItemsEditFormComponent implements OnInit, OnChanges { // Handle the requestable (IsInActive column) outside the context of a CDR editor so the UI can invert the meaning to make // more sense to the user // This should be inversed on the api data response at some point, but until then we handle it in the UI - this.isInActiveFormControl.setValue(!this.getColumn('IsInActive')?.GetValue()); + const isInActiveColumn = this.getColumn('IsInActive'); + this.isInActiveFormControl.setValue(!isInActiveColumn?.GetValue()); + isInActiveColumn?.GetMetadata().CanEdit() + ? this.isInActiveFormControl.enable({ emitEvent: false }) + : this.isInActiveFormControl.disable({ emitEvent: false }); this.onFormControlCreated(this.isInActiveFormControl); } diff --git a/imxweb/projects/rps/src/lib/list-report-viewer/list-report-viewer.component.ts b/imxweb/projects/rps/src/lib/list-report-viewer/list-report-viewer.component.ts index 15f7aabde..d592a18fc 100644 --- a/imxweb/projects/rps/src/lib/list-report-viewer/list-report-viewer.component.ts +++ b/imxweb/projects/rps/src/lib/list-report-viewer/list-report-viewer.component.ts @@ -27,7 +27,14 @@ import { Component, Input, OnInit } from '@angular/core'; import { CollectionLoadParameters, DataModel, DisplayColumns, EntitySchema } from 'imx-qbm-dbts'; -import { BusyService, ClassloggerService, DataSourceToolbarGroupData, DataSourceToolbarSettings, createGroupData } from 'qbm'; +import { + BusyService, + ClassloggerService, + DataSourceToolbarExportMethod, + DataSourceToolbarGroupData, + DataSourceToolbarSettings, + createGroupData, +} from 'qbm'; import { ListReportDataProvider } from './list-report-data-provider.interface'; /** @@ -136,8 +143,11 @@ export class ListReportViewerComponent implements OnInit { this.logger.warn(this, 'There was a problem, loading the columns. The displays of the objects will be shown instead'); } - const exportMethod = this.dataService.exportReports(this.navigationState); - exportMethod.initialColumns = displayedColumns.map((col) => col.ColumnName); + let exportMethod: DataSourceToolbarExportMethod | undefined; + if (this.dataService.exportReports) { + exportMethod = this.dataService.exportReports(this.navigationState); + exportMethod.initialColumns = displayedColumns.map((col) => col.ColumnName); + } this.dstSettings = { dataSource: data, @@ -186,7 +196,7 @@ export class ListReportViewerComponent implements OnInit { }, ...parameters, }), - [] + [], ); } }