Skip to content
Snippets Groups Projects
Unverified Commit cf720a40 authored by xgui3783's avatar xgui3783 Committed by GitHub
Browse files

Merge branch 'dev' into chore/regionId

parents dbc7b200 c3827e35
No related branches found
No related tags found
No related merge requests found
Showing with 250 additions and 55 deletions
...@@ -8,8 +8,6 @@ on: ...@@ -8,8 +8,6 @@ on:
env: env:
DOCKER_IMAGE_NAME: interactive-viewer DOCKER_IMAGE_NAME: interactive-viewer
DOCKER_IMAGE_TAG: ${{ github.sha }} DOCKER_IMAGE_TAG: ${{ github.sha }}
DOCKER_SAVE_FILENAME: iav.tar.gz
ARTEFACT_NAME: iav_docker_image
DOCKER_CONTAINER_NAME: github-actions-iav-dkr-container DOCKER_CONTAINER_NAME: github-actions-iav-dkr-container
jobs: jobs:
...@@ -26,7 +24,7 @@ jobs: ...@@ -26,7 +24,7 @@ jobs:
run: | run: |
docker build --build-arg BACKEND_URL=${BACKEND_URL} -t ${DOCKER_IMAGE_NAME}:${DOCKER_IMAGE_TAG} . docker build --build-arg BACKEND_URL=${BACKEND_URL} -t ${DOCKER_IMAGE_NAME}:${DOCKER_IMAGE_TAG} .
env: env:
BACKEND_URL: http://localhost:3001 BACKEND_URL: http://localhost:3001/
test: test:
runs-on: self-hosted runs-on: self-hosted
...@@ -39,15 +37,25 @@ jobs: ...@@ -39,15 +37,25 @@ jobs:
- name: Install dependencies - name: Install dependencies
run: | run: |
npm i npm i
- name: run docker image ${{ env.DOCKER_IMAGE_NAME }}:${{ env.DOCKER_IMAGE_TAG }} as ${{ env.DOCKER_CONTAINER_NAME }} - name: run docker image ${{ env.DOCKER_IMAGE_NAME }}:${{ env.DOCKER_IMAGE_TAG }}
run: docker run -p 3001:3000 --rm --name ${DOCKER_CONTAINER_NAME} -dit ${DOCKER_IMAGE_NAME}:${DOCKER_IMAGE_TAG} run: |
- name: run pptr tests docker run -p 3001:3000 \
--rm \
--name ${DOCKER_CONTAINER_NAME} \
--env HBP_CLIENTID=${{ secrets.HBP_CLIENTID }} \
--env HBP_CLIENTSECRET=${{ secrets.HBP_CLIENTSECRET }} \
--env REFRESH_TOKEN=${{ secrets.REFRESH_TOKEN }} \
-dit \
${DOCKER_IMAGE_NAME}:${DOCKER_IMAGE_TAG}
- name: sleep for 60s
run: sleep 60s
- name: run pptr tests - ${{ env.TEST_URL }}
run: node ./node_modules/.bin/mocha ./test/databrowser.spec.js --timeout 1800000 run: node ./node_modules/.bin/mocha ./test/databrowser.spec.js --timeout 1800000
env:
TEST_URL: http://localhost:3001
- name: cleanup, stop container ${{ env.DOCKER_CONTAINER_NAME }} - name: cleanup, stop container ${{ env.DOCKER_CONTAINER_NAME }}
if: always() if: always()
run: | run: docker stop ${DOCKER_CONTAINER_NAME}
docker ps | grep ${{ env.DOCKER_CONTAINER_NAME }} - name: cleanup, remove image ${{ env.DOCKER_IMAGE_NAME }}:${{ env.DOCKER_IMAGE_TAG }}
docker stop ${DOCKER_CONTAINER_NAME} if: success()
- name: cleanup, rm image ${{ env.DOCKER_IMAGE_NAME }}:${{ env.DOCKER_IMAGE_TAG }} run: docker rmi ${DOCKER_IMAGE_NAME}:${DOCKER_IMAGE_TAG}
if: always()
run: docker rmi ${DOCKER_IMAGE_NAME}:${DOCKER_IMAGE_TAG}
\ No newline at end of file
...@@ -92,6 +92,6 @@ ...@@ -92,6 +92,6 @@
"zone.js": "^0.9.1" "zone.js": "^0.9.1"
}, },
"dependencies": { "dependencies": {
"hbp-connectivity-component": "0.0.17" "hbp-connectivity-component": "0.0.23"
} }
} }
import {} from 'jasmine'
import {AtlasViewerAPIServices} from "src/atlasViewer/atlasViewer.apiService.service";
import {async, TestBed} from "@angular/core/testing";
import {provideMockActions} from "@ngrx/effects/testing";
import {provideMockStore} from "@ngrx/store/testing";
import {defaultRootState} from "src/services/stateStore.service";
import {Observable, of} from "rxjs";
import {Action} from "@ngrx/store";
import {AngularMaterialModule} from "src/ui/sharedModules/angularMaterial.module";
const actions$: Observable<Action> = of({type: 'TEST'})
describe('atlasViewer.apiService.service.ts', () => {
describe('getUserToSelectARegion', () => {
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [
AngularMaterialModule,
],
providers: [
AtlasViewerAPIServices,
provideMockActions(() => actions$),
provideMockStore({initialState: defaultRootState})
]
})
}))
it('should return value on resolve', async () => {
const regionToSend = 'test-region'
let sentData: any
const apiService = TestBed.get(AtlasViewerAPIServices)
const callApi = apiService.interactiveViewer.uiHandle.getUserToSelectARegion('selecting Region mode message')
apiService.getUserToSelectARegionResolve(regionToSend)
await callApi.then(r => {
sentData = r
})
expect(sentData).toEqual(regionToSend)
})
it('pluginRegionSelectionEnabled should false after resolve', async () => {
const { uiState } = defaultRootState
const regionToSend = 'test-region'
let sentData: any
const apiService = TestBed.get(AtlasViewerAPIServices)
const callApi = apiService.interactiveViewer.uiHandle.getUserToSelectARegion('selecting Region mode message')
apiService.getUserToSelectARegionResolve(regionToSend)
await callApi.then(r => {
sentData = r
})
expect(uiState.pluginRegionSelectionEnabled).toBe(false)
})
})
})
\ No newline at end of file
...@@ -4,10 +4,17 @@ import { Observable } from "rxjs"; ...@@ -4,10 +4,17 @@ import { Observable } from "rxjs";
import { distinctUntilChanged, map, filter } from "rxjs/operators"; import { distinctUntilChanged, map, filter } from "rxjs/operators";
import { DialogService } from "src/services/dialogService.service"; import { DialogService } from "src/services/dialogService.service";
import { LoggingService } from "src/services/logging.service"; import { LoggingService } from "src/services/logging.service";
import { getLabelIndexMap, getMultiNgIdsRegionsLabelIndexMap, IavRootStoreInterface, safeFilter } from "src/services/stateStore.service"; import {
DISABLE_PLUGIN_REGION_SELECTION,
getLabelIndexMap,
getMultiNgIdsRegionsLabelIndexMap,
IavRootStoreInterface,
safeFilter
} from "src/services/stateStore.service";
import { ModalHandler } from "../util/pluginHandlerClasses/modalHandler"; import { ModalHandler } from "../util/pluginHandlerClasses/modalHandler";
import { ToastHandler } from "../util/pluginHandlerClasses/toastHandler"; import { ToastHandler } from "../util/pluginHandlerClasses/toastHandler";
import { IPluginManifest } from "./atlasViewer.pluginService.service"; import { IPluginManifest } from "./atlasViewer.pluginService.service";
import {ENABLE_PLUGIN_REGION_SELECTION} from "src/services/state/uiState.store";
declare let window declare let window
...@@ -23,6 +30,9 @@ export class AtlasViewerAPIServices { ...@@ -23,6 +30,9 @@ export class AtlasViewerAPIServices {
public loadedLibraries: Map<string, {counter: number, src: HTMLElement|null}> = new Map() public loadedLibraries: Map<string, {counter: number, src: HTMLElement|null}> = new Map()
public getUserToSelectARegionResolve
public getUserToSelectARegionReject
constructor( constructor(
private store: Store<IavRootStoreInterface>, private store: Store<IavRootStoreInterface>,
private dialogService: DialogService, private dialogService: DialogService,
...@@ -118,8 +128,27 @@ export class AtlasViewerAPIServices { ...@@ -118,8 +128,27 @@ export class AtlasViewerAPIServices {
return Promise.reject('Needs to be overwritted') return Promise.reject('Needs to be overwritted')
}, },
getUserInput: config => this.dialogService.getUserInput(config), getUserInput: config => this.dialogService.getUserInput(config) ,
getUserConfirmation: config => this.dialogService.getUserConfirm(config), getUserConfirmation: config => this.dialogService.getUserConfirm(config),
getUserToSelectARegion: (selectingMessage) => new Promise((resolve, reject) => {
this.store.dispatch({
type: ENABLE_PLUGIN_REGION_SELECTION,
payload: selectingMessage
})
this.getUserToSelectARegionResolve = resolve
this.getUserToSelectARegionReject = reject
}),
// ToDo Method should be able to cancel any pending promise.
cancelPromise: (pr) => {
if (pr === this.interactiveViewer.uiHandle.getUserToSelectARegion) {
if (this.getUserToSelectARegionReject) this.getUserToSelectARegionReject('Rej')
this.store.dispatch({type: DISABLE_PLUGIN_REGION_SELECTION})
}
}
}, },
pluginControl : { pluginControl : {
loadExternalLibraries : () => Promise.reject('load External Library method not over written') loadExternalLibraries : () => Promise.reject('load External Library method not over written')
...@@ -205,6 +234,8 @@ export interface IInteractiveViewerInterface { ...@@ -205,6 +234,8 @@ export interface IInteractiveViewerInterface {
launchNewWidget: (manifest: IPluginManifest) => Promise<any> launchNewWidget: (manifest: IPluginManifest) => Promise<any>
getUserInput: (config: IGetUserInputConfig) => Promise<string> getUserInput: (config: IGetUserInputConfig) => Promise<string>
getUserConfirmation: (config: IGetUserConfirmation) => Promise<any> getUserConfirmation: (config: IGetUserConfirmation) => Promise<any>
getUserToSelectARegion: (selectingMessage: any) => Promise<any>
cancelPromise: (pr) => void
} }
pluginControl: { pluginControl: {
......
import { import {
AfterViewInit, AfterViewInit, ChangeDetectorRef,
Component, Component,
HostBinding, HostBinding,
OnDestroy, OnDestroy,
...@@ -117,6 +117,11 @@ export class AtlasViewer implements OnDestroy, OnInit, AfterViewInit { ...@@ -117,6 +117,11 @@ export class AtlasViewer implements OnDestroy, OnInit, AfterViewInit {
public onhoverSegmentsForFixed$: Observable<string[]> public onhoverSegmentsForFixed$: Observable<string[]>
private pluginRegionSelectionEnabled$: Observable<boolean>
private pluginRegionSelectionEnabled: boolean = false
private persistentStateNotifierTemplate$: Observable<string>
// private pluginRegionSelectionEnabled: boolean = false
constructor( constructor(
private store: Store<IavRootStoreInterface>, private store: Store<IavRootStoreInterface>,
private widgetServices: WidgetServices, private widgetServices: WidgetServices,
...@@ -129,6 +134,7 @@ export class AtlasViewer implements OnDestroy, OnInit, AfterViewInit { ...@@ -129,6 +134,7 @@ export class AtlasViewer implements OnDestroy, OnInit, AfterViewInit {
private snackbar: MatSnackBar, private snackbar: MatSnackBar,
private bottomSheet: MatBottomSheet, private bottomSheet: MatBottomSheet,
private log: LoggingService, private log: LoggingService,
private changeDetectorRef: ChangeDetectorRef,
) { ) {
this.snackbarMessage$ = this.store.pipe( this.snackbarMessage$ = this.store.pipe(
...@@ -136,6 +142,17 @@ export class AtlasViewer implements OnDestroy, OnInit, AfterViewInit { ...@@ -136,6 +142,17 @@ export class AtlasViewer implements OnDestroy, OnInit, AfterViewInit {
select("snackbarMessage"), select("snackbarMessage"),
) )
this.pluginRegionSelectionEnabled$ = this.store.pipe(
select('uiState'),
select("pluginRegionSelectionEnabled"),
distinctUntilChanged(),
)
this.persistentStateNotifierTemplate$ = this.store.pipe(
select('uiState'),
select("persistentStateNotifierTemplate"),
distinctUntilChanged(),
)
this.bottomSheet$ = this.store.pipe( this.bottomSheet$ = this.store.pipe(
select('uiState'), select('uiState'),
select('bottomSheetTemplate'), select('bottomSheetTemplate'),
...@@ -279,6 +296,10 @@ export class AtlasViewer implements OnDestroy, OnInit, AfterViewInit { ...@@ -279,6 +296,10 @@ export class AtlasViewer implements OnDestroy, OnInit, AfterViewInit {
} }
}), }),
) )
this.onhoverSegments$.subscribe(hr => {
this.hoveringRegions = hr
})
} }
private selectedParcellation$: Observable<any> private selectedParcellation$: Observable<any>
...@@ -361,6 +382,13 @@ export class AtlasViewer implements OnDestroy, OnInit, AfterViewInit { ...@@ -361,6 +382,13 @@ export class AtlasViewer implements OnDestroy, OnInit, AfterViewInit {
this.rd.setAttribute(document.body, 'darktheme', flag.toString()) this.rd.setAttribute(document.body, 'darktheme', flag.toString())
}), }),
) )
this.subscriptions.push(
this.pluginRegionSelectionEnabled$.subscribe(PRSE => {
this.pluginRegionSelectionEnabled = PRSE
this.changeDetectorRef.detectChanges()
})
)
} }
public ngAfterViewInit() { public ngAfterViewInit() {
...@@ -409,21 +437,26 @@ export class AtlasViewer implements OnDestroy, OnInit, AfterViewInit { ...@@ -409,21 +437,26 @@ export class AtlasViewer implements OnDestroy, OnInit, AfterViewInit {
withLatestFrom(this.onhoverSegments$), withLatestFrom(this.onhoverSegments$),
map(([_flag, onhoverSegments]) => onhoverSegments || []), map(([_flag, onhoverSegments]) => onhoverSegments || []),
) )
} }
private hoveringRegions = []
public mouseDownNehuba(_event) { public mouseDownNehuba(_event) {
this.rClContextualMenu.hide() this.rClContextualMenu.hide()
} }
public mouseUpNehuba(event) { public mouseClickNehuba(event) {
// if (this.mouseUpLeftPosition === event.pageX && this.mouseUpTopPosition === event.pageY) {} // if (this.mouseUpLeftPosition === event.pageX && this.mouseUpTopPosition === event.pageY) {}
if (!this.rClContextualMenu) { return } if (!this.rClContextualMenu) { return }
this.rClContextualMenu.mousePos = [ this.rClContextualMenu.mousePos = [
event.clientX, event.clientX,
event.clientY, event.clientY,
] ]
this.rClContextualMenu.show() if (!this.pluginRegionSelectionEnabled) {
this.rClContextualMenu.show()
} else {
if (this.hoveringRegions) this.apiService.getUserToSelectARegionResolve(this.hoveringRegions)
}
} }
public toggleSideNavMenu(opened) { public toggleSideNavMenu(opened) {
......
...@@ -47,7 +47,7 @@ ...@@ -47,7 +47,7 @@
[currentOnHover]="iavMouseHoverEl.currentOnHoverObs$ | async" [currentOnHover]="iavMouseHoverEl.currentOnHoverObs$ | async"
iav-captureClickListenerDirective iav-captureClickListenerDirective
(iav-captureClickListenerDirective-onMousedown)="mouseDownNehuba($event)" (iav-captureClickListenerDirective-onMousedown)="mouseDownNehuba($event)"
(iav-captureClickListenerDirective-onClick)="mouseUpNehuba($event)"> (iav-captureClickListenerDirective-onClick)="mouseClickNehuba($event)">
</ui-nehuba-container> </ui-nehuba-container>
<div class="z-index-10 position-absolute pe-none w-100 h-100"> <div class="z-index-10 position-absolute pe-none w-100 h-100">
...@@ -108,6 +108,11 @@ ...@@ -108,6 +108,11 @@
</ng-container> </ng-container>
</div> </div>
<div class="fixed-top pe-none d-flex justify-content-center m-4" *ngIf="pluginRegionSelectionEnabled">
<ng-container *ngTemplateOutlet="persistentStateNotifierTemplate">
</ng-container>
</div>
<div floatingMouseContextualContainerDirective> <div floatingMouseContextualContainerDirective>
<div *ngIf="!ismobile" <div *ngIf="!ismobile"
...@@ -204,4 +209,9 @@ ...@@ -204,4 +209,9 @@
<!-- logo tmpl --> <!-- logo tmpl -->
<ng-template #logoTmpl> <ng-template #logoTmpl>
<logo-container></logo-container> <logo-container></logo-container>
</ng-template> </ng-template>
\ No newline at end of file
<ng-template #persistentStateNotifierTemplate>
<mat-card>{{persistentStateNotifierTemplate$ | async}}</mat-card>
</ng-template>
import { enableProdMode } from '@angular/core';
enableProdMode()
import './main-common' import './main-common'
/* aot === production mode */
if (PRODUCTION) { console.log(`Interactive Atlas Viewer: ${VERSION}`) }
import 'zone.js' import 'zone.js'
import 'third_party/testSafari.js' import 'third_party/testSafari.js'
import { enableProdMode } from '@angular/core';
import { defineCustomElements } from 'hbp-connectivity-component/dist/loader' import { defineCustomElements } from 'hbp-connectivity-component/dist/loader'
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic' import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'
import { MainModule } from './main.module'; import { MainModule } from './main.module';
if (PRODUCTION) enableProdMode()
if (PRODUCTION) { console.log(`Interactive Atlas Viewer: ${VERSION}`) }
const requireAll = (r: any) => {r.keys().forEach(r)} const requireAll = (r: any) => {r.keys().forEach(r)}
requireAll(require.context('./res/ext', false, /\.json$/)) requireAll(require.context('./res/ext', false, /\.json$/))
requireAll(require.context('./res/images', true, /\.jpg$|\.png$|\.svg$/)) requireAll(require.context('./res/images', true, /\.jpg$|\.png$|\.svg$/))
......
...@@ -23,6 +23,9 @@ export const defaultState: StateInterface = { ...@@ -23,6 +23,9 @@ export const defaultState: StateInterface = {
bottomSheetTemplate: null, bottomSheetTemplate: null,
pluginRegionSelectionEnabled: false,
persistentStateNotifierTemplate: null,
/** /**
* replace with server side logic (?) * replace with server side logic (?)
*/ */
...@@ -105,6 +108,22 @@ export const getStateStore = ({ state = defaultState } = {}) => (prevState: Stat ...@@ -105,6 +108,22 @@ export const getStateStore = ({ state = defaultState } = {}) => (prevState: Stat
...prevState, ...prevState,
sidePanelCurrentViewContent: 'Dataset', sidePanelCurrentViewContent: 'Dataset',
} }
case ENABLE_PLUGIN_REGION_SELECTION: {
return {
...prevState,
pluginRegionSelectionEnabled: true,
persistentStateNotifierTemplate: action.payload
}
}
case DISABLE_PLUGIN_REGION_SELECTION: {
return {
...prevState,
pluginRegionSelectionEnabled: false,
persistentStateNotifierTemplate: null
}
}
case AGREE_COOKIE: { case AGREE_COOKIE: {
/** /**
* TODO replace with server side logic * TODO replace with server side logic
...@@ -168,6 +187,9 @@ export interface StateInterface { ...@@ -168,6 +187,9 @@ export interface StateInterface {
snackbarMessage: symbol snackbarMessage: symbol
pluginRegionSelectionEnabled: boolean
persistentStateNotifierTemplate: TemplateRef<any>
agreedCookies: boolean agreedCookies: boolean
agreedKgTos: boolean agreedKgTos: boolean
...@@ -243,6 +265,9 @@ export const HIDE_SIDE_PANEL_CONNECTIVITY = `HIDE_SIDE_PANEL_CONNECTIVITY` ...@@ -243,6 +265,9 @@ export const HIDE_SIDE_PANEL_CONNECTIVITY = `HIDE_SIDE_PANEL_CONNECTIVITY`
export const COLLAPSE_SIDE_PANEL_CURRENT_VIEW = `COLLAPSE_SIDE_PANEL_CURRENT_VIEW` export const COLLAPSE_SIDE_PANEL_CURRENT_VIEW = `COLLAPSE_SIDE_PANEL_CURRENT_VIEW`
export const EXPAND_SIDE_PANEL_CURRENT_VIEW = `EXPAND_SIDE_PANEL_CURRENT_VIEW` export const EXPAND_SIDE_PANEL_CURRENT_VIEW = `EXPAND_SIDE_PANEL_CURRENT_VIEW`
export const ENABLE_PLUGIN_REGION_SELECTION = `ENABLE_PLUGIN_REGION_SELECTION`
export const DISABLE_PLUGIN_REGION_SELECTION = `DISABLE_PLUGIN_REGION_SELECTION`
export const AGREE_COOKIE = `AGREE_COOKIE` export const AGREE_COOKIE = `AGREE_COOKIE`
export const AGREE_KG_TOS = `AGREE_KG_TOS` export const AGREE_KG_TOS = `AGREE_KG_TOS`
export const SHOW_KG_TOS = `SHOW_KG_TOS` export const SHOW_KG_TOS = `SHOW_KG_TOS`
......
...@@ -52,7 +52,7 @@ export { userConfigState, USER_CONFIG_ACTION_TYPES} ...@@ -52,7 +52,7 @@ export { userConfigState, USER_CONFIG_ACTION_TYPES}
export { ADD_NG_LAYER, FORCE_SHOW_SEGMENT, HIDE_NG_LAYER, REMOVE_NG_LAYER, SHOW_NG_LAYER } from './state/ngViewerState.store' export { ADD_NG_LAYER, FORCE_SHOW_SEGMENT, HIDE_NG_LAYER, REMOVE_NG_LAYER, SHOW_NG_LAYER } from './state/ngViewerState.store'
export { CHANGE_NAVIGATION, DESELECT_LANDMARKS, FETCHED_TEMPLATE, NEWVIEWER, SELECT_LANDMARKS, SELECT_PARCELLATION, SELECT_REGIONS, USER_LANDMARKS } from './state/viewerState.store' export { CHANGE_NAVIGATION, DESELECT_LANDMARKS, FETCHED_TEMPLATE, NEWVIEWER, SELECT_LANDMARKS, SELECT_PARCELLATION, SELECT_REGIONS, USER_LANDMARKS } from './state/viewerState.store'
export { IDataEntry, IParcellationRegion, FETCHED_DATAENTRIES, FETCHED_SPATIAL_DATA, ILandmark, IOtherLandmarkGeometry, IPlaneLandmarkGeometry, IPointLandmarkGeometry, IProperty, IPublication, IReferenceSpace, IFile, IFileSupplementData } from './state/dataStore.store' export { IDataEntry, IParcellationRegion, FETCHED_DATAENTRIES, FETCHED_SPATIAL_DATA, ILandmark, IOtherLandmarkGeometry, IPlaneLandmarkGeometry, IPointLandmarkGeometry, IProperty, IPublication, IReferenceSpace, IFile, IFileSupplementData } from './state/dataStore.store'
export { CLOSE_SIDE_PANEL, MOUSE_OVER_LANDMARK, MOUSE_OVER_SEGMENT, OPEN_SIDE_PANEL, SHOW_SIDE_PANEL_CONNECTIVITY, HIDE_SIDE_PANEL_CONNECTIVITY, COLLAPSE_SIDE_PANEL_CURRENT_VIEW, EXPAND_SIDE_PANEL_CURRENT_VIEW } from './state/uiState.store' export { CLOSE_SIDE_PANEL, MOUSE_OVER_LANDMARK, MOUSE_OVER_SEGMENT, OPEN_SIDE_PANEL, SHOW_SIDE_PANEL_CONNECTIVITY, HIDE_SIDE_PANEL_CONNECTIVITY, COLLAPSE_SIDE_PANEL_CURRENT_VIEW, EXPAND_SIDE_PANEL_CURRENT_VIEW, ENABLE_PLUGIN_REGION_SELECTION, DISABLE_PLUGIN_REGION_SELECTION } from './state/uiState.store'
export { UserConfigStateUseEffect } from './state/userConfigState.store' export { UserConfigStateUseEffect } from './state/userConfigState.store'
export const GENERAL_ACTION_TYPES = { export const GENERAL_ACTION_TYPES = {
......
...@@ -8,9 +8,11 @@ import { ...@@ -8,9 +8,11 @@ import {
import {select, Store} from "@ngrx/store"; import {select, Store} from "@ngrx/store";
import {fromEvent, Observable, Subscription} from "rxjs"; import {fromEvent, Observable, Subscription} from "rxjs";
import {distinctUntilChanged, filter, map} from "rxjs/operators"; import {distinctUntilChanged, filter, map} from "rxjs/operators";
import {AtlasViewerConstantsServices} from "src/atlasViewer/atlasViewer.constantService.service";
import {CLEAR_CONNECTIVITY_REGION, SET_CONNECTIVITY_REGION} from "src/services/state/viewerState.store"; import {CLEAR_CONNECTIVITY_REGION, SET_CONNECTIVITY_REGION} from "src/services/state/viewerState.store";
import {HIDE_SIDE_PANEL_CONNECTIVITY, isDefined, safeFilter} from "src/services/stateStore.service"; import {HIDE_SIDE_PANEL_CONNECTIVITY, isDefined, safeFilter} from "src/services/stateStore.service";
import {VIEWERSTATE_CONTROLLER_ACTION_TYPES} from "src/ui/viewerStateController/viewerState.base";
const compareFn = (it, item) => it.name === item.name
@Component({ @Component({
selector: 'connectivity-browser', selector: 'connectivity-browser',
...@@ -23,14 +25,18 @@ export class ConnectivityBrowserComponent implements AfterViewInit, OnDestroy { ...@@ -23,14 +25,18 @@ export class ConnectivityBrowserComponent implements AfterViewInit, OnDestroy {
private connectivityRegion$: Observable<any> private connectivityRegion$: Observable<any>
private selectedParcellation$: Observable<any> private selectedParcellation$: Observable<any>
public selectedRegions$: Observable<any[]>
private subscriptions: Subscription[] = [] private subscriptions: Subscription[] = []
public expandMenuIndex = -1 public expandMenuIndex = -1
public allRegions = [] public allRegions = []
public defaultColorMap: Map<string, Map<number, {red: number, green: number, blue: number}>> public defaultColorMap: Map<string, Map<number, {red: number, green: number, blue: number}>>
public parcellationHasConnectivityData = true public parcellationHasConnectivityData = true
private areaHemisphere: string private areaHemisphere: string
public math = Math public math = Math
public compareFn = compareFn
@ViewChild('connectivityComponent', {read: ElementRef}) public connectivityComponentElement: ElementRef @ViewChild('connectivityComponent', {read: ElementRef}) public connectivityComponentElement: ElementRef
...@@ -51,6 +57,12 @@ export class ConnectivityBrowserComponent implements AfterViewInit, OnDestroy { ...@@ -51,6 +57,12 @@ export class ConnectivityBrowserComponent implements AfterViewInit, OnDestroy {
map(state => state.connectivityRegion), map(state => state.connectivityRegion),
) )
this.selectedRegions$ = this.store$.pipe(
select('viewerState'),
filter(state => isDefined(state) && isDefined(state.regionsSelected)),
map(state => state.regionsSelected),
distinctUntilChanged(),
)
} }
public ngAfterViewInit(): void { public ngAfterViewInit(): void {
...@@ -102,6 +114,24 @@ export class ConnectivityBrowserComponent implements AfterViewInit, OnDestroy { ...@@ -102,6 +114,24 @@ export class ConnectivityBrowserComponent implements AfterViewInit, OnDestroy {
}) })
} }
navigateToRegion(region) {
this.store$.dispatch({
type: VIEWERSTATE_CONTROLLER_ACTION_TYPES.NAVIGATETO_REGION,
payload: { region: this.getRegionWithName(region) },
})
}
toggleRegionSelection(region) {
this.store$.dispatch({
type: VIEWERSTATE_CONTROLLER_ACTION_TYPES.TOGGLE_REGION_SELECT,
payload: { region: this.getRegionWithName(region) },
})
}
getRegionWithName(region) {
return this.allRegions.find(ar => ar.name === region)
}
public closeConnectivityView() { public closeConnectivityView() {
this.setDefaultMap() this.setDefaultMap()
...@@ -127,11 +157,9 @@ export class ConnectivityBrowserComponent implements AfterViewInit, OnDestroy { ...@@ -127,11 +157,9 @@ export class ConnectivityBrowserComponent implements AfterViewInit, OnDestroy {
this.defaultColorMap = new Map(getWindow().interactiveViewer.viewerHandle.getLayersSegmentColourMap()) this.defaultColorMap = new Map(getWindow().interactiveViewer.viewerHandle.getLayersSegmentColourMap())
const existingMap: Map<string, Map<number, {red: number, green: number, blue: number}>> = (getWindow().interactiveViewer.viewerHandle.getLayersSegmentColourMap()) const existingMap: Map<string, Map<number, {red: number, green: number, blue: number}>> = (getWindow().interactiveViewer.viewerHandle.getLayersSegmentColourMap())
const colorMap = new Map(existingMap) const colorMap = new Map(existingMap)
this.allRegions.forEach(r => { this.allRegions.forEach(r => {
if (r.ngId) { if (r.ngId) {
colorMap.get(r.ngId).set(r.labelIndex, {red: 255, green: 255, blue: 255}) colorMap.get(r.ngId).set(r.labelIndex, {red: 255, green: 255, blue: 255})
} }
...@@ -139,7 +167,7 @@ export class ConnectivityBrowserComponent implements AfterViewInit, OnDestroy { ...@@ -139,7 +167,7 @@ export class ConnectivityBrowserComponent implements AfterViewInit, OnDestroy {
this.connectedAreas.forEach(area => { this.connectedAreas.forEach(area => {
const areaAsRegion = this.allRegions const areaAsRegion = this.allRegions
.filter(r => r.name === area.name + this.areaHemisphere) .filter(r => r.name === area.name)
.map(r => r) .map(r => r)
if (areaAsRegion && areaAsRegion.length && areaAsRegion[0].ngId) { if (areaAsRegion && areaAsRegion.length && areaAsRegion[0].ngId) {
......
...@@ -6,10 +6,13 @@ ...@@ -6,10 +6,13 @@
loadurl="https://connectivityquery-connectivity.apps-dev.hbp.eu/connectivity" loadurl="https://connectivityquery-connectivity.apps-dev.hbp.eu/connectivity"
show-export="true" show-export="true"
show-source="true" show-source="true"
show-title="true" show-title="false"
show-toolbar="true"> show-toolbar="true"
<div slot="header" class="w-100 d-flex justify-content-end mt-3"><span show-description="true">
class="cursorPointer" (click)="closeConnectivityView()">X</span></div> <div slot="header" class="w-100 d-flex justify-content-between mt-3">
<span>Connectivity Browser</span>
<i (click)="closeConnectivityView()" class="far fa-times-circle cursorPointer"></i>
</div>
<div slot="connectedRegionMenu"> <div slot="connectedRegionMenu">
...@@ -24,35 +27,28 @@ ...@@ -24,35 +27,28 @@
</span> </span>
<div class="d-flex align-items-center justify-content-around"> <div class="d-flex align-items-center justify-content-around">
<small class="d-flex flex-column align-items-center w-100"> <small class="d-flex flex-column align-items-center w-100">
<!--ToDo Implement function when Hemisphere information will be available --> <button mat-icon-button class="border" (click)="toggleRegionSelection(connectedAreas[expandMenuIndex].name)">
<!-- *ngIf="(selectedRegions$ | async) as selectedRegions"-->
<!-- (click)="toggleRegionWithId(region.ngId, region.labelIndex, regionIsSelected(selectedRegions, region.ngId, region.labelIndex))">-->
<button mat-icon-button class="border">
<!-- <i class="fas fa-hand-pointer mt-n1"></i>-->
<span class="fa-stack fa-1x "> <span class="fa-stack fa-1x ">
<i class="fas fa-hand-pointer fa-stack-1x"></i> <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"
<!-- <i class="fas fa-slash fa-stack-1x fa-inverse"--> *ngIf="(selectedRegions$ | async | includes : getRegionWithName(connectedAreas[expandMenuIndex].name) : compareFn)"></i>
<!-- *ngIf="regionIsSelected(selectedRegions, region.ngId, region.labelIndex)"></i>-->
</span> </span>
</button> </button>
<!-- <span [innerText]="regionIsSelected(selectedRegions, region.ngId, region.labelIndex)? 'Deselect' : 'Select'"></span>--> <span [innerText]="(selectedRegions$ | async | includes : getRegionWithName(connectedAreas[expandMenuIndex].name) : compareFn) ? 'Deselect' : 'Select'"></span>
<span>Select</span>
</small> </small>
<small class="d-flex flex-column align-items-center w-100"> <small class="d-flex flex-column align-items-center w-100">
<button mat-icon-button class="border"> <button mat-icon-button class="border" (click)="navigateToRegion(connectedAreas[expandMenuIndex].name)">
<i class="fas fa-crosshairs mt-n1"></i> <i class="fas fa-crosshairs mt-n1"></i>
</button> </button>
Navigate Go To
</small> </small>
<small class="d-flex flex-column align-items-center w-100"> <small class="d-flex flex-column align-items-center w-100">
<button mat-icon-button class="border" (click)="updateConnevtivityRegion(connectedAreas[expandMenuIndex].name)"> <button mat-icon-button class="border" (click)="updateConnevtivityRegion(connectedAreas[expandMenuIndex].name)">
<i class="fab fa-connectdevelop mt-n1"></i> <i class="fab fa-connectdevelop mt-n1"></i>
</button> </button>
Connectivity Set as Source
</small> </small>
</div> </div>
</div> </div>
......
...@@ -20,11 +20,25 @@ ...@@ -20,11 +20,25 @@
Navigate Navigate
</span> </span>
</button> </button>
<button *ngIf="hasConnectivity" mat-button (click)="showConnectivity(region.name)"> <button *ngIf="hasConnectivity"
mat-button
[matMenuTriggerFor]="connectivitySourceDatasets"
#connectivityMenuButton="matMenuTrigger">
<i class="fab fa-connectdevelop"></i> <i class="fab fa-connectdevelop"></i>
<span> <span>
Connectivity Connectivity
</span> </span>
<i class="fas fa-angle-right"></i>
</button> </button>
<!-- ToDo make dynamic with AVAILABLE CONNECTIVITY DATASETS data - get info from atlas viewer core -->
<mat-menu #connectivitySourceDatasets="matMenu" xPosition="before" (click)="$event.stopPropagation()" hasBackdrop="false">
<div>
<button mat-menu-item
(click)="showConnectivity(region.name)">
<span>1000 Brains Study</span>
</button>
</div>
</mat-menu>
</mat-card-actions> </mat-card-actions>
</mat-card> </mat-card>
\ No newline at end of file
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment