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-2299 Close a site #2595

Open
wants to merge 11 commits into
base: develop
Choose a base branch
from
1 change: 1 addition & 0 deletions prime-angular-frontend/src/app/config/config.model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ export interface Configuration {
securityGroups: Config<number>[];
collegeLicenseGroupings: CollegeLicenseGroupingConfig[];
deviceProviderRoles: DeviceProviderRoleConfig[];
siteCloseReasons: Config<number>[];
}

export class Config<T> {
Expand Down
5 changes: 5 additions & 0 deletions prime-angular-frontend/src/app/config/config.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,11 @@ export class ConfigService implements IConfigService {
.sort(this.utilsService.sortByKey<DeviceProviderRoleConfig>('weight'));
}

public get siteCloseReasons(): Config<number>[] {
return [...this.configuration.siteCloseReasons]
.sort(this.utilsService.sortByKey<Config<number>>('name'));
}

/**
* @description
* Load the runtime configuration.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -606,4 +606,26 @@ export class SiteResource {
})
);
}

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

public openSite(siteId: number, note: string): NoContent {
return this.apiResource.post<NoContent>(`sites/${siteId}/open`, { note })
.pipe(
NoContentResponse,
catchError((error: any) => {
this.logger.error('[SiteRegistration] SiteResource::openSite 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,
CLOSE = 7,
OPEN = 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,
CLOSED = 7,
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ import { SiteRegistrationNote } from '@shared/models/site-registration-note.mode

import { AdjudicationRoutes } from '@adjudication/adjudication.routes';
import { AdjudicationResource } from '../services/adjudication-resource.service';
import { CloseSiteComponent } from '@shared/components/dialogs/content/close-site-note/close-site-note.component';
import { OpenSiteNoteComponent } from '@shared/components/dialogs/content/open-site-note/open-site-note.component';

export abstract class AbstractSiteAdminPage {
public abstract busy: Subscription;
Expand Down Expand Up @@ -225,6 +227,35 @@ export abstract class AbstractSiteAdminPage {
.subscribe(() => this.onRefresh());
}

public onClose(siteId: number): void {
const data: DialogOptions = {
title: 'Close a Site',
actionText: 'Close Site',
actionType: 'warn',
data: {
siteId: siteId,
}
};

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

public onOpen(siteId: number): void {

const data: DialogOptions = {
title: 'Open a Closed Site',
actionText: 'Open Site',
actionType: 'warn',
data: {
siteId: siteId,
}
};

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

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 @@ -42,6 +42,8 @@
(unreject)="onUnreject($event)"
(escalate)="onEscalate($event)"
(enableEditing)="onEnableEditing($event)"
(close)="onClose($event)"
(open)="onOpen($event)"
(flag)="onToggleFlagSite($event)"
(delete)="deleteSite($event)">
</app-site-registration-actions>
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.CLOSED">
<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,22 @@
<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.CLOSE)"
(click)="onClose()">
<mat-icon>close</mat-icon>
<span>Close Site</span>
</button>

<button mat-menu-item
[disabled]="!(Role.SUPER_ADMIN | inRole)"
*ngIf="isActionAllowed(SiteAdjudicationAction.OPEN)"
(click)="onOpen()">
<mat-icon>folder_open</mat-icon>
<span>Open Site</span>
</button>
<mat-divider></mat-divider>

<button mat-menu-item
Expand All @@ -89,7 +105,6 @@
<span>Delete Organization</span>
</button>
</ng-container>

</mat-menu>

</ng-container>
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ export class SiteRegistrationActionsComponent implements OnInit {
@Output() public unreject: EventEmitter<number>;
@Output() public escalate: EventEmitter<number>;
@Output() public delete: EventEmitter<{ [key: string]: number }>;
@Output() public close: EventEmitter<number>;
@Output() public open: EventEmitter<number>;
@Output() public enableEditing: EventEmitter<number>;
@Output() public flag: EventEmitter<{ siteId: number, flagged: boolean }>;
@Output() public isNew: EventEmitter<{ siteId: number, isNew: boolean }>;
Expand All @@ -42,6 +44,8 @@ export class SiteRegistrationActionsComponent implements OnInit {
this.unreject = new EventEmitter<number>();
this.escalate = new EventEmitter<number>();
this.enableEditing = new EventEmitter<number>();
this.close = new EventEmitter<number>();
this.open = new EventEmitter<number>();
this.flag = new EventEmitter<{ siteId: number, flagged: boolean }>();
this.isNew = new EventEmitter<{ siteId: number, isNew: boolean }>();
}
Expand Down Expand Up @@ -153,6 +157,14 @@ export class SiteRegistrationActionsComponent implements OnInit {
}
}

public onClose() {
this.close.emit(this.siteRegistration.id);
}

public onOpen() {
this.open.emit(this.siteRegistration.id);
}

/**
* @description
* Check whether the given action is valid according to the status of the
Expand All @@ -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.CLOSE);
case SiteStatusType.IN_REVIEW:
return (action === SiteAdjudicationAction.REQUEST_CHANGES
|| action === SiteAdjudicationAction.APPROVE
|| action === SiteAdjudicationAction.REJECT);
|| action === SiteAdjudicationAction.REJECT
|| action === SiteAdjudicationAction.CLOSE);
case SiteStatusType.LOCKED:
return (action === SiteAdjudicationAction.UNREJECT);
case SiteStatusType.CLOSED:
return (action === SiteAdjudicationAction.OPEN)
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)"
(close)="onClose($event)"
(open)="onOpen($event)"
(enableEditing)="onEnableEditing($event)"
(flag)="onToggleFlagSite($event)"
(isNew)="onToggleIsNewSite($event)">
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.CLOSED">
<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 @@ -81,7 +81,7 @@
{ key: 'Vendor', value: healthAuthoritySite?.healthAuthorityVendor?.vendorCode | configCode : 'vendors', _50: true },
{ key: healthAuthoritySite?.submittedDate ? 'Last Submitted by' : 'Last Updated by', value: getLastUpdatedUser(healthAuthoritySite?.authorizedUserName, healthAuthoritySite?.updatedTimeStamp)},
]">
<ng-container *ngIf="healthAuthoritySite.isIncomplete()"
<ng-container *ngIf="healthAuthoritySite.isIncomplete() && !healthAuthoritySite.isClosed()"
[ngTemplateOutlet]="notification"
[ngTemplateOutletContext]="{
props: {
Expand Down Expand Up @@ -110,6 +110,15 @@
}
}">
</ng-container>
<ng-container *ngIf="healthAuthoritySite.isClosed()"
[ngTemplateOutlet]="notification"
[ngTemplateOutletContext]="{
props: {
icon: 'not_interested',
text: 'Closed'
}
}">
</ng-container>
<ng-container *ngIf="healthAuthoritySite.isApproved() && !healthAuthoritySite.withinRenewalPeriod()"
[ngTemplateOutlet]="success_notification"
[ngTemplateOutletContext]="{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@ export class HealthAuthoritySiteUtils {
return healthAuthoritySite.status === SiteStatusType.LOCKED;
}

public static isClosed(healthAuthoritySite: BaseHealthAuthoritySite): boolean {
return healthAuthoritySite.status === SiteStatusType.CLOSED;
}

public static isApproved(healthAuthoritySite: BaseHealthAuthoritySite): boolean {
return healthAuthoritySite.status === SiteStatusType.EDITABLE
&& !!healthAuthoritySite.approvedDate;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@ export abstract class AbstractBaseHealthAuthoritySite implements BaseHealthAutho
return HealthAuthoritySiteUtils.isLocked(this);
}

public isClosed(): boolean {
return HealthAuthoritySiteUtils.isClosed(this);
}

public isApproved(): boolean {
return HealthAuthoritySiteUtils.isApproved(this);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,15 @@
}
}">
</ng-container>
<ng-container *ngIf="isClosed(site)"
[ngTemplateOutlet]="notification"
[ngTemplateOutletContext]="{
props: {
icon: 'not_interested',
text: 'Closed'
}
}">
</ng-container>
<ng-container *ngIf="isApproved(site) && !requiresRenewal(site)"
[ngTemplateOutlet]="success_notification"
[ngTemplateOutletContext]="{
Expand Down Expand Up @@ -221,7 +230,7 @@
</button>
<button *ngIf="site.careSettingCode === CareSettingEnum.PRIVATE_COMMUNITY_HEALTH_PRACTICE"
mat-menu-item
[disabled]="!site.completed || site.status === SiteStatusType.IN_REVIEW"
[disabled]="!site.completed || site.status === SiteStatusType.IN_REVIEW || site.status === SiteStatusType.CLOSED"
(click)="viewSiteRemoteUsers(organizationId, site)">
<span>View/Update Remote Practitioners</span>
</button>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,10 @@ export class SiteManagementPageComponent implements OnInit {
return site.status === SiteStatusType.LOCKED;
}

public isClosed(site: SiteListViewModel): boolean {
return site.status === SiteStatusType.CLOSED;
}

public getLockedSiteNotificationProperties() {
return {
icon: 'not_interested',
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
<h2 mat-dialog-title
class="d-flex align-items-stretch">
<mat-icon color="warn">warning</mat-icon>
<span class="flex-grow-1">
Close a Site
</span>
</h2>
<mat-dialog-content>
<p>
Please select a close reason.
</p>
<form [formGroup]="form">
<mat-form-field class="w-100">
<mat-label>Close Reason</mat-label>
<mat-select formControlName="siteCloseReason">
<mat-option *ngFor="let siteCloseReasonCode of siteCloseReasons"
[value]="siteCloseReasonCode.code">
{{ siteCloseReasonCode.name }}
</mat-option>
</mat-select>
<mat-error *ngIf="siteCloseReason.hasError('required')">Required</mat-error>
</mat-form-field>
<mat-form-field class="w-100">
<textarea matInput
placeholder="Note"
rows="10"
formControlName="note"></textarea>
<mat-error *ngIf="note.hasError('required')">Required</mat-error>
</mat-form-field>
</form>
<div class="mt-4">
<div class="row">
<div class="col-6">
<button mat-stroked-button
(click)="onCancel()"
class="my-2 mr-2">Cancel</button>
</div>
<div class="col-6 text-right">
<button mat-flat-button
(click)="onCloseSite()"
color="warn"
class="my-2 mr-1">Close Site</button>
</div>
</div>
</div>
</mat-dialog-content>
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
@import 'palette';
@import 'bootstrap/bootstrap-imports';

h2 {
color: theme-palette(blue);

.mat-icon {
font-size: 3rem;
}

img,
.mat-icon {
margin-right: 15px;
width: 50px;
height: 50px;
}

span {
border-bottom: 1px solid #eeee;
font-size: 1.75rem;
line-height: 3rem;
}
}
Loading
Loading