Skip to content

Commit

Permalink
Merge pull request #1790 from bcgov/develop
Browse files Browse the repository at this point in the history
Deployment PR - 1261
  • Loading branch information
trslater authored Sep 4, 2024
2 parents 6fbe17c + de670a9 commit e84cb6f
Show file tree
Hide file tree
Showing 92 changed files with 9,998 additions and 7,379 deletions.
11 changes: 8 additions & 3 deletions .github/workflows/e2e-test.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: E2E Testing w/ Playwright
name: E2E
on:
workflow_dispatch:
inputs:
Expand All @@ -19,10 +19,14 @@ on:
description: 'Branch to checkout'
default: 'develop'
schedule:
# 5:23 am daily
- cron: "23 5 * * *"
# 12:23 UTC (i.e., 5:23 am daily pacific time)
- cron: "23 12 * * *"
pull_request:
branches:
- main
jobs:
test:
name: Playwright Tests
timeout-minutes: 60
runs-on: ubuntu-latest
steps:
Expand All @@ -45,6 +49,7 @@ jobs:
ALCS_BASE_URL: ${{ inputs.alcsBaseUrl || 'https://alcs-dev.apps.silver.devops.gov.bc.ca' }}
BCEID_BASIC_USERNAME: ${{ secrets.BCEID_BASIC_USERNAME }}
BCEID_BASIC_PASSWORD: ${{ secrets.BCEID_BASIC_PASSWORD }}
PRIMARY_CONTACT_EMAIL: ${{ secrets.PRIMARY_CONTACT_EMAIL }}
run: npx playwright test
- uses: actions/upload-artifact@v4
if: always()
Expand Down
3,494 changes: 1,793 additions & 1,701 deletions alcs-frontend/package-lock.json

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { Injectable } from '@angular/core';
import { firstValueFrom } from 'rxjs';
import { environment } from '../../../environments/environment';
import { ToastService } from '../toast/toast.service';
import { UpcomingMeetingBoardMapDto } from './decision-meeting.dto';
import { UpcomingMeetingBoardMapDto, UpcomingMeetingDto } from './decision-meeting.dto';

