Skip to content
Open
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
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