diff --git a/src/atlasViewer/atlasViewer.component.ts b/src/atlasViewer/atlasViewer.component.ts index f779e44fa5192bfaf37fb977f0d98bd494799427..5fb6bb3e0e9631f309769780ef9cb7ce307129d1 100644 --- a/src/atlasViewer/atlasViewer.component.ts +++ b/src/atlasViewer/atlasViewer.component.ts @@ -10,12 +10,10 @@ import { } from "@angular/core"; import { Store, select, ActionsSubject } from "@ngrx/store"; import { - ViewerStateInterface, isDefined, safeFilter, - UIStateInterface, SHOW_SIDE_PANEL_CONNECTIVITY, - EXPAND_SIDE_PANEL_CURRENT_VIEW + EXPAND_SIDE_PANEL_CURRENT_VIEW, IavRootStoreInterface } from "../services/stateStore.service"; import {Observable, Subscription, combineLatest, interval, merge, of} from "rxjs"; import { @@ -39,7 +37,6 @@ import { TabsetComponent } from "ngx-bootstrap/tabs"; import { LocalFileService } from "src/services/localFile.service"; import { MatDialog, MatDialogRef, MatSnackBar, MatSnackBarRef, MatBottomSheet, MatBottomSheetRef } from "@angular/material"; import {SearchSideNav} from "src/ui/searchSideNav/searchSideNav.component"; -import {CaptureClickListenerDirective} from "src/util/directives/captureClickListener.directive"; import { CLOSE_SIDE_PANEL, OPEN_SIDE_PANEL @@ -76,7 +73,6 @@ export class AtlasViewer implements OnDestroy, OnInit, AfterViewInit { @ViewChild(NehubaContainer) nehubaContainer: NehubaContainer @ViewChild(FixedMouseContextualContainerDirective) rClContextualMenu: FixedMouseContextualContainerDirective - @ViewChild(CaptureClickListenerDirective) captureClickListenerDirective: CaptureClickListenerDirective @ViewChild('mobileMenuTabs') mobileMenuTabs: TabsetComponent @@ -121,14 +117,14 @@ export class AtlasViewer implements OnDestroy, OnInit, AfterViewInit { public unsupportedPreviewIdx: number = 0 public unsupportedPreviews: any[] = UNSUPPORTED_PREVIEW - public sidePanelOpen$: Observable<boolean> + public sidePanelIsOpen$: Observable<boolean> onhoverSegmentsForFixed$: Observable<string[]> regionToolsMenuVisible = false constructor( - private store: Store<ViewerStateInterface | UIStateInterface>, + private store: Store<IavRootStoreInterface>, private widgetServices: WidgetServices, private constantsService: AtlasViewerConstantsServices, public apiService: AtlasViewerAPIServices, @@ -168,10 +164,10 @@ export class AtlasViewer implements OnDestroy, OnInit, AfterViewInit { map(state => state.focusedSidePanel) ) - this.sidePanelOpen$ = this.store.pipe( + this.sidePanelIsOpen$ = this.store.pipe( select('uiState'), filter(state => isDefined(state)), - map(state => state.sidePanelOpen) + map(state => state.sidePanelIsOpen) ) this.selectedRegions$ = this.store.pipe( @@ -438,13 +434,6 @@ export class AtlasViewer implements OnDestroy, OnInit, AfterViewInit { this.store.dispatch({type: opened? CLOSE_SIDE_PANEL : OPEN_SIDE_PANEL}) } - showConnectivity(event) { - this.toggleSideNavMenu(false) - this.store.dispatch({type: EXPAND_SIDE_PANEL_CURRENT_VIEW}) - this.store.dispatch({type: SHOW_SIDE_PANEL_CONNECTIVITY}) - this.searchSideNav.connectivityActive.next(event) - } - /** * For completeness sake. Root element should never be destroyed. */ diff --git a/src/atlasViewer/atlasViewer.template.html b/src/atlasViewer/atlasViewer.template.html index a0bd8023c7cc75c902719ca2e84e9ffe2afa5c3b..a542ca229d490ba2311f16ebd3d115a4e3d1aad5 100644 --- a/src/atlasViewer/atlasViewer.template.html +++ b/src/atlasViewer/atlasViewer.template.html @@ -43,11 +43,11 @@ <div class="atlas-container" (drag-drop)="localFileService.handleFileDrop($event)"> <ui-nehuba-container iav-mouse-hover #iavMouseHoverEl="iavMouseHover" - [currentOnHoverObs$]="iavMouseHoverEl.currentOnHoverObs$" - [currentOnHover]="iavMouseHoverEl.currentOnHoverObs$ | async" - iav-captureClickListenerDirective - (mouseDownEmitter)="mouseDownNehuba($event)" - (mapClicked)="mouseUpNehuba($event)"> + [currentOnHoverObs$]="iavMouseHoverEl.currentOnHoverObs$" + [currentOnHover]="iavMouseHoverEl.currentOnHoverObs$ | async" + iav-captureClickListenerDirective + (iav-captureClickListenerDirective-onMousedown)="mouseDownNehuba($event)" + (iav-captureClickListenerDirective-onClick)="mouseUpNehuba($event)"> </ui-nehuba-container> <div class="z-index-10 position-absolute pe-none w-100 h-100"> @@ -57,7 +57,7 @@ class="w-100 h-100 bg-none mat-drawer-content-overflow-visible"> <mat-drawer mode="push" class="col-10 col-sm-10 col-md-4 col-lg-3 col-xl-2 p-2 bg-none box-shadow-none overflow-visible" - [disableClose]="true" [autoFocus]="false" [opened]="sidePanelOpen$ | async" #sideNavDrawer> + [disableClose]="true" [autoFocus]="false" [opened]="sidePanelIsOpen$ | async" #sideNavDrawer> <search-side-nav (dismiss)="toggleSideNavMenu(true)" class="h-100 d-block overflow-visible" #searchSideNav> </search-side-nav> @@ -146,34 +146,12 @@ [region]="onHoverRegion" [isSelected]="selectedRegions$ | async | includes : onHoverRegion : compareFn" [hasConnectivity]="selectedParcellation && selectedParcellation.name.includes('JuBrain Cytoarchitectonic Atlas')" - (exploreConnectivity) = "showConnectivity($event)" > </region-menu> </ng-container> </ng-container> </div> - -<!-- <panel-component class="shadow p-0 m-0" fixedMouseContextualContainerDirective>--> -<!-- <div body class="pe-all" *ngIf="(onhoverSegmentsForFixed$ | async) as onHoverSegments">--> -<!-- <mat-card *ngIf="onHoverSegments.length > 0 && regionToolsMenuVisible" class="d-flex flex-column p-0">--> -<!-- <div *ngFor="let onHoverRegion of onHoverSegments; let first = first"--> -<!-- class="border-dark rounded">--> -<!-- <mat-divider *ngIf="!first"></mat-divider>--> - -<!-- <region-menu--> -<!-- [region]="onHoverRegion"--> -<!-- [hasConnectivity]="selectedParcellation && selectedParcellation.name.includes('JuBrain Cytoarchitectonic Atlas')"--> -<!-- [pn]="selectedParcellation && selectedParcellation.name && selectedParcellation.name.length? selectedParcellation.name : 'CY'"--> -<!-- (exploreConnectivity) = "showConnectivity($event);">--> -<!-- </region-menu>--> - -<!-- </div>--> -<!-- </mat-card>--> -<!-- </div>--> - -<!-- </panel-component>--> - </layout-floating-container> <!-- required for manufacturing plugin templates --> diff --git a/src/main.module.ts b/src/main.module.ts index 2e0ecb9d4831e95a3753281999991c5b8d74a4d7..d1abd75d386310cb6f49c2a0b6766eb66dc98283 100644 --- a/src/main.module.ts +++ b/src/main.module.ts @@ -55,6 +55,7 @@ import 'src/res/css/version.css' import 'src/theme.scss' import 'src/res/css/extra_styles.css' import { AtlasViewerHistoryUseEffect } from "./atlasViewer/atlasViewer.history.service"; +import {UiStateUseEffect} from "src/services/state/uiState.store"; @NgModule({ imports : [ @@ -78,7 +79,8 @@ import { AtlasViewerHistoryUseEffect } from "./atlasViewer/atlasViewer.history.s ViewerStateUseEffect, NgViewerUseEffect, PluginServiceuseEffect, - AtlasViewerHistoryUseEffect + AtlasViewerHistoryUseEffect, + UiStateUseEffect ]), StoreModule.forRoot({ pluginState, diff --git a/src/services/state/uiState.store.ts b/src/services/state/uiState.store.ts index 5c589fa8f79032c2eb495491e6b7424da0a27df6..06e3025f7204012aa2af8efb3c83d5403c87ff7f 100644 --- a/src/services/state/uiState.store.ts +++ b/src/services/state/uiState.store.ts @@ -1,8 +1,11 @@ -import { Action } from '@ngrx/store' -import { TemplateRef } from '@angular/core'; +import {Action, select, Store} from '@ngrx/store' +import {Injectable, TemplateRef} from '@angular/core'; import { LOCAL_STORAGE_CONST, COOKIE_VERSION, KG_TOS_VERSION } from 'src/util/constants' -import { GENERAL_ACTION_TYPES } from '../stateStore.service' +import {GENERAL_ACTION_TYPES, IavRootStoreInterface} from '../stateStore.service' +import {Effect} from "@ngrx/effects"; +import {Observable} from "rxjs"; +import {filter, map, mapTo, scan, startWith} from "rxjs/operators"; export const defaultState: StateInterface = { mouseOverSegments: [], @@ -12,9 +15,9 @@ export const defaultState: StateInterface = { mouseOverUserLandmark: null, focusedSidePanel: null, - sidePanelOpen: true, + sidePanelIsOpen: true, sidePanelManualCollapsibleView: '', - sidePanelCurrentViewOpened: false, + sidePanelExploreCurrentViewIsOpen: false, snackbarMessage: null, @@ -64,23 +67,23 @@ export const getStateStore = ({ state = defaultState } = {}) => (prevState:State case OPEN_SIDE_PANEL: return { ...prevState, - sidePanelOpen: true + sidePanelIsOpen: true } case CLOSE_SIDE_PANEL: return { ...prevState, - sidePanelOpen: false + sidePanelIsOpen: false } case EXPAND_SIDE_PANEL_CURRENT_VIEW: return { ...prevState, - sidePanelCurrentViewOpened: true + sidePanelExploreCurrentViewIsOpen: true } case COLLAPSE_SIDE_PANEL_CURRENT_VIEW: return { ...prevState, - sidePanelCurrentViewOpened: false + sidePanelExploreCurrentViewIsOpen: false } case SHOW_SIDE_PANEL_CONNECTIVITY: @@ -143,9 +146,9 @@ export interface StateInterface{ } segment: any | null }[] - sidePanelOpen: boolean + sidePanelIsOpen: boolean sidePanelManualCollapsibleView: 'Connectivity' | '' | null - sidePanelCurrentViewOpened: boolean + sidePanelExploreCurrentViewIsOpen: boolean mouseOverSegment: any | number mouseOverLandmark: any @@ -178,6 +181,45 @@ export interface ActionInterface extends Action{ payload: any } +@Injectable({ + providedIn:'root' +}) + +export class UiStateUseEffect{ + + private numRegionSelectedWithHistory$: Observable<any[]> + + @Effect() + public sidePanelOpen$: Observable<any> + + @Effect() + public viewCurrentOpen$: Observable<any> + + constructor(store$: Store<IavRootStoreInterface>) { + this.numRegionSelectedWithHistory$ = store$.pipe( + select('viewerState'), + select('regionsSelected'), + map(arr => arr.length), + startWith(0), + scan((acc, curr) => [curr, ...acc], []) + ) + + this.sidePanelOpen$ = this.numRegionSelectedWithHistory$.pipe( + filter(([curr, prev]) => prev === 0 && curr > 0), + mapTo({ + type: OPEN_SIDE_PANEL + }) + ) + + this.viewCurrentOpen$ = this.numRegionSelectedWithHistory$.pipe( + filter(([curr, prev]) => prev === 0 && curr > 0), + mapTo({ + type: EXPAND_SIDE_PANEL_CURRENT_VIEW + }) + ) + } +} + export const MOUSE_OVER_SEGMENT = `MOUSE_OVER_SEGMENT` export const MOUSE_OVER_SEGMENTS = `MOUSE_OVER_SEGMENTS` export const MOUSE_OVER_LANDMARK = `MOUSE_OVER_LANDMARK` diff --git a/src/services/state/viewerState.store.ts b/src/services/state/viewerState.store.ts index c30a83fac4e55d9627f53b7b5f9415fd65254d07..dc19ff5870977ce4d65c90158b3c5b462f27550a 100644 --- a/src/services/state/viewerState.store.ts +++ b/src/services/state/viewerState.store.ts @@ -23,6 +23,7 @@ export interface StateInterface{ dedicatedView : string[] loadedNgLayers: NgLayerInterface[] + connectivityRegion: string | null } export interface ActionInterface extends Action{ @@ -43,6 +44,8 @@ export interface ActionInterface extends Action{ navigation? : any payload: any + + connectivityRegion?: string } export const defaultState:StateInterface = { @@ -55,7 +58,8 @@ export const defaultState:StateInterface = { dedicatedView: null, navigation: null, parcellationSelected: null, - templateSelected: null + templateSelected: null, + connectivityRegion: '' } export const getStateStore = ({ state = defaultState } = {}) => (prevState:Partial<StateInterface> = state, action:ActionInterface) => { @@ -176,6 +180,16 @@ export const getStateStore = ({ state = defaultState } = {}) => (prevState:Parti case GENERAL_ACTION_TYPES.APPLY_STATE: const { viewerState } = (action as any).state return viewerState + case SET_CONNECTIVITY_REGION: + return { + ...prevState, + connectivityRegion: action.connectivityRegion + } + case CLEAR_CONNECTIVITY_REGION: + return { + ...prevState, + connectivityRegion: '' + } default : return prevState } @@ -215,6 +229,8 @@ export const USER_LANDMARKS = `USER_LANDMARKS` export const ADD_TO_REGIONS_SELECTION_WITH_IDS = `ADD_TO_REGIONS_SELECTION_WITH_IDS` export const NEHUBA_LAYER_CHANGED = `NEHUBA_LAYER_CHANGED` +export const SET_CONNECTIVITY_REGION = `SET_CONNECTIVITY_REGION` +export const CLEAR_CONNECTIVITY_REGION = `CLEAR_CONNECTIVITY_REGION` @Injectable({ providedIn: 'root' diff --git a/src/ui/connectivityBrowser/connectivityBrowser.component.ts b/src/ui/connectivityBrowser/connectivityBrowser.component.ts index c6499368cdac35bbaeac282ea9eca22790bfe83b..13bb7c8cd70e5cb250aba98a41a71b10dbd34903 100644 --- a/src/ui/connectivityBrowser/connectivityBrowser.component.ts +++ b/src/ui/connectivityBrowser/connectivityBrowser.component.ts @@ -1,19 +1,16 @@ import { - AfterViewInit, + AfterViewInit, ChangeDetectorRef, Component, ElementRef, - EventEmitter, - Inject, - Input, OnDestroy, - Output, ViewChild } from "@angular/core"; import {AtlasViewerConstantsServices} from "src/atlasViewer/atlasViewer.constantService.service"; import {Observable, Subject, Subscription} from "rxjs"; import {select, Store} from "@ngrx/store"; -import {HIDE_SIDE_PANEL_CONNECTIVITY, safeFilter} from "src/services/stateStore.service"; -import {distinctUntilChanged, map} from "rxjs/operators"; +import {HIDE_SIDE_PANEL_CONNECTIVITY, isDefined, safeFilter} from "src/services/stateStore.service"; +import {distinctUntilChanged, filter, map} from "rxjs/operators"; +import {CLEAR_CONNECTIVITY_REGION, SET_CONNECTIVITY_REGION} from "src/services/state/viewerState.store"; @Component({ selector: 'connectivity-browser', @@ -21,43 +18,60 @@ import {distinctUntilChanged, map} from "rxjs/operators"; }) export class ConnectivityBrowserComponent implements AfterViewInit, OnDestroy { - @Input() region: string = '' + private region: string private connectedAreas = [] + private connectivityRegion$: Observable<any> private selectedParcellation$: Observable<any> private subscriptions: Subscription[] = [] private selectedParcellation: any public collapseMenu = -1 public allRegions = [] - public defaultColorMap + public defaultColorMap: Map<string, Map<number, {red: number, green: number, blue: number}>> + private noConnectivityForRegion = false math = Math @ViewChild('connectivityComponent', {read: ElementRef}) connectivityComponentElement: ElementRef - constructor(private constantService: AtlasViewerConstantsServices, private store$: Store<any> ){ + constructor(private constantService: AtlasViewerConstantsServices, private store$: Store<any> , private changeDetectionRef : ChangeDetectorRef + ){ this.selectedParcellation$ = this.store$.pipe( select('viewerState'), - safeFilter('parcellationSelected'), + filter(state=>isDefined(state)&&isDefined(state.parcellationSelected)), map(state=>state.parcellationSelected), distinctUntilChanged(), ) + + this.connectivityRegion$ = this.store$.pipe( + select('viewerState'), + safeFilter('connectivityRegion'), + map(state => state.connectivityRegion) + ) + } ngAfterViewInit(): void { this.subscriptions.push( this.selectedParcellation$.subscribe(parcellation => { this.selectedParcellation = parcellation - if (parcellation.regions && parcellation.regions.length) { - this.allRegions = [] - this.getAllRegionsFromParcellation(parcellation.regions) - if (this.defaultColorMap) { - this.saveAndDisableExistingColorTemplate() + if (parcellation && parcellation.name && parcellation.name === 'JuBrain Cytoarchitectonic Atlas') { + this.noConnectivityForRegion = false + if (parcellation.regions && parcellation.regions.length) { + this.allRegions = [] + this.getAllRegionsFromParcellation(parcellation.regions) + if (this.defaultColorMap) { + this.saveAndDisableExistingColorTemplate() + } } + } else { + this.noConnectivityForRegion = true } - - + }), + this.connectivityRegion$.subscribe(cr => { + this.region = cr + this.changeDetectionRef.detectChanges(); }) ) @@ -76,19 +90,27 @@ export class ConnectivityBrowserComponent implements AfterViewInit, OnDestroy { this.subscriptions.forEach(s => s.unsubscribe()) } - public closeConnectivityView() { + updateConnevtivityRegion(regionName) { + this.store$.dispatch({ + type: SET_CONNECTIVITY_REGION, + connectivityRegion: regionName + }) + } + public closeConnectivityView() { this.setDefaultMap() this.store$.dispatch({ type: HIDE_SIDE_PANEL_CONNECTIVITY, }) + this.store$.dispatch({ + type: CLEAR_CONNECTIVITY_REGION + }) } setDefaultMap() { this.allRegions.forEach(r => { if (r && r.ngId && r.rgb) { - // @ts-ignore this.defaultColorMap.get(r.ngId).set(r.labelIndex, {red: r.rgb[0], green: r.rgb[1], blue: r.rgb[2]}) } getWindow().interactiveViewer.viewerHandle.applyLayersColourMap(this.defaultColorMap) @@ -102,14 +124,13 @@ export class ConnectivityBrowserComponent implements AfterViewInit, OnDestroy { this.defaultColorMap = new Map(getWindow().interactiveViewer.viewerHandle.getLayersSegmentColourMap()) - const existingMap = (getWindow().interactiveViewer.viewerHandle.getLayersSegmentColourMap()) + const existingMap: Map<string, Map<number, {red: number, green: number, blue: number}>> = (getWindow().interactiveViewer.viewerHandle.getLayersSegmentColourMap()) const map = new Map(existingMap) this.allRegions.forEach(r => { if (r.ngId) { - // @ts-ignore map.get(r.ngId).set(r.labelIndex, {red: 255, green: 255, blue: 255}) } }) diff --git a/src/ui/connectivityBrowser/connectivityBrowser.template.html b/src/ui/connectivityBrowser/connectivityBrowser.template.html index 31dba5728019e20c2ae408b7060e1cc7c1bebcfd..3963b9eac18dac600c919323ca0f3c5a3a7d62af 100644 --- a/src/ui/connectivityBrowser/connectivityBrowser.template.html +++ b/src/ui/connectivityBrowser/connectivityBrowser.template.html @@ -1,9 +1,9 @@ -<div class="w-100 h-100 overflow-auto d-block d-flex flex-column pb-2" #connectivityComponent> +<div class="w-100 h-100 overflow-auto d-block d-flex flex-column pb-2" #connectivityComponent *ngIf="!noConnectivityForRegion; else noConnectivity"> + <!--ToDo set show-description="true" when data will available--> <hbp-connectivity-matrix-row [region]="region" theme="dark" loadurl="https://connectivityquery-connectivity.apps-dev.hbp.eu/connectivity" - show-description="true" show-export="true" show-source="true" show-title="true" @@ -24,7 +24,7 @@ </span> <div class="d-flex align-items-center justify-content-around"> <small class="d-flex flex-column align-items-center w-100"> - + <!--ToDo Implement function when Hemisphere information will be available --> <!-- *ngIf="(selectedRegions$ | async) as selectedRegions"--> <!-- (click)="toggleRegionWithId(region.ngId, region.labelIndex, regionIsSelected(selectedRegions, region.ngId, region.labelIndex))">--> @@ -32,6 +32,7 @@ <!-- <i class="fas fa-hand-pointer mt-n1"></i>--> <span class="fa-stack fa-1x "> <i class="fas fa-hand-pointer fa-stack-1x"></i> + <!--ToDo Implement function when Hemisphere information will be available --> <!-- <i class="fas fa-slash fa-stack-1x fa-inverse"--> <!-- *ngIf="regionIsSelected(selectedRegions, region.ngId, region.labelIndex)"></i>--> </span> @@ -48,8 +49,7 @@ </small> <small class="d-flex flex-column align-items-center w-100"> - <button mat-icon-button class="border" (click)="region = connectedAreas[collapseMenu].name"> - <!--(click)="changeConnectivityRegion('connection.name')"--> + <button mat-icon-button class="border" (click)="updateConnevtivityRegion(connectedAreas[collapseMenu].name)"> <i class="fab fa-connectdevelop mt-n1"></i> </button> Connectivity @@ -60,4 +60,18 @@ </div> </hbp-connectivity-matrix-row> -</div> \ No newline at end of file +</div> + +<ng-template #noConnectivity> + <mat-card class="p-2 w-100 h-100 overflow-auto d-block"> + <div class="w-100 d-flex justify-content-end mt-3"><span + class="cursorPointer" (click)="closeConnectivityView()">X</span></div> + <h5> + Connectivity Matrix Browser + </h5> + <div> + No Connectivity for selected Parcellation! + </div> + + </mat-card> +</ng-template> \ No newline at end of file diff --git a/src/ui/parcellationRegion/region.base.ts b/src/ui/parcellationRegion/region.base.ts index 5500e98368c379c23a4ebfdb2659e69735656ad9..427549df3e1a3d8c6750405b90ded5c31061feed 100644 --- a/src/ui/parcellationRegion/region.base.ts +++ b/src/ui/parcellationRegion/region.base.ts @@ -1,7 +1,13 @@ import { Store } from "@ngrx/store"; import {EventEmitter, Input, Output} from "@angular/core"; import { VIEWERSTATE_CONTROLLER_ACTION_TYPES } from "../viewerStateController/viewerState.base"; -import { IavRootStoreInterface } from "src/services/stateStore.service"; +import { + CLOSE_SIDE_PANEL, + EXPAND_SIDE_PANEL_CURRENT_VIEW, + IavRootStoreInterface, OPEN_SIDE_PANEL, + SHOW_SIDE_PANEL_CONNECTIVITY +} from "src/services/stateStore.service"; +import {SET_CONNECTIVITY_REGION} from "src/services/state/viewerState.store"; export class RegionBase{ @@ -35,4 +41,15 @@ export class RegionBase{ payload: { region } }) } + + pushConnectivityRegion(regionName) { + this.store$.dispatch({type: OPEN_SIDE_PANEL}) + this.store$.dispatch({type: EXPAND_SIDE_PANEL_CURRENT_VIEW}) + this.store$.dispatch({type: SHOW_SIDE_PANEL_CONNECTIVITY}) + + this.store$.dispatch({ + type: SET_CONNECTIVITY_REGION, + connectivityRegion: regionName + }) + } } \ No newline at end of file diff --git a/src/ui/parcellationRegion/regionMenu/regionMenu.template.html b/src/ui/parcellationRegion/regionMenu/regionMenu.template.html index 6b6a0de3dee52edf1b826424bdd9c4ec372ba4ee..0782175873a8a2712efe70680a15aa2d74382bfa 100644 --- a/src/ui/parcellationRegion/regionMenu/regionMenu.template.html +++ b/src/ui/parcellationRegion/regionMenu/regionMenu.template.html @@ -5,7 +5,7 @@ <mat-card-content> {{ region.description }} </mat-card-content> - <mat-card-actions class="d-flex flex-row"> + <mat-card-actions class="d-flex flex-row flex-wrap"> <button mat-button (click)="toggleRegionSelected()" [color]="isSelected ? 'primary': 'basic'"> @@ -20,8 +20,8 @@ Navigate </span> </button> - <button *ngIf="hasConnectivity" mat-button (click)="exploreConnectivity.emit(region.name)"> - <i class="fas fa-map-marked-alt"></i> + <button *ngIf="hasConnectivity" mat-button (click)="pushConnectivityRegion(region.name)"> + <i class="fab fa-connectdevelop"></i> <span> Connectivity </span> diff --git a/src/ui/regionToolsMenu/regionMenu.component.ts b/src/ui/regionToolsMenu/regionMenu.component.ts deleted file mode 100644 index 86d8dade3297f78df6c619b1005eb6f4d01b6c0b..0000000000000000000000000000000000000000 --- a/src/ui/regionToolsMenu/regionMenu.component.ts +++ /dev/null @@ -1,58 +0,0 @@ -import {AfterViewInit, Component, EventEmitter, Input, Output, ViewChild} from "@angular/core"; -import {Observable} from "rxjs"; -import {map, withLatestFrom} from "rxjs/operators"; -import {FixedMouseContextualContainerDirective} from "src/util/directives/FixedMouseContextualContainerDirective.directive"; -import {VIEWER_STATE_ACTION_TYPES} from "src/services/effect/effect"; -import {CHANGE_NAVIGATION, generateLabelIndexId} from "src/services/stateStore.service"; -import {ADD_TO_REGIONS_SELECTION_WITH_IDS} from "src/services/state/viewerState.store"; -import {Store} from "@ngrx/store"; -import {SearchSideNav} from "src/ui/searchSideNav/searchSideNav.component"; - -@Component({ - selector: 'region-menu', - templateUrl: './regionMenu.template.html', - styleUrls: ['./regionMenu.style.css'] -}) -export class RegionMenuComponent { - @Input() selectedRegions$: any - @Input() region: any - @Input() hasConnectivity: boolean - - @Output() exploreConnectivity: EventEmitter<string> = new EventEmitter() - - @ViewChild('searchSideNav') searchSideNav: SearchSideNav - - regionToolsMenuVisible = true - collapsedRegionDescription = false - - constructor(private store$: Store<any>) {} - - - toggleRegionWithId(ngId, labelIndex, removeFlag: any){ - if (removeFlag) { - this.store$.dispatch({ - type: VIEWER_STATE_ACTION_TYPES.DESELECT_REGIONS_WITH_ID, - deselecRegionIds: [generateLabelIndexId({ ngId, labelIndex })] - }) - } else { - this.store$.dispatch({ - type: ADD_TO_REGIONS_SELECTION_WITH_IDS, - selectRegionIds : [generateLabelIndexId({ ngId, labelIndex })] - }) - } - } - - regionIsSelected(selectedRegions, ngId, labelIndex) { - return selectedRegions.map(sr => generateLabelIndexId({ ngId: sr.ngId, labelIndex: sr.labelIndex })).includes(generateLabelIndexId({ ngId, labelIndex })) - } - - navigateTo(position){ - this.store$.dispatch({ - type: CHANGE_NAVIGATION, - navigation: { - position, - animation: {} - } - }) - } -} \ No newline at end of file diff --git a/src/ui/regionToolsMenu/regionMenu.style.css b/src/ui/regionToolsMenu/regionMenu.style.css deleted file mode 100644 index fc202344466f16355a9dd257690a17f7e56c151c..0000000000000000000000000000000000000000 --- a/src/ui/regionToolsMenu/regionMenu.style.css +++ /dev/null @@ -1,19 +0,0 @@ -.regionDescriptionTextClass{ - max-height:100px; - transition: max-height 0.15s ease-out; -} -.regionDescriptionTextOpened { - max-height: 310px; - transition: max-height 0.25s ease-in; -} - -[fixedMouseContextualContainerDirective] -{ - width: 15rem; -} - -[fixedMouseContextualContainerDirective] div[body] -{ - overflow: hidden; -} - diff --git a/src/ui/regionToolsMenu/regionMenu.template.html b/src/ui/regionToolsMenu/regionMenu.template.html deleted file mode 100644 index 0d7afd988ce28b6e91b0426986b677b5e0797aae..0000000000000000000000000000000000000000 --- a/src/ui/regionToolsMenu/regionMenu.template.html +++ /dev/null @@ -1,53 +0,0 @@ -<div class="text-nowrap text-truncate mt-2 ml-2 mr-2 overflow-hidden" [matTooltip]="region.name" - matTooltipShowDelay="1000">{{region.name}}</div> -<!-- ToDo implement it with Descriptions--> - <div > <!--*ngIf="!region.description && !region.description.length"--> - <div class="row m-2 position-relative overflow-hidden" - [class.regionDescriptionTextOpened] = "collapsedRegionDescription" - [class.overflow-y-auto] = "collapsedRegionDescription" - [class.regionDescriptionTextClass] = "!collapsedRegionDescription" - [class.linear-gradient-fade] = "(+regionDescriptionText.scrollHeight > +regionDescriptionText.clientHeight) && !collapsedRegionDescription" - #regionDescriptionText> - {{region.description}} - </div> - <div (click)="collapsedRegionDescription = true" - *ngIf="+regionDescriptionText.scrollHeight > +regionDescriptionText.clientHeight && !collapsedRegionDescription" - class="w-100 d-flex justify-content-center align-items-center mt-n2 cursorPointer"><i - class="fas fa-angle-down m-1"></i> Read More - </div> - <div (click)="collapsedRegionDescription = false" - *ngIf="collapsedRegionDescription" - class="w-100 d-flex justify-content-center align-items-center mt-n2 cursorPointer"><i - class="fas fa-angle-up m-1"></i> Collapse - </div> - </div> -<div class="d-flex align-items-center justify-content-between"> - <button mat-button - style="font-size: 12px" - class="pt-0 pb-0 br-1 pl-1" - [ngClass]="!hasConnectivity && 'w-100'" - *ngIf="(selectedRegions$ | async) as selectedRegions" - (click)="toggleRegionWithId(region.ngId, region.labelIndex, regionIsSelected(selectedRegions, region.ngId, region.labelIndex)); regionToolsMenuVisible = false; collapsedRegionDescription = false"> - <span class="fa-stack fa-1x"> - <i class="fas fa-hand-pointer fa-stack-1x"></i> - <i class="fas fa-slash fa-stack-1x fa-inverse" - *ngIf="regionIsSelected(selectedRegions, region.ngId, region.labelIndex)"></i> - </span> - <span [innerText]="regionIsSelected(selectedRegions, region.ngId, region.labelIndex)? 'Deselect' : 'Select'"></span> - </button> - <button mat-button - style="font-size: 12px" - class="pt-0 pb-0 br-1 pl-1" - [ngClass]="!hasConnectivity && 'w-100'" - (click)="navigateTo(region.position); regionToolsMenuVisible = false; collapsedRegionDescription = false"> - <i class="fas fa-crosshairs"></i> Navigate - </button> - - <button mat-button - *ngIf="hasConnectivity" - style="font-size: 12px" - class="pt-0 pb-0 br-1 pl-1 mr-1" - (click)="exploreConnectivity.emit(region.name); regionToolsMenuVisible = false; collapsedRegionDescription = false"> - <i class="fab fa-connectdevelop"></i> Connectivity - </button> -</div> \ No newline at end of file diff --git a/src/ui/searchSideNav/searchSideNav.component.ts b/src/ui/searchSideNav/searchSideNav.component.ts index 2b0d6aa6da88ec55e19a03d64ee8d4631ed9185c..4bca8384e7fb43d9ec0e5c7f624e41c984bd63a4 100644 --- a/src/ui/searchSideNav/searchSideNav.component.ts +++ b/src/ui/searchSideNav/searchSideNav.component.ts @@ -13,7 +13,6 @@ import { EXPAND_SIDE_PANEL_CURRENT_VIEW, OPEN_SIDE_PANEL } from "src/services/state/uiState.store"; -import {ConnectivityBrowserComponent} from "src/ui/connectivityBrowser/connectivityBrowser.component"; import { SELECT_REGIONS, IavRootStoreInterface } from "src/services/stateStore.service"; @Component({ @@ -24,24 +23,20 @@ import { SELECT_REGIONS, IavRootStoreInterface } from "src/services/stateStore.s ] }) -export class SearchSideNav implements OnInit, OnDestroy { +export class SearchSideNav implements OnDestroy { public availableDatasets: number = 0 - public connectivityActive = new Subject<string>() - public connectivityRegion = '' - private subscriptions: Subscription[] = [] private layerBrowserDialogRef: MatDialogRef<any> @Output() dismiss: EventEmitter<any> = new EventEmitter() @ViewChild('layerBrowserTmpl', {read: TemplateRef}) layerBrowserTmpl: TemplateRef<any> - @ViewChild('connectivityBrowser') connectivityBrowser: ConnectivityBrowserComponent - public autoOpenSideNavDataset$: Observable<any> - sidebarMenuState$: Observable<any> + sidePanelExploreCurrentViewIsOpen$: Observable<any> + sidePanelManualCollapsibleView$: Observable<any> constructor( public dialog: MatDialog, @@ -59,31 +54,14 @@ export class SearchSideNav implements OnInit, OnDestroy { mapTo(true) ) - this.sidebarMenuState$ = this.store$.pipe( + this.sidePanelExploreCurrentViewIsOpen$ = this.store$.pipe( select('uiState'), - map(state => { - return { - sidePanelOpen: state.sidePanelOpen, - sidePanelCurrentViewOpened: state.sidePanelCurrentViewOpened, - sidePanelManualCollapsibleView: state.sidePanelManualCollapsibleView - } - }) + select("sidePanelExploreCurrentViewIsOpen") ) - } - ngOnInit(){ - this.subscriptions.push( - this.connectivityActive.asObservable().subscribe(r => { - // this.connectivityService.getConnectivityByRegion(r) - this.connectivityRegion = r - }), - - this.autoOpenSideNavDataset$.subscribe(() => { - this.store$.dispatch({ - type: OPEN_SIDE_PANEL, - }) - this.expandSidePanelCurrentView() - }) + this.sidePanelManualCollapsibleView$ = this.store$.pipe( + select('uiState'), + select("sidePanelManualCollapsibleView") ) } diff --git a/src/ui/searchSideNav/searchSideNav.template.html b/src/ui/searchSideNav/searchSideNav.template.html index 17610a0f3787660453c22ec3b60503606416c3d8..44272b3dbb1c79d5ab5a52ff8d25ded57d0dc264 100644 --- a/src/ui/searchSideNav/searchSideNav.template.html +++ b/src/ui/searchSideNav/searchSideNav.template.html @@ -12,7 +12,7 @@ <!-- footer content --> <div class="d-flex flex-row justify-content-center" card-footer> <button mat-stroked-button - *ngIf="!(sidebarMenuState$ | async)?.sidePanelCurrentViewOpened" + *ngIf="!(sidePanelExploreCurrentViewIsOpen$ | async)" (click)="expandSidePanelCurrentView()" class="m-1 flex-grow-1 overflow-hidden" > <i class="fas fa-chevron-down"></i> @@ -23,14 +23,12 @@ </div> </viewer-state-controller> - <ng-container *ngIf="(sidebarMenuState$ | async) as sideBarMenu"> + <ng-container> <connectivity-browser class="pe-all flex-grow-5 flex-shrink-1" style="max-height: calc(100% - 220px)" - [region]="connectivityRegion" - #connectivityBrowser - *ngIf="sideBarMenu.sidePanelCurrentViewOpened && sideBarMenu.sidePanelManualCollapsibleView === 'Connectivity'"> + *ngIf="(sidePanelExploreCurrentViewIsOpen$ | async) && (sidePanelManualCollapsibleView$ | async)"> </connectivity-browser> - <data-browser *ngIf="sideBarMenu.sidePanelCurrentViewOpened && !sideBarMenu.sidePanelManualCollapsibleView" + <data-browser *ngIf="(sidePanelExploreCurrentViewIsOpen$ | async) && !(sidePanelManualCollapsibleView$ | async)" class="pe-all flex-grow-5 flex-shrink-1" [template]="viewerStateController.templateSelected$ | async" [parcellation]="viewerStateController.parcellationSelected$ | async" diff --git a/src/util/directives/captureClickListener.directive.ts b/src/util/directives/captureClickListener.directive.ts index bd92d61fe6cf9944e5142078b964c4e31044cd55..2d943c2200e6ca60f2c3c5e14c6fb74e1f012a64 100644 --- a/src/util/directives/captureClickListener.directive.ts +++ b/src/util/directives/captureClickListener.directive.ts @@ -1,7 +1,6 @@ import {Directive, ElementRef, EventEmitter, Input, OnDestroy, OnInit, Output} from "@angular/core"; -import {Observable, Observer, Subscription} from "rxjs"; +import {fromEvent, Observable, Observer, Subscription} from "rxjs"; import {switchMapTo, takeUntil} from "rxjs/operators"; -import {RegionMenuComponent} from "src/ui/regionToolsMenu/regionMenu.component"; @Directive({ selector: '[iav-captureClickListenerDirective]' @@ -10,28 +9,20 @@ import {RegionMenuComponent} from "src/ui/regionToolsMenu/regionMenu.component"; export class CaptureClickListenerDirective implements OnInit, OnDestroy { private subscriptions: Subscription[] = [] - @Output() mapClicked: EventEmitter<any> = new EventEmitter() - @Output() mouseDownEmitter: EventEmitter<any> = new EventEmitter() + @Output('iav-captureClickListenerDirective-onClick') mapClicked: EventEmitter<any> = new EventEmitter() + @Output('iav-captureClickListenerDirective-onMousedown') mouseDownEmitter: EventEmitter<any> = new EventEmitter() constructor(private el: ElementRef){} ngOnInit(): void { - - // Listen click Events - const mouseDownObs$ = new Observable((observer: Observer<any>) => { - this.el.nativeElement.addEventListener('mousedown', event => observer.next({eventName: 'mousedown', event}), true) - }) as Observable<{eventName: string, event: MouseEvent}> - const mouseMoveObs$ = new Observable((observer: Observer<any>) => { - this.el.nativeElement.addEventListener('mousemove', event => observer.next({eventName: 'mousemove', event}), true) - }) as Observable<{eventName: string, event: MouseEvent}> - const mouseUpObs$ = new Observable((observer: Observer<any>) => { - this.el.nativeElement.addEventListener('mouseup', event => observer.next({eventName: 'mouseup', event}), true) - }) as Observable<{eventName: string, event: MouseEvent}> + const mouseDownObs$ = fromEvent(this.el.nativeElement, 'mousedown', { capture: true }) + const mouseMoveObs$ = fromEvent(this.el.nativeElement, 'mousemove', { capture: true }) + const mouseUpObs$ = fromEvent(this.el.nativeElement, 'mouseup', { capture: true }) this.subscriptions.push( - mouseDownObs$.subscribe(e => { - this.mouseDownEmitter.emit(e.event) + mouseDownObs$.subscribe(event => { + this.mouseDownEmitter.emit(event) }), mouseDownObs$.pipe( switchMapTo( @@ -39,8 +30,8 @@ export class CaptureClickListenerDirective implements OnInit, OnDestroy { takeUntil(mouseMoveObs$) ) ) - ).subscribe(e => { - this.mapClicked.emit(e.event) + ).subscribe(event => { + this.mapClicked.emit(event) }) ) }