diff --git a/ui/src/app/modules/laboratory/laboratory.component.html b/ui/src/app/modules/laboratory/laboratory.component.html index 5f36d2166..e2f59dd21 100644 --- a/ui/src/app/modules/laboratory/laboratory.component.html +++ b/ui/src/app/modules/laboratory/laboratory.component.html @@ -44,30 +44,216 @@ params?.loadedSystemSettings " > - <div - [ngClass]="{ - 'col-2': params?.LISConfigurations?.isLIS && showMenuItems, - 'col-12': !params?.LISConfigurations?.isLIS - }" - *ngIf="showMenuItems" - class="laboratory-header mat-elevation-z1" - [ngStyle]="{ - height: params?.LISConfigurations?.isLIS ? '95vh' : 'auto', - 'margin-top': params?.LISConfigurations?.isLIS ? '-15px' : '', - 'margin-left': params?.LISConfigurations?.isLIS ? '-5px' : '' - }" - > - <mat-chip-listbox - class="w-100" - cdkDropListOrientation="{{ - params?.LISConfigurations && !params?.LISConfigurations?.isLIS - ? 'horizontal' - : '' - }}" + <ng-container *ngIf="!params?.LISConfigurations?.isLIS"> + <div [ngClass]="{ - 'full-width-chip mat-chip-list-stacked': - params?.LISConfigurations?.isLIS + 'col-2': params?.LISConfigurations?.isLIS && showMenuItems, + 'col-12': !params?.LISConfigurations?.isLIS + }" + *ngIf="showMenuItems" + class="laboratory-header mat-elevation-z1" + [ngStyle]="{ + height: 'auto', + 'margin-top': params?.LISConfigurations?.isLIS ? '-15px' : '', + 'margin-left': params?.LISConfigurations?.isLIS ? '-5px' : '' }" + > + <mat-chip-listbox + class="w-100" + cdkDropListOrientation="{{ + params?.LISConfigurations && !params?.LISConfigurations?.isLIS + ? 'horizontal' + : '' + }}" + [ngClass]="{ + 'full-width-chip mat-chip-list-stacked': + params?.LISConfigurations?.isLIS + }" + > + <div + style=" + border-bottom: solid 1px #f2f2f2; + background-color: #f2f2f2; + " + class="w-100 pl-3 pt-1 pb-2" + *ngIf="params?.LISConfigurations?.isLIS" + > + <button mat-button [matMenuTriggerFor]="labs"> + <mat-icon color="primary">location_on</mat-icon + >{{ params?.currentLocation?.display }} + </button> + <mat-menu #labs="matMenu"> + <button mat-menu-item (click)="setCurrentLab(null)">All</button> + <button + mat-menu-item + (click)="setCurrentLab(lab)" + *ngFor="let lab of params?.labs" + > + {{ lab?.name }} + </button> + </mat-menu> + <p class="ml-4"> + {{ params?.currentUser?.person?.display }} + <em>({{ params?.currentUser?.username }})</em> + </p> + </div> + <mat-chip-option + class="{{ + params?.LISConfigurations?.isLIS ? 'w-100 mt-2' : 'w-20' + }}" + *ngIf="params?.privileges && params?.LISConfigurations?.isLIS" + (click)="changeRoute($event, 'dashboard-lab', true)" + routerLinkActive="active-route-chip" + [ngClass]="{ + 'active-route-chip': currentRoutePath === 'dashboard-lab', + 'for-lis-chip': params?.LISConfigurations?.isLIS + }" + [ngStyle]="{ + 'border-radius': params?.LISConfigurations?.isLIS + ? '0 !important' + : '', + padding: params?.LISConfigurations?.isLIS + ? '12px !important' + : '' + }" + > + Dashboard + </mat-chip-option> + <mat-chip-option + class="{{ params?.LISConfigurations?.isLIS ? 'w-100' : 'w-20' }}" + *ngIf=" + params?.privileges && + params?.privileges['Laboratory Orders'] && + params?.LISConfigurations?.isLIS && + params?.currentLocation?.name !== 'All' + " + (click)="changeRoute($event, 'sample-registration', false)" + routerLinkActive="active-route-chip" + [ngClass]="{ + 'active-route-chip': currentRoutePath === 'sample-registration' + }" + > + Sample Reception & Registration + </mat-chip-option> + <mat-chip-option + class="{{ params?.LISConfigurations?.isLIS ? 'w-100' : 'w-20' }}" + *ngIf=" + params?.privileges && + params?.privileges['Laboratory Diagnostic Orders'] && + !params?.LISConfigurations?.isLIS + " + (click)="changeRoute($event, 'lab-investigation-home', true)" + routerLinkActive="active-route-chip" + [ngClass]="{ + 'active-route-chip': + currentRoutePath === 'lab-investigation-home' + }" + > + Diagnostic Orders/Services + </mat-chip-option> + <mat-chip-option + class="{{ params?.LISConfigurations?.isLIS ? 'w-100' : 'w-20' }}" + *ngIf=" + params?.privileges && + params?.privileges['Sample Collection'] && + !params?.LISConfigurations?.isLIS + " + (click)="changeRoute($event, 'sample-collection', true)" + routerLinkActive="active-route-chip" + [ngClass]="{ + 'active-route-chip': currentRoutePath === 'sample-collection' + }" + > + Sample collection + </mat-chip-option> + <mat-chip-option + class="{{ params?.LISConfigurations?.isLIS ? 'w-100' : 'w-20' }}" + routerLinkActive="active-route-chip" + (click)=" + changeRoute($event, 'sample-acceptance-and-results', true) + " + [ngClass]="{ + 'active-route-chip': + currentRoutePath === 'sample-acceptance-and-results' + }" + *ngIf=" + params?.privileges && + params?.privileges['Sample Acceptance and Results'] + " + > + Sample Testing & Results + </mat-chip-option> + <mat-chip-option + *ngIf="params?.LISConfigurations?.isLIS" + class="{{ params?.LISConfigurations?.isLIS ? 'w-100' : 'w-20' }}" + routerLinkActive="active-route-chip" + (click)="changeRoute($event, 'sample-results-list', true)" + [ngClass]="{ + 'active-route-chip': currentRoutePath === 'sample-results-list' + }" + > + Results + </mat-chip-option> + <mat-chip-option + class="{{ params?.LISConfigurations?.isLIS ? 'w-100' : 'w-20' }}" + routerLinkActive="active-route-chip" + (click)="changeRoute($event, 'sample-tracking', true)" + [ngClass]="{ + 'active-route-chip': currentRoutePath === 'sample-tracking' + }" + *ngIf=" + params?.privileges && params?.privileges['Sample Tracking'] + " + > + Sample Tracking + </mat-chip-option> + <mat-chip-option + class="{{ params?.LISConfigurations?.isLIS ? 'w-100' : 'w-20' }}" + *ngIf=" + params?.privileges && + params?.privileges['Laboratory Orders'] && + params?.LISConfigurations?.isLIS + " + routerLinkActive="active-route-chip" + (click)="changeRoute($event, 'sample-storage', true)" + [ngClass]="{ + 'active-route-chip': currentRoutePath === 'sample-storage' + }" + > + Sample Storage & Disposal + </mat-chip-option> + <mat-chip-option + class="{{ params?.LISConfigurations?.isLIS ? 'w-100' : 'w-20' }}" + routerLinkActive="active-route-chip" + (click)="changeRoute($event, 'reports', false)" + [ngClass]="{ + 'active-route-chip': currentRoutePath === 'reports' + }" + *ngIf=" + params?.privileges && params?.privileges['Laboratory Reports'] + " + > + Reports + </mat-chip-option> + <mat-chip-option + class="{{ params?.LISConfigurations?.isLIS ? 'w-100' : 'w-20' }}" + routerLinkActive="active-route-chip" + (click)="changeRoute($event, 'settings', true)" + [ngClass]="{ + 'active-route-chip': currentRoutePath === 'settings' + }" + *ngIf="params?.privileges && params?.privileges['Tests Settings']" + > + Maintenance + </mat-chip-option> + </mat-chip-listbox> + </div> + </ng-container> + <ng-container *ngIf="params?.LISConfigurations?.isLIS"> + <div + *ngIf="showMenuItems" + class="col-2.5 lis-menu" + style="margin-left: -16px; margin-right: -8px" > <div style="border-bottom: solid 1px #f2f2f2; background-color: #f2f2f2" @@ -93,148 +279,57 @@ <em>({{ params?.currentUser?.username }})</em> </p> </div> - <mat-chip-option - class="{{ params?.LISConfigurations?.isLIS ? 'w-100' : 'w-20' }}" - *ngIf="params?.privileges && params?.LISConfigurations?.isLIS" - (click)="changeRoute($event, 'dashboard-lab', true)" - routerLinkActive="active-route" - [ngClass]="{ - 'active-route': currentRoutePath === 'dashboard-lab', - 'for-lis-chip': params?.LISConfigurations?.isLIS - }" - [ngStyle]="{ - 'border-radius': params?.LISConfigurations?.isLIS - ? '0 !important' - : '', - padding: params?.LISConfigurations?.isLIS ? '12px !important' : '' - }" - > - Dashboard - </mat-chip-option> - <mat-chip-option - class="{{ params?.LISConfigurations?.isLIS ? 'w-100' : 'w-20' }}" - *ngIf=" - params?.privileges && - params?.privileges['Laboratory Orders'] && - params?.LISConfigurations?.isLIS && - params?.currentLocation?.name !== 'All' - " - (click)="changeRoute($event, 'sample-registration', false)" - routerLinkActive="active-route" - [ngClass]="{ - 'active-route': currentRoutePath === 'sample-registration' - }" - > - Sample Reception & Registration - </mat-chip-option> - <mat-chip-option - class="{{ params?.LISConfigurations?.isLIS ? 'w-100' : 'w-20' }}" - *ngIf=" - params?.privileges && - params?.privileges['Laboratory Diagnostic Orders'] && - !params?.LISConfigurations?.isLIS - " - (click)="changeRoute($event, 'lab-investigation-home', true)" - routerLinkActive="active-route" - [ngClass]="{ - 'active-route': currentRoutePath === 'lab-investigation-home' - }" - > - Diagnostic Orders/Services - </mat-chip-option> - <mat-chip-option - class="{{ params?.LISConfigurations?.isLIS ? 'w-100' : 'w-20' }}" - *ngIf=" - params?.privileges && - params?.privileges['Sample Collection'] && - !params?.LISConfigurations?.isLIS - " - (click)="changeRoute($event, 'sample-collection', true)" - routerLinkActive="active-route" - [ngClass]="{ - 'active-route': currentRoutePath === 'sample-collection' - }" - > - Sample collection - </mat-chip-option> - <mat-chip-option - class="{{ params?.LISConfigurations?.isLIS ? 'w-100' : 'w-20' }}" - routerLinkActive="active-route" - (click)="changeRoute($event, 'sample-acceptance-and-results', true)" - [ngClass]="{ - 'active-route': - currentRoutePath === 'sample-acceptance-and-results' - }" - *ngIf=" - params?.privileges && - params?.privileges['Sample Acceptance and Results'] - " - > - Sample Testing & Results - </mat-chip-option> - <mat-chip-option - *ngIf="params?.LISConfigurations?.isLIS" - class="{{ params?.LISConfigurations?.isLIS ? 'w-100' : 'w-20' }}" - routerLinkActive="active-route" - (click)="changeRoute($event, 'sample-results-list', true)" - [ngClass]="{ - 'active-route': currentRoutePath === 'sample-results-list' - }" - > - Results - </mat-chip-option> - <mat-chip-option - class="{{ params?.LISConfigurations?.isLIS ? 'w-100' : 'w-20' }}" - routerLinkActive="active-route" - (click)="changeRoute($event, 'sample-tracking', true)" - [ngClass]="{ - 'active-route': currentRoutePath === 'sample-tracking' - }" - *ngIf="params?.privileges && params?.privileges['Sample Tracking']" - > - Sample Tracking - </mat-chip-option> - <mat-chip-option - class="{{ params?.LISConfigurations?.isLIS ? 'w-100' : 'w-20' }}" - *ngIf=" - params?.privileges && - params?.privileges['Laboratory Orders'] && - params?.LISConfigurations?.isLIS - " - routerLinkActive="active-route" - (click)="changeRoute($event, 'sample-storage', true)" - [ngClass]="{ - 'active-route': currentRoutePath === 'sample-storage' - }" - > - Sample Storage & Disposal - </mat-chip-option> - <mat-chip-option - class="{{ params?.LISConfigurations?.isLIS ? 'w-100' : 'w-20' }}" - routerLinkActive="active-route" - (click)="changeRoute($event, 'reports', false)" - [ngClass]="{ - 'active-route': currentRoutePath === 'reports' - }" - *ngIf=" - params?.privileges && params?.privileges['Laboratory Reports'] - " - > - Reports - </mat-chip-option> - <mat-chip-option - class="{{ params?.LISConfigurations?.isLIS ? 'w-100' : 'w-20' }}" - routerLinkActive="active-route" - (click)="changeRoute($event, 'settings', true)" - [ngClass]="{ - 'active-route': currentRoutePath === 'settings' - }" - *ngIf="params?.privileges && params?.privileges['Tests Settings']" - > - Maintenance - </mat-chip-option> - </mat-chip-listbox> - </div> + <div> + <ul style="height: 100vh" class="lis-menu-items"> + <ng-container *ngFor="let labMenu of laboratoryMenus"> + <li + (click)="setOpenLabMenu($event, labMenu?.id)" + [routerLink]="labMenu.route" + routerLinkActive="active-route" + [ngClass]="{ + 'active-route': currentLabMenuId === labMenu?.id + }" + role="listitem" + > + <div class="d-flex align-items-center"> + <mat-icon>{{ labMenu?.icon }}</mat-icon> + <label class="mx-2 mb-0"> {{ labMenu?.name }} </label> + </div> + </li> + <div + *ngIf=" + labMenu?.subMenus?.length > 0 && + showSubMenu && + currentLabMenuId === labMenu?.id + " + > + <mat-list role="list" class="ml-2"> + <ng-container> + <mat-list-item + (click)="setOpenLabSubMenu($event, subMenu?.id)" + *ngFor="let subMenu of labMenu?.subMenus" + matRipple + role="listitem" + routerLinkActive="active-route" + [routerLink]="subMenu.route" + [ngClass]="{ + 'active-route': currentLabSubMenuId === subMenu?.id + }" + class="list-item cursor-pointer" + > + <div class="d-flex align-items-center"> + <mat-icon>{{ subMenu?.icon }}</mat-icon> + <label class="mx-2 mb-0"> {{ subMenu?.name }} </label> + </div> + </mat-list-item> + </ng-container> + </mat-list> + </div> + </ng-container> + </ul> + </div> + </div> + </ng-container> <div [ngClass]="{ 'col-10': params?.LISConfigurations?.isLIS && showMenuItems, diff --git a/ui/src/app/modules/laboratory/laboratory.component.scss b/ui/src/app/modules/laboratory/laboratory.component.scss index f8b5645d5..f0d18f973 100644 --- a/ui/src/app/modules/laboratory/laboratory.component.scss +++ b/ui/src/app/modules/laboratory/laboratory.component.scss @@ -40,21 +40,60 @@ // border-radius: 0 16px 16px 0 !important; // } -::ng-deep .mat-mdc-standard-chip .for-lis-chip:hover { +::ng-deep .mat-mdc-standard-chip { border-radius: 0 !important; } +.laboratory-header .mat-mdc-standard-chip:not(.mdc-evolution-chip--disabled) { + background-color: inherit !important; + border-bottom: solid 1px #fafafa; +} + .active-route { background-color: #2a8fd1 !important; // TODO use variable color: #fff !important; border-radius: 0 !important; } -::ng-deep .mat-mdc-standard-chip { +.laboratory-header .mdc-evolution-chip--selected, +.laboratory-header .mat-mdc-chip-selected { + background-color: #2a8fd1 !important; // TODO use variable + color: #fff !important; border-radius: 0 !important; } +.laboratory-header .mat-chip-option.mat-mdc-chip-selected { + background-color: #2a8fd1 !important; /* Or any color you prefer */ + color: #fff; /* Adjust text color if needed */ +} -::ng-deep .mat-mdc-standard-chip:not(.mdc-evolution-chip--disabled) { - background-color: transparent !important; - border-bottom: solid 1px #fafafa; +::ng-deep .mat-expansion-panel { + border-radius: 0 !important; +} + +::ng-deep .mat-expansion-panel-header.mat-expanded { + height: 48px; +} + +::ng-deep .mat-expansion-panel-body { + padding: 0 !important; +} + +.lis-menu .mat-expansion-panel-spacing { + margin: 0 !important; +} + +.lis-menu .mat-expansion-panel-header { + padding: 24px 24px !important; + border-bottom: solid 1px #eee; +} + +ul { + list-style-type: none; + margin-left: -24px; + box-shadow: 0px 1px 1px 0px rgba(0, 0, 0, 0.2), + 0px 1px 1px 0px rgba(0, 0, 0, 0.14), 0px 1px 1px 0px rgba(0, 0, 0, 0.12); +} + +.lis-menu-items li { + padding: 12px 4px; } diff --git a/ui/src/app/modules/laboratory/laboratory.component.ts b/ui/src/app/modules/laboratory/laboratory.component.ts index 1b6ec17e8..5f6262f4a 100644 --- a/ui/src/app/modules/laboratory/laboratory.component.ts +++ b/ui/src/app/modules/laboratory/laboratory.component.ts @@ -35,12 +35,13 @@ import { Title } from "@angular/platform-browser"; import { LocationService } from "src/app/core/services"; import { SystemSettingsService } from "src/app/core/services/system-settings.service"; import { iCareConnectConfigurationsModel } from "src/app/core/models/lis-configurations.model"; +import { LabMenu } from "./resources/models/lab-menu.model"; @Component({ selector: "lab-root", templateUrl: "./laboratory.component.html", styleUrls: ["./laboratory.component.scss"], - encapsulation: ViewEncapsulation.None + encapsulation: ViewEncapsulation.None, }) export class LaboratoryComponent implements OnInit { title = "Laboratory"; @@ -84,6 +85,82 @@ export class LaboratoryComponent implements OnInit { errors: any[] = []; loadedSystemSettings$: Observable<boolean>; + laboratoryMenus: LabMenu[] = [ + { + name: "Dashboard", + route: "dashboard-lab", + id: "dashboard", + icon: "dashboard", + subMenus: [], + }, + { + name: "Sample Reception & Registration", + route: "sample-registration", + icon: "add_to_queue", + id: "registration", + subMenus: [ + { + name: "Sample Registration", + route: "sample-registration", + id: "registration", + icon: "list", + }, + ], + }, + { + name: "Sample Acceptance and Results", + route: "sample-acceptance-and-results", + icon: "dvr", + id: "acceptance", + subMenus: [], + }, + { + name: "Results", + route: "sample-results-list", + id: "results", + icon: "send", + subMenus: [], + }, + { + name: "Sample Tracking", + route: "sample-tracking", + id: "tracking", + icon: "track_changes", + subMenus: [], + }, + { + name: "Sample Storage", + route: "sample-storage", + id: "sample-storage", + icon: "storage", + subMenus: [], + }, + { + name: "Reports", + route: "reports", + icon: "report", + id: "reports", + subMenus: [], + }, + { + name: "Maintenance", + route: "settings", + id: "settings", + icon: "settings", + subMenus: [ + { + name: "General", + route: "settings", + id: "general", + icon: "settings", + }, + ], + }, + ]; + showSubMenu: boolean = false; + currentLabMenuId: string = "dashboard"; + currentLabSubMenuId: string; + constructor( private store: Store<AppState>, private router: Router, @@ -280,6 +357,17 @@ export class LaboratoryComponent implements OnInit { this.currentLocation$ = this.store.select(getCurrentLocation(false)); } + setOpenLabMenu(event: Event, id: string): void { + event.stopPropagation(); + this.currentLabMenuId = id; + this.showSubMenu = true; + } + + setOpenLabSubMenu(event: Event, id: string): void { + event.stopPropagation(); + this.currentLabSubMenuId = id; + } + setCurrentLab(location: any): void { this.currentLocation$ = of(null); if (location) { diff --git a/ui/src/app/modules/laboratory/resources/models/lab-menu.model.ts b/ui/src/app/modules/laboratory/resources/models/lab-menu.model.ts new file mode 100644 index 000000000..0200650f1 --- /dev/null +++ b/ui/src/app/modules/laboratory/resources/models/lab-menu.model.ts @@ -0,0 +1,7 @@ +export interface LabMenu { + name: string; + route: string; + icon?: string; + id: string; + subMenus?: LabMenu[]; +}