Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PRIME-2769 Archive Site #2610

Merged
merged 17 commits into from
Nov 5, 2024
Original file line number Diff line number Diff line change
Expand Up @@ -606,4 +606,37 @@ export class SiteResource {
})
);
}

public archiveSite(siteId: number, note: string): NoContent {
return this.apiResource.post<NoContent>(`sites/${siteId}/archive`, { note })
.pipe(
NoContentResponse,
catchError((error: any) => {
this.logger.error('[SiteRegistration] SiteResource::archiveSite error has occurred: ', error);
throw error;
})
);
}

public restoreArchivedSite(siteId: number, note: string): NoContent {
return this.apiResource.post<NoContent>(`sites/${siteId}/restore`, { note })
.pipe(
NoContentResponse,
catchError((error: any) => {
this.logger.error('[SiteRegistration] SiteResource::restoreArchivedSite error has occurred: ', error);
throw error;
})
);
}

public canRestoreSite(siteId: number): Observable<boolean> {
return this.apiResource.get<boolean>(`sites/${siteId}/can-restore`)
.pipe(
map((response: ApiHttpResponse<boolean>) => response.result),
catchError((error: any) => {
this.logger.error('[SiteRegistration] SiteResource::canRestoreSite error has occurred: ', error);
throw error;
})
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,7 @@ export enum SiteAdjudicationAction {
REQUEST_CHANGES = 1,
APPROVE = 2,
REJECT = 3,
UNREJECT = 4
UNREJECT = 4,
ARCHIVE = 7,
RESTORE = 8,
}
3 changes: 2 additions & 1 deletion prime-angular-frontend/src/app/lib/enums/site-status.enum.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,6 @@ export enum SiteStatusType {
IN_REVIEW = 2,
LOCKED = 3,
EDITABLE_NOT_APPROVED = 4,
FLAGGED = 5
FLAGGED = 5,
ARCHIVED = 8,
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import { SiteRegistrationNote } from '@shared/models/site-registration-note.mode

import { AdjudicationRoutes } from '@adjudication/adjudication.routes';
import { AdjudicationResource } from '../services/adjudication-resource.service';
import { SiteActionEnum, SiteArchiveRestoreComponent } from '@shared/components/dialogs/content/site-archive-restore/site-archive-restore.component';

export abstract class AbstractSiteAdminPage {
public abstract busy: Subscription;
Expand Down Expand Up @@ -198,7 +199,7 @@ export abstract class AbstractSiteAdminPage {
message: 'Are you sure you want to reject this Site Registration?',
actionText: 'Reject Site Registration',
actionType: 'warn',
component: NoteComponent
component: NoteComponent,
};

this.busy = this.dialog.open(ConfirmDialogComponent, { data })
Expand All @@ -225,6 +226,54 @@ export abstract class AbstractSiteAdminPage {
.subscribe(() => this.onRefresh());
}

public onArchive(siteId: number): void {
const data: DialogOptions = {
data: {
siteId: siteId,
action: SiteActionEnum.Archive,
}
};

this.busy = this.dialog.open(SiteArchiveRestoreComponent, { data })
.afterClosed()
.subscribe((result: { reload: boolean }) => (result?.reload) ?
this.getDataset(this.route.snapshot.queryParams) : noop);
}

public onRestore(siteId: number): void {

this.siteResource.canRestoreSite(siteId)
.subscribe((value: boolean) => {

if (value) {
const data: DialogOptions = {
data: {
siteId: siteId,
action: SiteActionEnum.Restore,
}
};

this.busy = this.dialog.open(SiteArchiveRestoreComponent, { data })
.afterClosed()
.subscribe((result: { reload: boolean }) => (result?.reload) ?
this.getDataset(this.route.snapshot.queryParams) : noop);

} else {
const data: DialogOptions = {
title: 'Restore Archived Site',
message: 'Site ID has been used in a different site. This Site can\'t be restored.',
cancelText: "Close",
actionType: 'warn',
actionHide: true
};

this.dialog.open(ConfirmDialogComponent, { data })
.afterClosed()
.subscribe();
}
});
}

public onEnableEditing(siteId: number): void {
this.busy = this.siteResource.enableEditingSite(siteId)
.subscribe(() => this.onRefresh());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,9 @@
(escalate)="onEscalate($event)"
(enableEditing)="onEnableEditing($event)"
(flag)="onToggleFlagSite($event)"
(delete)="deleteSite($event)">
(delete)="deleteSite($event)"
(archive)="onArchive($event)"
(restore)="onRestore($event)">
</app-site-registration-actions>

</ng-template>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@
[class.editable]="row.status === SiteStatusType.EDITABLE && !row.approvedDate"
[class.under-review]="row.status === SiteStatusType.IN_REVIEW"
[class.approved]="row.status === SiteStatusType.EDITABLE && !!row.approvedDate"
[class.declined]="row.status === SiteStatusType.LOCKED">
[class.declined]="row.status === SiteStatusType.LOCKED || row.status === SiteStatusType.ARCHIVED">
<div class="d-flex align-items-center">
<span class="mr-1">{{ SiteStatusType[row.status] | case : 'snake' : 'space' | capitalize : true | default: 'Editable' }}</span>
<mat-icon *ngIf="row?.flagged"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,23 @@
<mat-icon>flag</mat-icon>
<span>{{siteRegistration?.isNew ? 'Unflag' : 'Flag'}} "Is New"</span>
</button>

<button mat-menu-item
[disabled]="!(Role.SUPER_ADMIN | inRole)"
*ngIf="isActionAllowed(SiteAdjudicationAction.ARCHIVE)"
(click)="onArchive()">
<mat-icon>archive</mat-icon>
<span>Archive Site</span>
</button>

<button mat-menu-item
[disabled]="!(Role.SUPER_ADMIN | inRole)"
*ngIf="isActionAllowed(SiteAdjudicationAction.RESTORE)"
(click)="onRestore()">
<mat-icon>unarchive</mat-icon>
<span>Restore Site</span>
</button>

<mat-divider></mat-divider>

<button mat-menu-item
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ export class SiteRegistrationActionsComponent implements OnInit {
@Output() public reject: EventEmitter<number>;
@Output() public unreject: EventEmitter<number>;
@Output() public escalate: EventEmitter<number>;
@Output() public archive: EventEmitter<number>;
@Output() public restore: EventEmitter<number>;
@Output() public delete: EventEmitter<{ [key: string]: number }>;
@Output() public enableEditing: EventEmitter<number>;
@Output() public flag: EventEmitter<{ siteId: number, flagged: boolean }>;
Expand All @@ -41,6 +43,8 @@ export class SiteRegistrationActionsComponent implements OnInit {
this.reject = new EventEmitter<number>();
this.unreject = new EventEmitter<number>();
this.escalate = new EventEmitter<number>();
this.archive = new EventEmitter<number>();
this.restore = new EventEmitter<number>();
this.enableEditing = new EventEmitter<number>();
this.flag = new EventEmitter<{ siteId: number, flagged: boolean }>();
this.isNew = new EventEmitter<{ siteId: number, isNew: boolean }>();
Expand Down Expand Up @@ -82,6 +86,14 @@ export class SiteRegistrationActionsComponent implements OnInit {
}
}

public onArchive() {
this.archive.emit(this.siteRegistration.id);
}

public onRestore() {
this.restore.emit(this.siteRegistration.id);
}

public onContactSigningAuthority() {
const site = this.siteRegistration as SiteRegistrationListViewModel;
const signingAuthority = site.signingAuthority;
Expand Down Expand Up @@ -161,13 +173,17 @@ export class SiteRegistrationActionsComponent implements OnInit {
public isActionAllowed(action: SiteAdjudicationAction): boolean {
switch (this.siteRegistration.status) {
case SiteStatusType.EDITABLE:
return (action === SiteAdjudicationAction.REJECT);
return (action === SiteAdjudicationAction.REJECT
|| action === SiteAdjudicationAction.ARCHIVE);
case SiteStatusType.IN_REVIEW:
return (action === SiteAdjudicationAction.REQUEST_CHANGES
|| action === SiteAdjudicationAction.APPROVE
|| action === SiteAdjudicationAction.REJECT);
|| action === SiteAdjudicationAction.REJECT
|| action === SiteAdjudicationAction.ARCHIVE);
case SiteStatusType.LOCKED:
return (action === SiteAdjudicationAction.UNREJECT);
case SiteStatusType.ARCHIVED:
return (action === SiteAdjudicationAction.RESTORE);
default:
return false;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@
(delete)="onDelete($event)"
(unreject)="onUnreject($event)"
(escalate)="onEscalate($event)"
(archive)="onArchive($event)"
(restore)="onRestore($event)"
(enableEditing)="onEnableEditing($event)"
(flag)="onToggleFlagSite($event)"
(isNew)="onToggleIsNewSite($event)">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,7 @@ export class SiteRegistrationContainerComponent extends AbstractSiteAdminPage im
signingAuthority,
signingAuthorityName: `${signingAuthority.firstName ? signingAuthority.firstName : ''} ${signingAuthority.lastName}`,
organizationName: name,
duplicatePecSiteCount: 0,
name,
organizationDoingBusinessAs: doingBusinessAs,
hasClaim,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@
[class.editable]="row.status === SiteStatusType.EDITABLE && !row.approvedDate"
[class.under-review]="row.status === SiteStatusType.IN_REVIEW"
[class.approved]="row.status === SiteStatusType.EDITABLE && !!row.approvedDate"
[class.declined]="row.status === SiteStatusType.LOCKED">
[class.declined]="row.status === SiteStatusType.LOCKED || row.status === SiteStatusType.ARCHIVED">
<div class="d-flex align-items-center">
<span class="mr-1">{{ SiteStatusType[row.status] | case : 'snake' : 'space' | capitalize : true | default: 'Editable' }}</span>
<mat-icon *ngIf="row?.flagged"
Expand All @@ -109,7 +109,17 @@
*matHeaderCellDef
scope="col"> Site ID </th>
<td mat-cell
*matCellDef="let row;"> {{ row.pec | default }} </td>
*matCellDef="let row;">
<div class="d-flex align-items-center">
{{ row.pec | default }}
<mat-icon *ngIf="row?.duplicatePecSiteCount && row?.duplicatePecSiteCount > 0"
[matTooltip]="getDuplicatePecText(row)"
class="pec-alert"
(click)="onPecFilter(row.pec)"
matTooltipPosition="after">info
</mat-icon>
</div>
</td>
</ng-container>

<ng-container matColumnDef="remoteUsers">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,15 @@
.red {
color: orangered;
}

.pec-alert {
color: theme-palette(yellow);
font-size: large;
}

.prefix-container {
height: 48px;
width: 24px;
padding-top: 3px;
padding-bottom: 3px;
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ export class SiteRegistrationTableComponent implements OnInit, AfterViewInit {
@Output() public notify: EventEmitter<{ siteId: number }>;
@Output() public reload: EventEmitter<number>;
@Output() public route: EventEmitter<string | (string | number)[]>;
@Output() public pecFilter: EventEmitter<string>;

@ViewChild(MatPaginator, { static: true }) public paginator: MatPaginator;
@ViewChild('secondaryPaginator', { static: true }) public secondaryPaginator: MatPaginator;
Expand Down Expand Up @@ -71,7 +72,7 @@ export class SiteRegistrationTableComponent implements OnInit, AfterViewInit {
this.reload = new EventEmitter<number>();
this.route = new EventEmitter<string | (string | number)[]>();
this.routeUtils = new RouteUtils(activatedRoute, router, AdjudicationRoutes.routePath(AdjudicationRoutes.SITE_REGISTRATIONS));

this.pecFilter = new EventEmitter<string>();
}

public onAssign(siteId: number): void {
Expand Down Expand Up @@ -172,6 +173,14 @@ export class SiteRegistrationTableComponent implements OnInit, AfterViewInit {
}
});
}

public getDuplicatePecText(row: SiteRegistrationListViewModel) {
return `${row.duplicatePecSiteCount + 1} sites share the same site ID`;
}

public onPecFilter(pec: string) {
this.pecFilter.emit(pec);
}
}


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@
[id]="CareSettingEnum.HEALTH_AUTHORITY">
<ng-template matTabContent>
<div class="mt-3">
<app-search-ha-form #searchHaForm
<app-search-ha-form #searchHaSiteForm
(search)="onSearch($event)"
(siteStatus)="onSiteStatusChange($event)"
(vendor)="onVendorChange($event)"
Expand All @@ -57,7 +57,7 @@
(notify)="onNotify($event)"
(route)="onRoute($event)"
(reload)="onRefresh()"
(pecFilter)="onTextSearch($event)"></app-health-authority-table>
(pecFilter)="onTextSearchHaSite($event)"></app-health-authority-table>
</div>
</ng-template>
</mat-tab>
Expand All @@ -67,7 +67,8 @@
let-columns="columns"
let-localStoragePrefix="localStoragePrefix">
<div class="mt-3">
<app-search-form *ngIf="showSearchFilter"
<app-search-form #searchComSiteForm
*ngIf="showSearchFilter"
[hideStatus]="false"
[statusType]="SearchFormStatusType.SiteStatuses"
[localStoragePrefix]="localStoragePrefix"
Expand All @@ -84,6 +85,7 @@
(reassign)="onReassign($event)"
(notify)="onNotify($event)"
(route)="onRoute($event)"
(reload)="onRefresh()"></app-site-registration-table>
(reload)="onRefresh()"
(pecFilter)="onTextSearchComSite($event)"></app-site-registration-table>
</ng-template>
</app-page>
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@ import { SearchHAFormComponent } from '../search-ha-form/search-ha-form.componen
export class SiteRegistrationTabsComponent extends AbstractSiteAdminPage implements OnInit {
public busy: Subscription;
@Input() public refresh: Observable<boolean>;
@ViewChild('searchHaForm') searchHaForm: SearchHAFormComponent;
@ViewChild('searchHaSiteForm') searchHaSiteForm: SearchHAFormComponent;
@ViewChild('searchComSiteForm') searchComSiteForm: SearchHAFormComponent;

public dataSource: MatTableDataSource<SiteRegistrationListViewModel>;
public healthAuthoritySites: HealthAuthoritySiteAdminList[];
Expand Down Expand Up @@ -129,9 +130,14 @@ export class SiteRegistrationTabsComponent extends AbstractSiteAdminPage impleme
this.routeUtils.removeQueryParams({ careSetting: this.tabIndexToCareSettingMap[tabChangeEvent.index], page: null });
}

public onTextSearch(textSearch: string | null): void {
public onTextSearchHaSite(textSearch: string | null): void {
this.routeUtils.updateQueryParams({ textSearch, page: null });
this.searchHaForm.textSearch.setValue(textSearch);
this.searchHaSiteForm.textSearch.setValue(textSearch);
}

public onTextSearchComSite(textSearch: string | null): void {
this.routeUtils.updateQueryParams({ textSearch, page: null });
this.searchComSiteForm.textSearch.setValue(textSearch);
}

public ngOnInit(): void {
Expand Down Expand Up @@ -175,6 +181,10 @@ export class SiteRegistrationTabsComponent extends AbstractSiteAdminPage impleme
} else {
this.busy = this.getPaginatedSites({ careSettingCode, ...queryParams })
.subscribe((paginatedList: PaginatedList<SiteRegistrationListViewModel>) => {
paginatedList.results.forEach((s: SiteRegistrationListViewModel) => {
s.duplicatePecSiteCount = paginatedList.results.filter((innerSite: SiteRegistrationListViewModel) => innerSite.id !== s.id
&& innerSite.pec && innerSite.pec === s.pec).length;
});
this.dataSource.data = paginatedList.results;
this.pagination = paginatedList;
});
Expand Down
Loading
Loading