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 @@
b32f3a9288588262ff652ef1fe639551d0cce92a
cd633f4378e2f09003301521206faa759b7dff9f
3 changes: 1 addition & 2 deletions .sync-history
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
8a5d78f15 2026-07-13 Merged PR 93367: 713184 - Web Portal: Optimize request history loading, optimize Pending Requests loading #713184
793ca3335 2026-07-08 Merged PR 94402: #724361 - ATT: Fix attestation grouping crash on undefined groupedData
cd633f437 2026-07-21 Merged PR 94742: #713400 - QER/ATT/CPL/POL: remove shared dashboard busy-state coupling in por...
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
### July 22, 2026
- 713400: Optimalized Web Portal Dashboard component widgets coupling

### July 13, 2026
- 713184: Optimizing request history and pending request loading (Need API update).
- 724361: Fixing pending attestation grouping.
Expand Down
Binary file modified imxweb/imx-modules/imx-api-qer.tgz
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
import { Component, OnInit } from '@angular/core';
import { Router } from '@angular/router';

import { DashboardService, PendingItemsType, UserModelService } from 'qer';
import { PendingItemsType, UserModelService } from 'qer';
import { AttestationFeatureGuardService } from '../attestation-feature-guard.service';

@Component({
Expand All @@ -40,24 +40,16 @@ export class DashboardPluginComponent implements OnInit {

constructor(
public readonly router: Router,
private readonly dashboardSvc: DashboardService,
private readonly userModelSvc: UserModelService,
private readonly attFeatureGuard: AttestationFeatureGuardService
) { }

public async ngOnInit(): Promise<void> {

const busy = this.dashboardSvc.beginBusy();

try {
this.pendingItems = await this.userModelSvc.getPendingItems();
this.attEnabled = (await this.attFeatureGuard.getAttestationConfig()).IsAttestationEnabled;
} finally {
busy.endBusy();
}
this.pendingItems = await this.userModelSvc.getPendingItems();
this.attEnabled = (await this.attFeatureGuard.getAttestationConfig()).IsAttestationEnabled;
}

public goToAttestationInquiries(): void {
this.router.navigate(['attestation', 'decision'], {queryParams: {inquiries:true}});
this.router.navigate(['attestation', 'decision'], { queryParams: { inquiries: true } });
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
import { Component, OnInit } from '@angular/core';
import { Router } from '@angular/router';

import { DashboardService, PendingItemsType, UserModelService } from 'qer';
import { PendingItemsType, UserModelService } from 'qer';
import { CplPermissionsService } from '../rules/admin/cpl-permissions.service';

@Component({
Expand All @@ -41,22 +41,14 @@ export class DashboardPluginComponent implements OnInit {

constructor(
public readonly router: Router,
private readonly dashboardService: DashboardService,
private readonly permissionService: CplPermissionsService,
private readonly userModelSvc: UserModelService
) { }

public async ngOnInit(): Promise<void> {

const busy = this.dashboardService.beginBusy();

try {
this.isExceptionAdmin = await this.permissionService.isExceptionAdmin();
if (this.isExceptionAdmin) {
this.pendingItems = await this.userModelSvc.getPendingItems();
}
} finally {
busy.endBusy();
this.isExceptionAdmin = await this.permissionService.isExceptionAdmin();
if (this.isExceptionAdmin) {
this.pendingItems = await this.userModelSvc.getPendingItems();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
import { Component, OnInit } from '@angular/core';
import { Router } from '@angular/router';

import { DashboardService, PendingItemsType, UserModelService } from 'qer';
import { PendingItemsType, UserModelService } from 'qer';

@Component({
templateUrl: './dashboard-plugin.component.html'
Expand All @@ -38,18 +38,10 @@ export class DashboardPluginComponent implements OnInit {

constructor(
public readonly router: Router,
private readonly dashboardService: DashboardService,
private readonly userModelSvc: UserModelService
) { }

public async ngOnInit(): Promise<void> {

const busy = this.dashboardService.beginBusy();

try {
this.pendingItems = await this.userModelSvc.getPendingItems();
} finally {
busy.endBusy();
}
this.pendingItems = await this.userModelSvc.getPendingItems();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ import { OverlayRef } from '@angular/cdk/overlay';
import { Injectable } from '@angular/core';
import { QerApiService } from '../qer-api-client.service';
import { EuiLoadingService } from '@elemental-ui/core';
import { CollectionLoadParameters, DataModel, DisplayColumns, EntitySchema, ExtendedTypedEntityCollection, TypedEntityBuilder, ValType } from 'imx-qbm-dbts';
import { PortalDevices, PortalRespTeamResponsibilities, ResponsibilitiesExtendedData } from 'imx-api-qer';
import { CollectionLoadParameters, DataModel, EntitySchema, ExtendedTypedEntityCollection, MethodDescriptor, TimeZoneInfo } from 'imx-qbm-dbts';
import { PortalRespTeamResponsibilities, ResponsibilitiesExtendedData } from 'imx-api-qer';

@Injectable({
providedIn: 'root',
Expand All @@ -40,7 +40,7 @@ export class TeamResponsibilitiesService {
constructor(
private readonly qerClient: QerApiService,
private readonly busyService: EuiLoadingService
) {}
) { }

public get responsibilitySchema(): EntitySchema {
return this.qerClient.typedClient.PortalRespTeamResponsibilities.GetSchema();
Expand All @@ -53,7 +53,7 @@ export class TeamResponsibilitiesService {
}

public handleCloseLoader(): void {
if(this.busyIndicator) {
if (this.busyIndicator) {
setTimeout(() => {
this.busyService.hide(this.busyIndicator);
this.busyIndicator = undefined;
Expand All @@ -69,8 +69,21 @@ export class TeamResponsibilitiesService {
return this.qerClient.client.portal_resp_team_responsibilities_datamodel_get();
}

public async countInactiveIdentity(): Promise<number>{
const responsibilities = await this.get({forinactive: '1', PageSize: -1})
return responsibilities.totalCount;
public async countInactiveIdentity(): Promise<number> {
return this.qerClient.apiClient.processRequest(this.getInactiveResponsibilitiesCountDescriptor());
}

private getInactiveResponsibilitiesCountDescriptor(): MethodDescriptor<number> {
return {
path: '/portal/resp/team/responsibilities/count',
method: 'GET',
parameters: [],
headers: {
'imx-timezone': TimeZoneInfo.get()
},
credentials: 'include',
observe: 'response',
responseType: 'json',
};
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,30 +28,24 @@ import { Component, OnInit } from '@angular/core';
import { TeamResponsibilitiesService } from '../team-responsibilities.service';
import { Router } from '@angular/router';
import { QerPermissionsService } from '../../admin/qer-permissions.service';
import { DashboardService } from '../../wport/start/dashboard.service';

@Component({
selector: 'imx-team-responsibility-tile',
templateUrl: './team-responsibility-tile.component.html',
})
export class TeamResponsibilityTileComponent implements OnInit {
public inactiveResponsibilitiesCount: number;

constructor(
private readonly teamResponsibilitiesService: TeamResponsibilitiesService,
public readonly router: Router,
private readonly qerPermissionsService: QerPermissionsService,
private readonly dashboardService: DashboardService
) {}
private readonly qerPermissionsService: QerPermissionsService
) { }

async ngOnInit(): Promise<void> {
const busy = this.dashboardService.beginBusy();
try{
const permission = await this.qerPermissionsService.isPersonManager();
if(permission){
this.inactiveResponsibilitiesCount = await this.teamResponsibilitiesService.countInactiveIdentity();
}
}finally{
busy.endBusy();
const permission = await this.qerPermissionsService.isPersonManager();
if (permission) {
this.inactiveResponsibilitiesCount = await this.teamResponsibilitiesService.countInactiveIdentity();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@ import { IdentitySidesheetComponent } from '../../identities/identity-sidesheet/
import { ProjectConfigurationService } from '../../project-configuration/project-configuration.service';
import { QerApiService } from '../../qer-api-client.service';
import { UserModelService } from '../../user/user-model.service';
import { DashboardService } from '../start/dashboard.service';
import { CreateNewIdentityComponent } from '../../identities/create-new-identity/create-new-identity.component';
import { IdentitiesService } from '../../identities/identities.service';

Expand All @@ -47,9 +46,7 @@ import { IdentitiesService } from '../../identities/identities.service';
export class BusinessOwnerChartSummaryComponent implements OnInit {
public reports: PortalPersonReports[];
public ownerships: OwnershipInformation[];
public get viewReady(): boolean {
return !this.dashboardService.isBusy;
}
public viewReady = false;
public allReportsCount: number;

private projectConfig: ProjectConfig;
Expand All @@ -58,18 +55,17 @@ export class BusinessOwnerChartSummaryComponent implements OnInit {
private readonly router: Router,
private readonly qerClient: QerApiService,
private readonly busyService: EuiLoadingService,
private readonly dashboardService: DashboardService,
private readonly sideSheet: EuiSidesheetService,
private readonly errorHandler: ErrorHandler,
private readonly configService: ProjectConfigurationService,
private readonly identitiesService: IdentitiesService,
private readonly userModelService: UserModelService,
public readonly qerPermissions: QerPermissionsService,
public readonly translate: TranslateService
) {}
) { }

public async ngOnInit(): Promise<void> {
const busy = this.dashboardService.beginBusy();
this.viewReady = false;
try {
const userConfig = await this.userModelService.getUserConfig();
this.ownerships = userConfig.Ownerships;
Expand All @@ -78,7 +74,7 @@ export class BusinessOwnerChartSummaryComponent implements OnInit {

await this.getData();
} finally {
busy.endBusy();
this.viewReady = true;
}
}

Expand Down Expand Up @@ -127,7 +123,7 @@ export class BusinessOwnerChartSummaryComponent implements OnInit {
}

public async openCreateNewIdentitySidesheet(): Promise<void> {
const identityCreated = await this.sideSheet.open(CreateNewIdentityComponent, {
const identityCreated = await this.sideSheet.open(CreateNewIdentityComponent, {
title: await this.translate.get('#LDS#Heading Create Identity').toPromise(),
headerColour: 'iris-blue',
padding: '0px',
Expand All @@ -142,21 +138,22 @@ export class BusinessOwnerChartSummaryComponent implements OnInit {
}).afterClosed().toPromise();

if (identityCreated) {
const busy = this.dashboardService.beginBusy();
this.viewReady = false;
try {
await this.getData();
} finally {
busy.endBusy();
this.viewReady = true;
}
} }
}
}

public openOwnership(ownerShip: OwnershipInformation): void {
this.router.navigate(['myresponsibilities', ownerShip.TableName]);
}

private async getData(): Promise<void> {
await this.loadIndirectOrDirectReports();
if (this.allReportsCount > 0 ) {
if (this.allReportsCount > 0) {
await this.loadDirectReports();
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import { Injectable } from "@angular/core";
import { BusyService } from "qbm";

/** @deprecated Use per-widget loading states instead of shared dashboard busy-state coupling. */
@Injectable({ providedIn: 'root' })
export class DashboardService extends BusyService {

Expand Down
Loading
Loading