From 777e101b5ef2e961b2c3abb49579ddcd85ba905d Mon Sep 17 00:00:00 2001 From: aasandei-vsp Date: Thu, 7 May 2026 16:47:13 +0300 Subject: [PATCH] Support multiple Archive Stewards per archive Adapt the Legacy Planning panel to render one card per Archive Steward instead of a single steward record. Each card has a $PR-blue-100 border, a $PR-blue-25 hover background, and a material-icons edit icon in the top-right; the whole card is clickable and reuses the existing edit form to update that steward. The bottom button becomes "Add a new Archive Steward" and opens the same form with no pre-filled directive. The legacy-contact requirement now only gates the very first steward; once at least one exists, additional ones can be added without it. Errors when loading or saving stewards surface through MessageService.showError. Issue: PER-10415 --- .../directive-dialog.component.html | 6 +- .../directive-dialog.component.spec.ts | 73 ++++++++ .../directive-dialog.component.ts | 25 ++- .../directive-display.component.html | 72 ++++---- .../directive-display.component.scss | 21 +++ .../directive-display.component.spec.ts | 157 ++++++++++++++---- .../directive-display.component.ts | 51 ++++-- .../directive-display/test-utils.ts | 29 +++- .../directive-edit.component.ts | 4 +- .../services/api/directive.repo.spec.ts | 9 +- src/app/shared/services/api/directive.repo.ts | 12 +- src/styles/_colors.scss | 2 + 12 files changed, 358 insertions(+), 103 deletions(-) diff --git a/src/app/directive/components/directive-dialog/directive-dialog.component.html b/src/app/directive/components/directive-dialog/directive-dialog.component.html index d8a98eb42..247ce6f5a 100644 --- a/src/app/directive/components/directive-dialog/directive-dialog.component.html +++ b/src/app/directive/components/directive-dialog/directive-dialog.component.html @@ -2,8 +2,8 @@ @default { } @@ -12,7 +12,7 @@ } diff --git a/src/app/directive/components/directive-dialog/directive-dialog.component.spec.ts b/src/app/directive/components/directive-dialog/directive-dialog.component.spec.ts index 4397c0ef1..c17f564c7 100644 --- a/src/app/directive/components/directive-dialog/directive-dialog.component.spec.ts +++ b/src/app/directive/components/directive-dialog/directive-dialog.component.spec.ts @@ -7,8 +7,32 @@ import { ApiService } from '@shared/services/api/api.service'; import { provideHttpClientTesting } from '@angular/common/http/testing'; import { AccountService } from '@shared/services/account/account.service'; import { AccountVO } from '@models/account-vo'; +import { Directive } from '@models/directive'; import { DirectiveDialogComponent } from './directive-dialog.component'; +const buildDirective = ( + directiveId: string, + stewardEmail: string, + note: string, +): Directive => + new Directive({ + directiveId, + archiveId: 1, + type: 'admin', + createdDt: new Date(), + updatedDt: new Date(), + trigger: { + directiveTriggerId: directiveId, + directiveId, + type: 'admin', + createdDt: new Date(), + updatedDt: new Date(), + }, + steward: { email: stewardEmail, name: '' }, + note, + executionDt: null, + }); + describe('DirectiveDialogComponent', () => { let component: DirectiveDialogComponent; let fixture: ComponentFixture; @@ -38,4 +62,53 @@ describe('DirectiveDialogComponent', () => { it('should create', () => { expect(component).toBeTruthy(); }); + + it('should switch to edit mode with the selected directive', () => { + const directive = buildDirective( + 'directive-1', + 'first@example.com', + 'note', + ); + component.switchToEdit(directive); + + expect(component.mode).toBe('edit'); + expect(component.editing).toBe(directive); + }); + + it('should switch to edit mode with null when adding a new steward', () => { + component.switchToEdit(null); + + expect(component.mode).toBe('edit'); + expect(component.editing).toBeNull(); + }); + + it('should append a saved directive when its id is not in the list', () => { + component.directives = [ + buildDirective('directive-1', 'first@example.com', 'one'), + ]; + const newDirective = buildDirective( + 'directive-2', + 'second@example.com', + 'two', + ); + + component.saveEditedDirective(newDirective); + + expect(component.directives.length).toBe(2); + expect(component.directives[1]).toBe(newDirective); + expect(component.mode).toBe('display'); + expect(component.editing).toBeNull(); + }); + + it('should replace a saved directive when its id matches an existing entry', () => { + const existing = buildDirective('directive-1', 'old@example.com', 'old'); + component.directives = [existing]; + const updated = buildDirective('directive-1', 'new@example.com', 'new'); + + component.saveEditedDirective(updated); + + expect(component.directives.length).toBe(1); + expect(component.directives[0]).toBe(updated); + expect(component.directives[0]).not.toBe(existing); + }); }); diff --git a/src/app/directive/components/directive-dialog/directive-dialog.component.ts b/src/app/directive/components/directive-dialog/directive-dialog.component.ts index 4f473bc61..ecf61d2aa 100644 --- a/src/app/directive/components/directive-dialog/directive-dialog.component.ts +++ b/src/app/directive/components/directive-dialog/directive-dialog.component.ts @@ -18,19 +18,32 @@ export class DirectiveDialogComponent { }); } public mode: DialogState = 'display'; - public directive: Directive; + public directives: Directive[] = []; + public editing: Directive | null = null; - public setSavedDirective(directive: Directive): void { - this.directive = directive; + public setLoadedDirectives(directives: Directive[]): void { + this.directives = directives; } - public switchToEdit(directive: Directive): void { - this.setSavedDirective(directive); + public switchToEdit(directive: Directive | null): void { + this.editing = directive; this.mode = 'edit'; } public saveEditedDirective(directive: Directive): void { - this.setSavedDirective(directive); + const matchingIndex = this.directives.findIndex( + (existing) => existing.directiveId === directive.directiveId, + ); + if (matchingIndex >= 0) { + this.directives = [ + ...this.directives.slice(0, matchingIndex), + directive, + ...this.directives.slice(matchingIndex + 1), + ]; + } else { + this.directives = [...this.directives, directive]; + } + this.editing = null; this.mode = 'display'; } } diff --git a/src/app/directive/components/directive-display/directive-display.component.html b/src/app/directive/components/directive-display/directive-display.component.html index 05f8e2c49..a06da56a2 100644 --- a/src/app/directive/components/directive-display/directive-display.component.html +++ b/src/app/directive/components/directive-display/directive-display.component.html @@ -25,9 +25,9 @@ >

- Archive Steward: The {{ archiveName }} Archive + Archive Stewards: The {{ archiveName }} Archive
- @if (noPlan) { + @if (showNoPlanWarning) {
@@ -47,47 +47,61 @@
}

- The Archive Steward for this archive will receive your note when your Legacy - Plan is activated. + Each Archive Steward for this archive will receive your note when your + Legacy Plan is activated.

@if (error) {
- An error occured while trying to find the Archive Steward for the current + An error occured while trying to find the Archive Stewards for the current archive. Please reload the page and try again.
} @if (!error) { -
-
-
Archive Steward email
-
+ edit - {{ directive?.steward?.email ?? 'not assigned' }} +
+
+
Archive Steward email
+
+ {{ directive?.steward?.email ?? 'not assigned' }} +
+
+
+
Note to Steward
+
+ {{ directive?.note ?? 'none' }} +
+
-
-
Note to Steward
-
- {{ directive?.note ?? 'none' }} -
-
-
+ } }
 
diff --git a/src/app/directive/components/directive-display/directive-display.component.scss b/src/app/directive/components/directive-display/directive-display.component.scss index fc27569ee..eb9644ecb 100644 --- a/src/app/directive/components/directive-display/directive-display.component.scss +++ b/src/app/directive/components/directive-display/directive-display.component.scss @@ -18,6 +18,27 @@ display: block; } +.archive-steward-card { + position: relative; + border: 1px solid $PR-blue-100; + border-radius: 0.25rem; + padding: 1em 2.5em 1em 1em; + margin-bottom: 0.75em; + cursor: pointer; + + &:hover, + &:focus-visible { + background: $PR-blue-25; + } + + .edit-icon { + position: absolute; + top: 0.75em; + right: 0.75em; + color: $gray-dark; + } +} + .archive-steward-table { display: table; diff --git a/src/app/directive/components/directive-display/directive-display.component.spec.ts b/src/app/directive/components/directive-display/directive-display.component.spec.ts index e22052dfb..066ceb674 100644 --- a/src/app/directive/components/directive-display/directive-display.component.spec.ts +++ b/src/app/directive/components/directive-display/directive-display.component.spec.ts @@ -5,6 +5,7 @@ import { MockBuilder, MockRender, ngMocks } from 'ng-mocks'; import { ArchiveVO } from '@models/index'; import { AccountService } from '@shared/services/account/account.service'; import { ApiService } from '@shared/services/api/api.service'; +import { MessageService } from '@shared/services/message/message.service'; import { DirectiveDisplayComponent } from './directive-display.component'; import { @@ -16,6 +17,21 @@ import { @NgModule() class DummyModule {} +class MockMessageService { + public static errorShown: boolean = false; + public static lastMessage: string | null = null; + + public static reset(): void { + MockMessageService.errorShown = false; + MockMessageService.lastMessage = null; + } + + public showError(options: { message: string }): void { + MockMessageService.errorShown = true; + MockMessageService.lastMessage = options.message; + } +} + describe('DirectiveDisplayComponent', () => { let mockApiService: MockApiService; @@ -25,6 +41,7 @@ describe('DirectiveDisplayComponent', () => { fullName: 'Test', }); MockDirectiveRepo.reset(); + MockMessageService.reset(); MockDirectiveRepo.mockStewardEmail = 'test@example.com'; MockDirectiveRepo.mockNote = 'Unit Testing!'; MockDirectiveRepo.legacyContactName = 'Test User'; @@ -40,6 +57,10 @@ describe('DirectiveDisplayComponent', () => { .provide({ provide: ApiService, useValue: mockApiService, + }) + .provide({ + provide: MessageService, + useClass: MockMessageService, }); }); @@ -69,7 +90,7 @@ describe('DirectiveDisplayComponent', () => { fixture.detectChanges(); const instance = fixture.point.componentInstance; - expect(instance.directive).not.toBeUndefined(); + expect(instance.directives.length).toBe(1); expect( ngMocks.findAll('.archive-steward-note')[0].nativeElement.innerText, ).toContain('Unit Testing!'); @@ -79,48 +100,100 @@ describe('DirectiveDisplayComponent', () => { ).toContain('test@example.com'); })); - it('should format null fields properly', fakeAsync(() => { - MockDirectiveRepo.reset(); + it('should render one card per directive', fakeAsync(() => { + MockDirectiveRepo.mockDirectives = [ + new MockDirectiveRepo().createDirective( + 'first@example.com', + 'note 1', + 'directive-1', + ), + new MockDirectiveRepo().createDirective( + 'second@example.com', + 'note 2', + 'directive-2', + ), + ]; const fixture = MockRender(DirectiveDisplayComponent); flush(); fixture.detectChanges(); - expect(ngMocks.findAll('.not-assigned').length).toBeGreaterThan(0); + expect(ngMocks.findAll('.archive-steward-card').length).toBe(2); + const emails = ngMocks + .findAll('.archive-steward-email') + .map((el) => el.nativeElement.innerText.trim()); + + expect(emails).toContain('first@example.com'); + expect(emails).toContain('second@example.com'); })); - it('should format filled out fields properly', fakeAsync(() => { + it('should emit beginEdit with the clicked directive', fakeAsync(() => { + MockDirectiveRepo.mockDirectives = [ + new MockDirectiveRepo().createDirective( + 'first@example.com', + 'note 1', + 'directive-1', + ), + ]; const fixture = MockRender(DirectiveDisplayComponent); flush(); fixture.detectChanges(); + const instance = fixture.point.componentInstance; + const beginEditSpy = spyOn(instance.beginEdit, 'emit'); - expect(ngMocks.findAll('.not-assigned').length).toBe(0); + ngMocks + .find('.archive-steward-card') + .nativeElement.dispatchEvent(new Event('click')); + + expect(beginEditSpy).toHaveBeenCalledWith(instance.directives[0]); })); - it('should be able to handle API errors when fetching Directive', fakeAsync(() => { + it('should emit beginEdit with null when the Add button is clicked', fakeAsync(() => { + const fixture = MockRender(DirectiveDisplayComponent); + flush(); + fixture.detectChanges(); + const instance = fixture.point.componentInstance; + const beginEditSpy = spyOn(instance.beginEdit, 'emit'); + + ngMocks.find('button').nativeElement.dispatchEvent(new Event('click')); + + expect(beginEditSpy).toHaveBeenCalledWith(null); + })); + + it('should mark missing fields as not assigned', fakeAsync(() => { + MockDirectiveRepo.mockDirectives = [ + new MockDirectiveRepo().createDirective(null, null, 'directive-empty'), + ]; + const fixture = MockRender(DirectiveDisplayComponent); + flush(); + fixture.detectChanges(); + + expect(ngMocks.findAll('.not-assigned').length).toBe(2); + })); + + it('should be able to handle API errors when fetching Directives', fakeAsync(() => { MockDirectiveRepo.failRequest = true; const fixture = MockRender(DirectiveDisplayComponent); flush(); fixture.detectChanges(); expect(ngMocks.findAll('.error').length).toBe(1); - expect(ngMocks.findAll('.archive-steward-table').length).toBe(0); + expect(ngMocks.findAll('.archive-steward-card').length).toBe(0); expect(ngMocks.find('button').nativeElement.disabled).toBeTruthy(); + expect(MockMessageService.errorShown).toBeTrue(); })); - it('should show the "No Plan" warning if the user does not have a legacy contact', async () => { - // Reset TestBed and reconfigure for this test + it('should show the "No Plan" warning if the user does not have a legacy contact and no stewards exist', async () => { TestBed.resetTestingModule(); MockDirectiveRepo.reset(); MockDirectiveRepo.legacyContactName = null; MockDirectiveRepo.legacyContactEmail = null; - MockDirectiveRepo.mockStewardEmail = 'test@example.com'; - MockDirectiveRepo.mockNote = 'Unit Testing!'; await TestBed.configureTestingModule({ declarations: [DirectiveDisplayComponent], providers: [ { provide: AccountService, useValue: new MockAccountService() }, { provide: ApiService, useValue: new MockApiService() }, + { provide: MessageService, useClass: MockMessageService }, ], }).compileComponents(); @@ -128,7 +201,6 @@ describe('DirectiveDisplayComponent', () => { const instance = fixture.componentInstance; fixture.detectChanges(); - // Wait for ngOnInit to complete await instance.ngOnInit(); fixture.detectChanges(); @@ -140,6 +212,43 @@ describe('DirectiveDisplayComponent', () => { expect(fixture.nativeElement.querySelector('button').disabled).toBeTruthy(); }); + it('should not show the "No Plan" warning when at least one steward exists', async () => { + TestBed.resetTestingModule(); + MockDirectiveRepo.reset(); + MockDirectiveRepo.legacyContactName = null; + MockDirectiveRepo.legacyContactEmail = null; + MockDirectiveRepo.mockDirectives = [ + new MockDirectiveRepo().createDirective( + 'existing@example.com', + 'note', + 'directive-1', + ), + ]; + + await TestBed.configureTestingModule({ + declarations: [DirectiveDisplayComponent], + providers: [ + { provide: AccountService, useValue: new MockAccountService() }, + { provide: ApiService, useValue: new MockApiService() }, + { provide: MessageService, useClass: MockMessageService }, + ], + }).compileComponents(); + + const fixture = TestBed.createComponent(DirectiveDisplayComponent); + const instance = fixture.componentInstance; + fixture.detectChanges(); + + await instance.ngOnInit(); + fixture.detectChanges(); + + expect(instance.noPlan).toBeTrue(); + expect( + fixture.nativeElement.querySelectorAll('.no-plan-warning').length, + ).toBe(0); + + expect(fixture.nativeElement.querySelector('button').disabled).toBeFalsy(); + }); + it('should not show the "No Plan" warning if the user does have a legacy contact', fakeAsync(() => { const fixture = MockRender(DirectiveDisplayComponent); flush(); @@ -150,7 +259,6 @@ describe('DirectiveDisplayComponent', () => { })); it('should be able to handle API errors when fetching Legacy Contact', async () => { - // Reset TestBed and reconfigure for this test TestBed.resetTestingModule(); MockDirectiveRepo.reset(); MockDirectiveRepo.failLegacyRequest = true; @@ -164,6 +272,7 @@ describe('DirectiveDisplayComponent', () => { providers: [ { provide: AccountService, useValue: new MockAccountService() }, { provide: ApiService, useValue: new MockApiService() }, + { provide: MessageService, useClass: MockMessageService }, ], }).compileComponents(); @@ -171,14 +280,13 @@ describe('DirectiveDisplayComponent', () => { const instance = fixture.componentInstance; fixture.detectChanges(); - // Wait for ngOnInit to complete await instance.ngOnInit(); fixture.detectChanges(); expect(instance.error).toBeTrue(); expect(fixture.nativeElement.querySelectorAll('.error').length).toBe(1); expect( - fixture.nativeElement.querySelectorAll('.archive-steward-table').length, + fixture.nativeElement.querySelectorAll('.archive-steward-card').length, ).toBe(0); expect(fixture.nativeElement.querySelector('button').disabled).toBeTruthy(); @@ -197,24 +305,13 @@ describe('DirectiveDisplayComponent', () => { expect(ngMocks.find('button').nativeElement.disabled).toBeFalsy(); })); - it('should say "Assign" for new directive', fakeAsync(() => { - MockDirectiveRepo.mockStewardEmail = null; - MockDirectiveRepo.mockNote = null; + it('should always show "Add a new Archive Steward" on the bottom button', fakeAsync(() => { const fixture = MockRender(DirectiveDisplayComponent); flush(); fixture.detectChanges(); - expect(ngMocks.find('button').nativeElement.innerText).toContain('Assign'); - expect(ngMocks.find('button').nativeElement.innerText).not.toContain( - 'Edit', + expect(ngMocks.find('button').nativeElement.innerText).toContain( + 'Add a new Archive Steward', ); })); - - it('should say "Edit" for existing directive', fakeAsync(() => { - const fixture = MockRender(DirectiveDisplayComponent); - flush(); - fixture.detectChanges(); - - expect(ngMocks.find('button').nativeElement.innerText).toContain('Edit'); - })); }); diff --git a/src/app/directive/components/directive-display/directive-display.component.ts b/src/app/directive/components/directive-display/directive-display.component.ts index 17b257ea1..606533b0d 100644 --- a/src/app/directive/components/directive-display/directive-display.component.ts +++ b/src/app/directive/components/directive-display/directive-display.component.ts @@ -2,6 +2,7 @@ import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core'; import { Directive } from '@models/index'; import { AccountService } from '@shared/services/account/account.service'; import { ApiService } from '@shared/services/api/api.service'; +import { MessageService } from '@shared/services/message/message.service'; @Component({ selector: 'pr-directive-display', @@ -11,29 +12,46 @@ import { ApiService } from '@shared/services/api/api.service'; }) export class DirectiveDisplayComponent implements OnInit { @Input() public checkLegacyContact: boolean = true; - @Input() public initialDirective: Directive; - @Output() public loadedDirective = new EventEmitter(); - @Output() public beginEdit = new EventEmitter(); + @Input() public initialDirectives: Directive[] = []; + @Output() public loadedDirectives = new EventEmitter(); + @Output() public beginEdit = new EventEmitter(); public archiveName: string; - public directive: Directive; + public directives: Directive[] = []; public error: boolean; public noPlan: boolean; constructor( private account: AccountService, private api: ApiService, + private message: MessageService, ) { this.error = false; this.noPlan = false; } async ngOnInit(): Promise { - this.directive = this.initialDirective; + this.directives = this.initialDirectives ?? []; this.archiveName = this.account.getArchive().fullName; if (this.checkLegacyContact) { await this.getLegacyContact(); } - await this.getDirective(); + await this.getDirectives(); + } + + public get gateAddButton(): boolean { + return this.error || (this.noPlan && this.directives.length === 0); + } + + public get showNoPlanWarning(): boolean { + return this.noPlan && this.directives.length === 0; + } + + public onCardActivated( + event: KeyboardEvent | MouseEvent, + directive: Directive, + ): void { + event.preventDefault(); + this.beginEdit.emit(directive); } protected async getLegacyContact(): Promise { @@ -47,16 +65,25 @@ export class DirectiveDisplayComponent implements OnInit { } } - protected async getDirective(): Promise { + protected async getDirectives(): Promise { try { - this.directive = await this.api.directive.get(this.account.getArchive()); + const fetchedDirectives = await this.api.directive.get( + this.account.getArchive(), + ); + this.directives = (fetchedDirectives ?? []).map((directive) => { + if (directive?.note) { + directive.note = directive.note.trim(); + } + return directive; + }); } catch { this.error = true; + this.message.showError({ + message: + 'There was an error loading the Archive Stewards. Please reload the page and try again.', + }); return; } - if (this.directive?.note) { - this.directive.note = this.directive.note.trim(); - } - this.loadedDirective.emit(this.directive); + this.loadedDirectives.emit(this.directives); } } diff --git a/src/app/directive/components/directive-display/test-utils.ts b/src/app/directive/components/directive-display/test-utils.ts index 31ade3de6..39a4dee57 100644 --- a/src/app/directive/components/directive-display/test-utils.ts +++ b/src/app/directive/components/directive-display/test-utils.ts @@ -31,6 +31,7 @@ export class MockDirectiveRepo { public static mockStewardId: number = null; public static mockStewardEmail: string = null; public static mockNote: string = null; + public static mockDirectives: DirectiveData[] | null = null; public static reset(): void { MockDirectiveRepo.failRequest = false; @@ -40,37 +41,47 @@ export class MockDirectiveRepo { MockDirectiveRepo.failLegacyRequest = false; MockDirectiveRepo.legacyContactName = null; MockDirectiveRepo.legacyContactEmail = null; + MockDirectiveRepo.mockDirectives = null; } - public createDirective(): DirectiveData { - const testDirectiveId = '39b2a5fa-3508-4030-91b6-21dc6ec7a1ab'; + public createDirective( + stewardEmail: string = MockDirectiveRepo.mockStewardEmail, + note: string = MockDirectiveRepo.mockNote, + directiveId: string = '39b2a5fa-3508-4030-91b6-21dc6ec7a1ab', + ): DirectiveData { return { - directiveId: testDirectiveId, + directiveId, archiveId: 1, type: 'admin', createdDt: new Date(), updatedDt: new Date(), trigger: { - directiveTriggerId: testDirectiveId, - directiveId: testDirectiveId, + directiveTriggerId: directiveId, + directiveId, type: 'admin', createdDt: new Date(), updatedDt: new Date(), }, steward: { - email: MockDirectiveRepo.mockStewardEmail, + email: stewardEmail, name: '', }, - note: MockDirectiveRepo.mockNote, + note, executionDt: null, }; } - public async get(): Promise { + public async get(): Promise { if (MockDirectiveRepo.failRequest) { throw new Error('Unit Testing: Forced Request Failure'); } - return this.createDirective(); + if (MockDirectiveRepo.mockDirectives) { + return MockDirectiveRepo.mockDirectives; + } + if (!MockDirectiveRepo.mockStewardEmail && !MockDirectiveRepo.mockNote) { + return []; + } + return [this.createDirective()]; } public async getLegacyContact(): Promise { diff --git a/src/app/directive/components/directive-edit/directive-edit.component.ts b/src/app/directive/components/directive-edit/directive-edit.component.ts index 99f3bd50a..24bd92b4e 100644 --- a/src/app/directive/components/directive-edit/directive-edit.component.ts +++ b/src/app/directive/components/directive-edit/directive-edit.component.ts @@ -14,7 +14,7 @@ import { MessageService } from '@shared/services/message/message.service'; }) export class DirectiveEditComponent implements OnInit { @Output() public savedDirective = new EventEmitter(); - @Input() public directive: Directive; + @Input() public directive: Directive | null = null; public email: string; public note: string; public waiting = false; @@ -30,7 +30,7 @@ export class DirectiveEditComponent implements OnInit { ngOnInit(): void { if (this.directive) { - this.email = this.directive.steward.email; + this.email = this.directive.steward?.email; this.note = this.directive.note; } this.archiveName = this.account.getArchive().fullName; diff --git a/src/app/shared/services/api/directive.repo.spec.ts b/src/app/shared/services/api/directive.repo.spec.ts index 55b44b2a9..3364ba144 100644 --- a/src/app/shared/services/api/directive.repo.spec.ts +++ b/src/app/shared/services/api/directive.repo.spec.ts @@ -49,13 +49,14 @@ describe('DirectiveRepo', () => { expect(repo).not.toBeNull(); }); - it('can get a Directive from an Archive', (done) => { + it('can get a list of Directives for an Archive', (done) => { repo.httpV2.setAuthToken('test_token'); repo .get(testArchive) - .then((directive) => { - expect(directive).not.toBeNull(); - expect(directive.note).toBe('Test Note'); + .then((directives) => { + expect(directives).not.toBeNull(); + expect(directives.length).toBe(1); + expect(directives[0].note).toBe('Test Note'); done(); }) .catch(done.fail); diff --git a/src/app/shared/services/api/directive.repo.ts b/src/app/shared/services/api/directive.repo.ts index b6b7f951b..5c7106395 100644 --- a/src/app/shared/services/api/directive.repo.ts +++ b/src/app/shared/services/api/directive.repo.ts @@ -9,14 +9,10 @@ import { getFirst } from '../http-v2/http-v2.service'; import { BaseRepo } from './base'; export class DirectiveRepo extends BaseRepo { - public async get(archive: ArchiveVO): Promise { - return await getFirst( - this.httpV2.get( - `/v2/directive/archive/${archive.archiveId}`, - {}, - Directive, - ), - ).toPromise(); + public async get(archive: ArchiveVO): Promise { + return await this.httpV2 + .get(`/v2/directive/archive/${archive.archiveId}`, {}, Directive) + .toPromise(); } public async create(directive: DirectiveCreateRequest): Promise { diff --git a/src/styles/_colors.scss b/src/styles/_colors.scss index 42c05a46e..c1fea09cb 100644 --- a/src/styles/_colors.scss +++ b/src/styles/_colors.scss @@ -6,6 +6,8 @@ $PR-orange: #ff9933; // VARIATIONS $PR-blue-light: #5261b7; $PR-blue-lightest: #41496e; +$PR-blue-100: #d0d1db; +$PR-blue-25: #f4f6fd; $PR-orange-light: #ffc779; $PR-orange-lightest: #ffead5;