@Injectable({
providedIn: 'root',
Expand All @@ -16,7 +16,16 @@ export class DecisionMeetingService {
private toastService: ToastService,
) {}

async fetch() {
async fetch(fileNumber?: string) {
if (fileNumber !== undefined) {
try {
const meetings = await firstValueFrom(this.http.get<UpcomingMeetingDto[]>(`${this.url}/${fileNumber}`));
const record: UpcomingMeetingBoardMapDto = { all: meetings };
return record;
} catch (err) {
this.toastService.showErrorToast('Failed to fetch scheduled discussions');
}
}
try {
return await firstValueFrom(this.http.get<UpcomingMeetingBoardMapDto>(`${this.url}/overview/meetings`));
} catch (err) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,18 @@ <h5 class="detail-heading">
<mat-icon style="transform: scale(1.1)">arrow_right_alt</mat-icon>
</div>
</button>
<button
*ngIf="isCommissioner && hasMeetings"
class="menu-item"
mat-flat-button
color="accent"
(click)="onGoToSchedule(_application.fileNumber)"
>
<div class="center">
Go to card
<mat-icon style="transform: scale(1.1)">arrow_right_alt</mat-icon>
</div>
</button>
<ng-container *ngIf="linkedCards.length > 1">
<button class="menu-item center" mat-flat-button color="accent" [matMenuTriggerFor]="goToMenu">
Go to card ▾
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { HttpClientTestingModule } from '@angular/common/http/testing';
import { RouterTestingModule } from '@angular/router/testing';

import { DetailsHeaderComponent } from './details-header.component';
Expand All @@ -9,7 +10,7 @@ describe('DetailsHeaderComponent', () => {

beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [RouterTestingModule],
imports: [RouterTestingModule, HttpClientTestingModule],
declarations: [DetailsHeaderComponent],
providers: [],
}).compileComponents();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Component, Input } from '@angular/core';
import { Component, Input, OnDestroy, OnInit } from '@angular/core';
import { Router } from '@angular/router';
import { Subject } from 'rxjs';
import { combineLatestWith, Subject, takeUntil } from 'rxjs';
import { ApplicationTypeDto } from '../../services/application/application-code.dto';
import { ApplicationModificationDto } from '../../services/application/application-modification/application-modification.dto';
import { ApplicationReconsiderationDto } from '../../services/application/application-reconsideration/application-reconsideration.dto';
Expand All @@ -23,14 +23,18 @@ import {
import { TimeTrackable } from '../time-tracker/time-tracker.component';
import { ApplicationDetailService } from '../../services/application/application-detail.service';
import { ApplicationSubmissionService } from '../../services/application/application-submission/application-submission.service';
import { AuthenticationService, ROLES } from '../../services/authentication/authentication.service';
import { BoardService } from '../../services/board/board.service';
import { DecisionMeetingService } from '../../services/decision-meeting/decision-meeting.service';
import { UpcomingMeetingBoardMapDto } from '../../services/decision-meeting/decision-meeting.dto';

@Component({
selector: 'app-details-header[application]',
templateUrl: './details-header.component.html',
styleUrls: ['./details-header.component.scss'],
})
export class DetailsHeaderComponent {
destroy = new Subject<void>();
export class DetailsHeaderComponent implements OnInit, OnDestroy {
$destroy = new Subject<void>();

@Input() heading = 'Title Here';
@Input() days = 'Calendar Days';
Expand Down Expand Up @@ -96,6 +100,8 @@ export class DetailsHeaderComponent {
this.currentStatus = DEFAULT_NO_STATUS;
});
}

this.$application.next(application);
}
}

Expand Down Expand Up @@ -125,7 +131,55 @@ export class DetailsHeaderComponent {
isNOI = false;
currentStatus?: ApplicationSubmissionStatusPill;

constructor(private router: Router) {}
isCommissioner: boolean = false;
hasMeetings: boolean = false;

$meetingsByBoard = new Subject<UpcomingMeetingBoardMapDto>();
$application = new Subject<ApplicationDto | CommissionerApplicationDto | NoticeOfIntentDto | NotificationDto>();

constructor(
private router: Router,
private authService: AuthenticationService,
private boardService: BoardService,
private meetingService: DecisionMeetingService,
) {}

ngOnInit(): void {
this.loadMeetings();

this.authService.$currentUser.pipe(takeUntil(this.$destroy)).subscribe((currentUser) => {
this.isCommissioner =
!!currentUser &&
!!currentUser.client_roles &&
currentUser.client_roles.length === 1 &&
currentUser.client_roles.includes(ROLES.COMMISSIONER);
});

this.boardService.$boards
.pipe(combineLatestWith(this.$meetingsByBoard, this.$application))
.pipe(takeUntil(this.$destroy))
.subscribe(([boards, meetingsByBoard, application]) => {
if (boards && meetingsByBoard && application) {
const visibleBoardCodes = boards.filter((board) => board.showOnSchedule).map((board) => board.code);

const visibleBoardCodeMeetingPairs = Object.entries(meetingsByBoard).filter(([code, _]) =>
visibleBoardCodes.includes(code),
);

this.hasMeetings = visibleBoardCodeMeetingPairs.some(([_, meetings]) =>
meetings.some((meeting) => meeting.fileNumber === application?.fileNumber),
);
}
});
}

async loadMeetings() {
const meetingsByBoards = await this.meetingService.fetch();

if (meetingsByBoards !== undefined) {
this.$meetingsByBoard.next(meetingsByBoards);
}
}

async onGoToCard(card: CardDto) {
const boardCode = card.boardCode;
Expand All @@ -134,6 +188,12 @@ export class DetailsHeaderComponent {
await this.router.navigateByUrl(`/board/${boardCode}?card=${cardUuid}&type=${cardTypeCode}`);
}

async onGoToSchedule(fileNumber: string) {
if (this.isCommissioner) {
await this.router.navigateByUrl(`/home?file_number=${fileNumber}`);
}
}

async setupLinkedCards() {
const application = this._application;
const result = [];
Expand Down Expand Up @@ -168,4 +228,9 @@ export class DetailsHeaderComponent {
await this.applicationSubmissionService?.update(this._application?.fileNumber, { applicant });
}
}

ngOnDestroy(): void {
this.$destroy.next();
this.$destroy.complete();
}
}
2 changes: 1 addition & 1 deletion alcs-frontend/src/app/shared/header/header.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
<button class="menu-item subheading1">Home</button>
</a>
</div>
<div *ngIf="hasRoles && !isCommissioner">
<div *ngIf="hasRoles && !isCommissioner && !isSoilOfficer">
<a routerLink="/schedule">
<button class="menu-item subheading1">Schedule</button>
</a>
Expand Down
6 changes: 6 additions & 0 deletions alcs-frontend/src/app/shared/header/header.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ export class HeaderComponent implements OnInit {
sortedBoards: BoardWithFavourite[] = [];
notifications: MessageDto[] = [];
isCommissioner = false;
isSoilOfficer = false;
isAdmin = false;
showMaintenanceBanner = true;
maintenanceBannerMessage = '';
Expand All @@ -49,6 +50,11 @@ export class HeaderComponent implements OnInit {
? currentUser.client_roles.includes(ROLES.COMMISSIONER)
: false;

this.isSoilOfficer =
currentUser.client_roles && currentUser.client_roles.length == 1
? currentUser.client_roles.includes(ROLES.SOIL_OFFICER)
: false;

this.isAdmin = currentUser.client_roles ? currentUser.client_roles.includes(ROLES.ADMIN) : false;

if (this.hasRoles) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,15 +38,15 @@ <h3 class="center">
>
<div class="main-panel-date center" *ngIf="boardMeeting.nextMeeting?.meetingDate">
<mat-icon>event</mat-icon>
<h4>{{ boardMeeting.nextMeeting!.meetingDate | momentFormat : customDateFormat }}</h4>
<h4>{{ boardMeeting.nextMeeting!.meetingDate | momentFormat: customDateFormat }}</h4>
</div>
<h4 class="main-panel-no-meetings center" *ngIf="!boardMeeting.nextMeeting?.meetingDate">None Scheduled</h4>
<h4 class="main-panel-no-meetings center" *ngIf="!boardMeeting.nextMeeting?.meetingDate">None</h4>
</mat-panel-description>
</mat-expansion-panel-header>
<div class="meetings-container">
<div class="previous-meetings">
<h4>Previous Meetings</h4>
<h5 *ngIf="!boardMeeting.pastMeetings.length" class="no-meetings">No Meetings</h5>
<h4>Previous</h4>
<h5 *ngIf="!boardMeeting.pastMeetings.length" class="no-meetings">None</h5>
<mat-expansion-panel
class="meeting-panel"
hideToggle="true"
Expand All @@ -59,33 +59,33 @@ <h5 *ngIf="!boardMeeting.pastMeetings.length" class="no-meetings">No Meetings</h
class="meeting-header meeting-header-previous"
>
<mat-panel-title class="center">
<h5>{{ pastMeeting.meetingDate | momentFormat : customDateFormat }}</h5>
<h5>{{ pastMeeting.meetingDate | momentFormat: customDateFormat }}</h5>
</mat-panel-title>
</mat-expansion-panel-header>
<ng-container *ngFor="let meeting of pastMeeting.meetings">
<ng-template *ngTemplateOutlet="meetingPanel; context: { $implicit: meeting }"></ng-template>
</ng-container>
</mat-expansion-panel>
</div>
<div class="next-meeting">
<h4>Next Meeting</h4>
<h5 *ngIf="!boardMeeting.nextMeeting" class="no-meetings">No Meetings</h5>
<div class="for-discussion">
<h4>For Discussion</h4>
<h5 *ngIf="!boardMeeting.upcomingMeetings.length" class="no-meetings">None Scheduled</h5>
<mat-expansion-panel
[(expanded)]="boardMeeting.nextMeeting.isExpanded"
class="meeting-panel"
hideToggle="true"
*ngIf="boardMeeting.nextMeeting"
[(expanded)]="upcomingMeeting.isExpanded"
*ngFor="let upcomingMeeting of boardMeeting.upcomingMeetings"
>
<mat-expansion-panel-header
expandedHeight="54px"
collapsedHeight="54px"
class="meeting-header meeting-header-next"
class="meeting-header meeting-header-for-discussion"
>
<mat-panel-title class="center">
<h5>{{ boardMeeting.nextMeeting!.meetingDate | momentFormat : customDateFormat }}</h5>
<h5>{{ upcomingMeeting.meetingDate | momentFormat: customDateFormat }}</h5>
</mat-panel-title>
</mat-expansion-panel-header>
<ng-container *ngFor="let meeting of boardMeeting.nextMeeting!.meetings">
<ng-container *ngFor="let meeting of upcomingMeeting.meetings">
<ng-template *ngTemplateOutlet="meetingPanel; context: { $implicit: meeting }"></ng-template>
</ng-container>
</mat-expansion-panel>
Expand All @@ -105,7 +105,7 @@ <h5 *ngIf="!boardMeeting.upcomingMeetings.length" class="no-meetings">None Sched
class="meeting-header meeting-header-upcoming"
>
<mat-panel-title class="center">
<h5>{{ upcomingMeeting.meetingDate | momentFormat : customDateFormat }}</h5>
<h5>{{ upcomingMeeting.meetingDate | momentFormat: customDateFormat }}</h5>
</mat-panel-title>
</mat-expansion-panel-header>
<ng-container *ngFor="let meeting of upcomingMeeting.meetings">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -155,10 +155,10 @@ mat-panel-description {
}
}

.next-meeting {
.for-discussion {
background-color: rgba(colors.$primary-color-light, 0.5);

.meeting-header-next.mat-expansion-panel-header:hover {
.meeting-header-for-discussion.mat-expansion-panel-header:hover {
border: 2px solid colors.$primary-color;
background-color: colors.$white;

Expand All @@ -167,7 +167,7 @@ mat-panel-description {
}
}

.meeting-header-next.mat-expansion-panel-header.mat-expanded {
.meeting-header-for-discussion.mat-expansion-panel-header.mat-expanded {
background-color: colors.$primary-color-dark;

&:hover {
Expand Down Expand Up @@ -296,7 +296,7 @@ mat-panel-description {
}

.previous-meetings,
.next-meeting,
.for-discussion,
.upcoming-meetings {
min-width: 100%;
width: 100%;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { ToastService } from '../../services/toast/toast.service';
import { AssigneeDto, UserDto } from '../../services/user/user.dto';
import { UserService } from '../../services/user/user.service';
import { CardType } from '../card/card.component';
import { RouterTestingModule } from '@angular/router/testing';

import { MeetingOverviewComponent } from './meeting-overview.component';

Expand All @@ -34,6 +35,7 @@ describe('MeetingOverviewComponent', () => {
mockToastService = createMock();

await TestBed.configureTestingModule({
imports: [RouterTestingModule],
providers: [
{
provide: DecisionMeetingService,
Expand Down
Loading

0 comments on commit e84cb6f

Please sign in to comment.