diff --git a/common/constants.js b/common/constants.js index 24f62981b7f7962f08ddaac2e453456ed5c7117b..3930701456f635903a155fc824992572478ba505 100644 --- a/common/constants.js +++ b/common/constants.js @@ -1,6 +1,12 @@ (function(exports){ exports.ARIA_LABELS = { + // generic + CLOSE: 'Close', + OPEN: 'Open', + EXPAND: 'Expand', + COLLAPSE: 'Collapse', + // dataset specific SHOW_DATASET_PREVIEW: 'Show dataset preview', TOGGLE_EXPLORE_PANEL: `Toggle explore panel`, @@ -21,6 +27,7 @@ STATUS_PANEL: 'Viewre status panel', SHOW_FULL_STATUS_PANEL: 'Show full status panel', HIDE_FULL_STATUS_PANEL: 'Hide full status panel', + TOGGLE_SIDE_PANEL: 'Toggle side panel', // sharing module SHARE_BTN: `Share this view`, diff --git a/src/ui/databrowserModule/databrowser/databrowser.component.ts b/src/ui/databrowserModule/databrowser/databrowser.component.ts index f348a1596a30cb3c9cfff2a3a84d1e4496c2e746..252308bbe725f2eb905c3c4c48246b06860158ed 100644 --- a/src/ui/databrowserModule/databrowser/databrowser.component.ts +++ b/src/ui/databrowserModule/databrowser/databrowser.component.ts @@ -76,7 +76,7 @@ export class DataBrowser implements OnChanges, OnDestroy, OnInit { * TODO to be replaced with properly region UUIDs from KG */ return { - id: `${this.parcellation.name}/${r.name}`, + id: `${this.parcellation?.name || 'untitled_parcellation'}/${r.name}`, ...r, } }) diff --git a/src/ui/nehubaContainer/nehubaContainer.component.spec.ts b/src/ui/nehubaContainer/nehubaContainer.component.spec.ts index 1711cc5b984f271e292f0daea58d1c860aeda346..7bad2e4453a1e8c9feaf24e22dd4577180b96c5c 100644 --- a/src/ui/nehubaContainer/nehubaContainer.component.spec.ts +++ b/src/ui/nehubaContainer/nehubaContainer.component.spec.ts @@ -34,6 +34,15 @@ import { CommonModule } from '@angular/common' import { IMPORT_NEHUBA_INJECT_TOKEN } from './nehubaViewer/nehubaViewer.component' import { viewerStateHelperStoreName } from 'src/services/state/viewerState.store.helper' import { RenderViewOriginDatasetLabelPipe } from '../parcellationRegion/region.base' +import { By } from '@angular/platform-browser' +import { ARIA_LABELS } from 'common/constants' +import { NoopAnimationsModule } from '@angular/platform-browser/animations' + +const { + TOGGLE_SIDE_PANEL, + EXPAND, + COLLAPSE +} = ARIA_LABELS const _bigbrainJson = require('!json-loader!src/res/ext/bigbrain.json') const _bigbrainNehubaConfigJson = require('!json-loader!src/res/ext/bigbrainNehubaConfig.json') @@ -52,6 +61,7 @@ describe('> nehubaContainer.component.ts', () => { TestBed.configureTestingModule({ imports: [ + NoopAnimationsModule, PluginModule, WidgetModule, ComponentsModule, @@ -185,5 +195,202 @@ describe('> nehubaContainer.component.ts', () => { }) }) + + describe('> extended sidepanel hides and shows as expected', () => { + describe('> on start, if nothing is selected', () => { + beforeEach(() => { + const mockStore = TestBed.inject(MockStore) + const newState = { + ...defaultRootState, + viewerState: { + ...defaultRootState.viewerState, + fetchedTemplates: [ bigbrainJson ], + templateSelected: bigbrainJson, + parcellationSelected: bigbrainJson.parcellations[0] + }, + [viewerStateHelperStoreName]: { + fetchedAtlases: [ humanAtlas ], + selectedAtlasId: humanAtlas['@id'] + } + } + + mockStore.setState(newState) + }) + + it('> both should be shut', () => { + const fixture = TestBed.createComponent(NehubaContainer) + fixture.detectChanges() + expect( + fixture.componentInstance.matDrawerMain.opened + ).toEqual(false) + expect( + fixture.componentInstance.matDrawerMinor.opened + ).toEqual(false) + }) + + it('> opening via tab should result in only top drawer open', () => { + + const fixture = TestBed.createComponent(NehubaContainer) + fixture.detectChanges() + const toggleBtn = fixture.debugElement.query( By.css(`[aria-label="${TOGGLE_SIDE_PANEL}"]`) ) + toggleBtn.triggerEventHandler('click', null) + fixture.detectChanges() + + expect( + fixture.componentInstance.matDrawerMain.opened + ).toEqual(true) + expect( + fixture.componentInstance.matDrawerMinor.opened + ).toEqual(false) + }) + + it('> on opening top drawer, explore features should not be present', () => { + + const fixture = TestBed.createComponent(NehubaContainer) + fixture.detectChanges() + const toggleBtn = fixture.debugElement.query( By.css(`[aria-label="${TOGGLE_SIDE_PANEL}"]`) ) + toggleBtn.triggerEventHandler('click', null) + fixture.detectChanges() + const expandRegionFeatureBtn = fixture.debugElement.query( By.css(`mat-drawer[data-mat-drawer-open="true"] [aria-label="${EXPAND}"]`) ) + expect(expandRegionFeatureBtn).toBeNull() + }) + it('> collapse btn should not be visible', () => { + + const fixture = TestBed.createComponent(NehubaContainer) + fixture.detectChanges() + const toggleBtn = fixture.debugElement.query( By.css(`[aria-label="${TOGGLE_SIDE_PANEL}"]`) ) + toggleBtn.triggerEventHandler('click', null) + fixture.detectChanges() + const expandRegionFeatureBtn = fixture.debugElement.query( By.css(`mat-drawer[data-mat-drawer-open="true"] [aria-label="${COLLAPSE}"]`) ) + expect(expandRegionFeatureBtn).toBeNull() + }) + }) + + describe('> on start, if something is selected', () => { + beforeEach(() => { + const mockStore = TestBed.inject(MockStore) + const newState = { + ...defaultRootState, + viewerState: { + ...defaultRootState.viewerState, + fetchedTemplates: [ bigbrainJson ], + templateSelected: bigbrainJson, + parcellationSelected: bigbrainJson.parcellations[0], + regionsSelected: [{ + name: "foobar" + }] + }, + [viewerStateHelperStoreName]: { + fetchedAtlases: [ humanAtlas ], + selectedAtlasId: humanAtlas['@id'] + } + } + + mockStore.setState(newState) + }) + it('> both should be open', () => { + const fixture = TestBed.createComponent(NehubaContainer) + fixture.detectChanges() + expect( + fixture.componentInstance.matDrawerMain.opened + ).toEqual(true) + expect( + fixture.componentInstance.matDrawerMinor.opened + ).toEqual(true) + + expect( + fixture.componentInstance.navSideDrawerMainSwitch.switchState + ).toEqual(true) + expect( + fixture.componentInstance.navSideDrawerMinorSwitch.switchState + ).toEqual(true) + }) + + it('> closing main drawer via tag should close both', () => { + const fixture = TestBed.createComponent(NehubaContainer) + fixture.detectChanges() + const toggleBtn = fixture.debugElement.query( By.css(`[aria-label="${TOGGLE_SIDE_PANEL}"]`) ) + toggleBtn.triggerEventHandler('click', null) + fixture.detectChanges() + expect( + fixture.componentInstance.matDrawerMain.opened + ).toEqual(false) + + /** + * TODO investigate why openedStart/closedStart events fail to fire + */ + // expect( + // fixture.componentInstance.matDrawerMinor.opened + // ).toEqual(false) + + // expect( + // fixture.componentInstance.navSideDrawerMainSwitch.switchState + // ).toEqual(false) + // expect( + // fixture.componentInstance.navSideDrawerMinorSwitch.switchState + // ).toEqual(false) + }) + it('> collapse btn should be visible', () => { + + const fixture = TestBed.createComponent(NehubaContainer) + fixture.detectChanges() + const collapseRegionFeatureBtn = fixture.debugElement.query( By.css(`mat-drawer[data-mat-drawer-open="true"] [aria-label="${COLLAPSE}"]`) ) + expect(collapseRegionFeatureBtn).not.toBeNull() + }) + it('> clicking on collapse btn should minimize 1 drawer', () => { + + const fixture = TestBed.createComponent(NehubaContainer) + fixture.detectChanges() + const collapseRegionFeatureBtn = fixture.debugElement.query( By.css(`mat-drawer[data-mat-drawer-open="true"] [aria-label="${COLLAPSE}"]`) ) + collapseRegionFeatureBtn.triggerEventHandler('click', null) + fixture.detectChanges() + expect( + fixture.componentInstance.matDrawerMain.opened + ).toEqual(true) + + /** + * TODO investigate why property does not get updated + */ + // expect( + // fixture.componentInstance.matDrawerMinor.opened + // ).toEqual(false) + + expect( + fixture.componentInstance.navSideDrawerMainSwitch.switchState + ).toEqual(true) + expect( + fixture.componentInstance.navSideDrawerMinorSwitch.switchState + ).toEqual(false) + }) + + it('> on minimize drawer, clicking expand btn should expand everything', () => { + const fixture = TestBed.createComponent(NehubaContainer) + fixture.detectChanges() + const collapseRegionFeatureBtn = fixture.debugElement.query( By.css(`mat-drawer[data-mat-drawer-open="true"] [aria-label="${COLLAPSE}"]`) ) + collapseRegionFeatureBtn.triggerEventHandler('click', null) + fixture.detectChanges() + const expandRegionFeatureBtn = fixture.debugElement.query( By.css(`mat-drawer[data-mat-drawer-open="true"] [aria-label="${EXPAND}"]`) ) + expandRegionFeatureBtn.triggerEventHandler('click', null) + fixture.detectChanges() + + expect( + fixture.componentInstance.matDrawerMain.opened + ).toEqual(true) + expect( + fixture.componentInstance.matDrawerMinor.opened + ).toEqual(true) + + expect( + fixture.componentInstance.navSideDrawerMainSwitch.switchState + ).toEqual(true) + /** + * TODO figoure out why switch state is updated async, and karma can't force update state + */ + // expect( + // fixture.componentInstance.navSideDrawerMinorSwitch.switchState + // ).toEqual(true) + }) + }) + }) }) }) \ No newline at end of file diff --git a/src/ui/nehubaContainer/nehubaContainer.component.ts b/src/ui/nehubaContainer/nehubaContainer.component.ts index 8b9d7528c70dfd60c590340d22ff077f3e8d6a4d..a4bbf234392b95b90e37080c5900ee80048dadd0 100644 --- a/src/ui/nehubaContainer/nehubaContainer.component.ts +++ b/src/ui/nehubaContainer/nehubaContainer.component.ts @@ -84,6 +84,9 @@ const sortByFreshness: (acc: any[], curr: any[]) => any[] = (acc, curr) => { const { ZOOM_IN, ZOOM_OUT, + TOGGLE_SIDE_PANEL, + EXPAND, + COLLAPSE } = ARIA_LABELS @Component({ @@ -129,8 +132,13 @@ const { export class NehubaContainer implements OnInit, OnChanges, OnDestroy { + public _tmp: number = 0 public ARIA_LABEL_ZOOM_IN = ZOOM_IN public ARIA_LABEL_ZOOM_OUT = ZOOM_OUT + public ARIA_LABEL_TOGGLE_SIDE_PANEL = TOGGLE_SIDE_PANEL + public ARIA_LABEL_EXPAND = EXPAND + public ARIA_LABEL_COLLAPSE = COLLAPSE + public ID_MESH_LOADING_STATUS = MESH_LOADING_STATUS @ViewChild(NehubaViewerContainerDirective,{static: true}) diff --git a/src/ui/nehubaContainer/nehubaContainer.style.css b/src/ui/nehubaContainer/nehubaContainer.style.css index e2f28b86488fe75027e58ba237afa99a62d2e779..e4db541a0072a4b05c0af33d171b268d7eb48d23 100644 --- a/src/ui/nehubaContainer/nehubaContainer.style.css +++ b/src/ui/nehubaContainer/nehubaContainer.style.css @@ -180,3 +180,8 @@ div#scratch-pad margin-right: 1rem; text-align: right; } + +.tab-toggle-container +{ + margin-top: 1.5rem; +} diff --git a/src/ui/nehubaContainer/nehubaContainer.template.html b/src/ui/nehubaContainer/nehubaContainer.template.html index 4f1cd43013ca64cedb577b1e6d5c3f0d079ae055..aff06dee64595cc16c52c45addf3260b67e3714f 100644 --- a/src/ui/nehubaContainer/nehubaContainer.template.html +++ b/src/ui/nehubaContainer/nehubaContainer.template.html @@ -48,6 +48,7 @@ <!-- sidenav-content --> <mat-drawer class="box-shadow-none border-0 pe-none bg-none col-10 col-sm-10 col-md-5 col-lg-4 col-xl-3 col-xxl-2" mode="side" + [attr.data-mat-drawer-open]="matDrawerMaster.opened" [opened]="sideNavMasterSwitch.switchState" [autoFocus]="false" (closedStart)="sideNavSwitch.switchState && matDrawerMinor.close()" @@ -61,9 +62,11 @@ </div> <button mat-raised-button + *ngIf="selectedRegions.length > 0" + [attr.aria-label]="ARIA_LABEL_EXPAND" (click)="matDrawerMinor.open()" class="explore-btn pe-all" - [color]="selectedRegions.length > 0 ? 'accent' : 'basic'"> + color="accent"> Explore regional features & connectivity </button> </mat-drawer> @@ -81,8 +84,9 @@ </ng-content> </div> - <div *ngIf="viewerLoaded" class="position-absolute z-index-6 top-0 left-0 pe-none m-2"> + <div *ngIf="viewerLoaded" class="position-absolute z-index-6 top-0 left-0 pe-none tab-toggle-container"> <button mat-raised-button + [attr.aria-label]="ARIA_LABEL_TOGGLE_SIDE_PANEL" class="pe-all tab-toggle" (click)="sideNavMasterSwitch.toggle()" [color]="!sideNavMasterSwitch.switchState && selectedRegions.length > 0 ? 'accent' : 'basic'"> @@ -95,7 +99,7 @@ <!-- drawer #2 --> <mat-drawer-container - [iav-switch-initstate]="true" + [iav-switch-initstate]="selectedRegions.length > 0" iav-switch #sideNavSwitch="iavSwitch" class="mat-drawer-content-overflow-visible w-100 h-100 position-absolute invisible" @@ -104,11 +108,13 @@ <!-- sidenav-content --> <mat-drawer class="darker-bg iv-custom-comp visible col-10 col-sm-10 col-md-5 col-lg-4 col-xl-3 col-xxl-2 d-flex flex-column pe-all" mode="push" + [attr.data-mat-drawer-open]="matDrawerMinor.opened" [autoFocus]="false" #matDrawerMinor="matDrawer" (openedChange)="$event && sideNavSwitch.open()" [disableClose]="true" [@openClose]="sideNavMasterSwitch.switchState && sideNavSwitch.switchState ? 'open' : 'closed'" + (@openClose.start)="_tmp=1" (@openClose.done)="$event.toState === 'closed' && matDrawerMinor.close()"> <div class="position-relative d-flex flex-column h-100"> @@ -167,6 +173,7 @@ <!-- collapse btn --> <div class="h-0 w-100 collapse-position d-flex flex-column justify-content-end align-items-center"> <button mat-raised-button class="mat-elevation-z8" + [attr.aria-label]="ARIA_LABEL_COLLAPSE" (click)="sideNavSwitch.close()" [color]="selectedRegions.length > 0 ? 'accent' : 'basic'"> <i class="fas fa-chevron-up"></i>