diff --git a/docs/releases/v2.12.3.md b/docs/releases/v2.12.3.md new file mode 100644 index 0000000000000000000000000000000000000000..fb6c01665023d1ff49eaa3aeedba5f70a56a03ca --- /dev/null +++ b/docs/releases/v2.12.3.md @@ -0,0 +1,6 @@ +# v2.12.3 + +## Bugfix + +- Visually distinguish regions that are mapped in a space to those that are not +- Remove experimental flag to VOI diff --git a/mkdocs.yml b/mkdocs.yml index 3b54fefc8324bbd99777bc67e61f5ec46d8865c2..46599c96864afde1458b6c31eb9e9329d18227fc 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -33,6 +33,7 @@ nav: - Fetching datasets: 'advanced/datasets.md' - Display non-atlas volumes: 'advanced/otherVolumes.md' - Release notes: + - v2.12.3: 'releases/v2.12.3.md' - v2.12.2: 'releases/v2.12.2.md' - v2.12.1: 'releases/v2.12.1.md' - v2.12.0: 'releases/v2.12.0.md' diff --git a/package.json b/package.json index 5746b8bb314805db1ef23fd255cbd2cfc2f07315..9a950eda81052fb46f1e8d2d6fad750132fd1b69 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "siibra-explorer", - "version": "2.12.2", + "version": "2.12.3", "description": "siibra-explorer - explore brain atlases. Based on humanbrainproject/nehuba & google/neuroglancer. Built with angular", "scripts": { "lint": "eslint src --ext .ts", diff --git a/src/atlasComponents/sapi/sapi.service.ts b/src/atlasComponents/sapi/sapi.service.ts index 50db1238456bd0f706188dfbd8651bdf489ae8ee..1faa428f1354027d9f758b934e70514a49f8267e 100644 --- a/src/atlasComponents/sapi/sapi.service.ts +++ b/src/atlasComponents/sapi/sapi.service.ts @@ -461,7 +461,7 @@ export class SAPI{ ) } - private async getLabelledMap(parcellation: SxplrParcellation, template: SxplrTemplate) { + async getLabelledMap(parcellation: SxplrParcellation, template: SxplrTemplate) { // No need to retrieve sapi object, since we know @id maps to id return await this.v3Get("/map", { query: { diff --git a/src/atlasComponents/sapiViews/core/region/module.ts b/src/atlasComponents/sapiViews/core/region/module.ts index 6e9140d0b5968e384f4f08907246dd6b9a621a30..dc8a9711748846fec96dab6a738214d89e619b8a 100644 --- a/src/atlasComponents/sapiViews/core/region/module.ts +++ b/src/atlasComponents/sapiViews/core/region/module.ts @@ -10,6 +10,7 @@ import { SapiViewsUtilModule } from "../../util/module"; import { SapiViewsCoreRegionRegionListItem } from "./region/listItem/region.listItem.component"; import { SapiViewsCoreRegionRegionBase } from "./region/region.base.directive"; import { SapiViewsCoreRegionRegionRich } from "./region/rich/region.rich.component"; +import { MatTooltipModule } from "@angular/material/tooltip"; @NgModule({ imports: [ @@ -21,6 +22,7 @@ import { SapiViewsCoreRegionRegionRich } from "./region/rich/region.rich.compone StrictLocalModule, FeatureModule, ReadmoreModule, + MatTooltipModule, ], declarations: [ SapiViewsCoreRegionRegionListItem, diff --git a/src/atlasComponents/sapiViews/core/rich/regionsHierarchy/regionsHierarchy.component.ts b/src/atlasComponents/sapiViews/core/rich/regionsHierarchy/regionsHierarchy.component.ts index ac272bc82f976687831e70f358104f302bb52c8a..0c85164a964950a7dec142e1fb047ac1e1aa9106 100644 --- a/src/atlasComponents/sapiViews/core/rich/regionsHierarchy/regionsHierarchy.component.ts +++ b/src/atlasComponents/sapiViews/core/rich/regionsHierarchy/regionsHierarchy.component.ts @@ -20,6 +20,7 @@ const filterByRegexPipe = new FilterByRegexPipe() }) export class SapiViewsCoreRichRegionsHierarchy { + TXT_CANNOT_BE_SELECTED = "Not mapped in this template space." static IsParent(region: SxplrRegion, parentRegion: SxplrRegion): boolean { return region.parentIds.some(id => parentRegion.id === id) @@ -36,6 +37,9 @@ export class SapiViewsCoreRichRegionsHierarchy { ) } + @Input('sxplr-sapiviews-core-rich-regionshierarchy-label-mapped-region-names') + labelMappedRegionNames: string[] = [] + @Input('sxplr-sapiviews-core-rich-regionshierarchy-accent-regions') accentedRegions: SxplrRegion[] = [] @@ -100,10 +104,9 @@ export class SapiViewsCoreRichRegionsHierarchy { onNodeClick({node: roi, event }: {node: SxplrRegion, event: MouseEvent}){ /** - * only allow leave nodes to be selectable for now + * Only allow the regions that are labelled mapped to be selected. */ - const children = this._regions.filter(r => this.isParent(r, roi)) - if (children.length > 0) { + if (!this.labelMappedRegionNames.includes(roi.name)) { return } if (event.ctrlKey) { diff --git a/src/atlasComponents/sapiViews/core/rich/regionsHierarchy/regionsHierarchy.template.html b/src/atlasComponents/sapiViews/core/rich/regionsHierarchy/regionsHierarchy.template.html index 762ae45d856a8a5e53defdfbeea120c2437df898..fe58b7efcf598036e2fbae302f54720a9d0369d0 100644 --- a/src/atlasComponents/sapiViews/core/rich/regionsHierarchy/regionsHierarchy.template.html +++ b/src/atlasComponents/sapiViews/core/rich/regionsHierarchy/regionsHierarchy.template.html @@ -14,10 +14,12 @@ </mat-form-field> -<ng-template #tmplRef let-region> +<ng-template #tmplRef let-region let-last="last"> <div class="mat-body sxplr-d-flex sxplr-align-items-center sxplr-h-100 region-tmpl" + [matTooltip]="last && !labelMappedRegionNames.includes(region.name) ? TXT_CANNOT_BE_SELECTED : null" [ngClass]="{ - 'sxplr-custom-cmp accent': accentedRegions | includes : region + 'sxplr-custom-cmp accent': accentedRegions | includes : region, + 'muted-7': !labelMappedRegionNames.includes(region.name) }" [innerHTML]="region.name | hightlightPipe : searchTerm"> </div> diff --git a/src/components/flatHierarchy/treeView/treeView.template.html b/src/components/flatHierarchy/treeView/treeView.template.html index 730cd04b0122a538195b971e9f8f90f39eed7e46..7ecb9798a4b6300275d18e0a8ee753062d8c67df 100644 --- a/src/components/flatHierarchy/treeView/treeView.template.html +++ b/src/components/flatHierarchy/treeView/treeView.template.html @@ -23,7 +23,8 @@ <ng-template [ngTemplateOutlet]="phTmpl" [ngTemplateOutletContext]="{ - $implicit: node + $implicit: node, + last: !node.expandable }"> </ng-template> @@ -51,7 +52,8 @@ <ng-template [ngTemplateOutlet]="renderNodeTmplRef" [ngTemplateOutletContext]="{ - $implicit: node.node + $implicit: node.node, + last: !node.expandable }"> </ng-template> </div> diff --git a/src/features/guards.ts b/src/features/guards.ts index fefbc7a0bbc14d1a5baf042ec6283de30d6516ed..eff1ea272787e87cee62e2fc5e10305880ea9452 100644 --- a/src/features/guards.ts +++ b/src/features/guards.ts @@ -8,11 +8,6 @@ export function isVoiData(feature: unknown): feature is VoiFeature { return !!feature['bbox'] } -export function notQuiteRight(feature: unknown): string[] { - if (feature['name'].includes("Cellular level 3D reconstructed volumes at 1µm resolution")) { - return [ - "This volume is currently not displayed correctly. We are working to restore the functionality." - ] - } +export function notQuiteRight(_feature: unknown): string[] { return [] } diff --git a/src/viewerModule/viewerCmp/viewerCmp.component.ts b/src/viewerModule/viewerCmp/viewerCmp.component.ts index 75f18fd1e32b272b33b510222e3d11f9e71ffee6..8a5ed8f0aa91d858e4b617f81b7923658eebfdca 100644 --- a/src/viewerModule/viewerCmp/viewerCmp.component.ts +++ b/src/viewerModule/viewerCmp/viewerCmp.component.ts @@ -1,7 +1,7 @@ import { ChangeDetectionStrategy, ChangeDetectorRef, Component, OnDestroy, TemplateRef, ViewChild } from "@angular/core"; import { select, Store } from "@ngrx/store"; -import { combineLatest, Observable, Subscription } from "rxjs"; -import { debounceTime, map, shareReplay } from "rxjs/operators"; +import { combineLatest, Observable, of, Subscription } from "rxjs"; +import { debounceTime, map, shareReplay, switchMap } from "rxjs/operators"; import { CONST, ARIA_LABELS, QUICKTOUR_DESC } from 'common/constants' import { animate, state, style, transition, trigger } from "@angular/animations"; import { IQuickTourData } from "src/ui/quickTour"; @@ -139,15 +139,41 @@ export class ViewerCmp implements OnDestroy { select(atlasSelection.selectors.relevantSelectedPoint) ) - public view$ = combineLatest([ + #currentMap$ = combineLatest([ + this.#templateSelected$, + this.#parcellationSelected$ + ]).pipe( + switchMap(([tmpl, parc]) => tmpl && parc ? this.sapi.getLabelledMap(parc, tmpl) : of(null)) + ) + + + #view0$ = combineLatest([ this.#selectedRegions$, this.#viewerMode$, this.#selectedFeature$, this.#selectedPoint$, this.#templateSelected$, - this.#parcellationSelected$ + this.#parcellationSelected$, ]).pipe( - map(([ selectedRegions, viewerMode, selectedFeature, selectedPoint, selectedTemplate, selectedParcellation ]) => { + map(([ selectedRegions, viewerMode, selectedFeature, selectedPoint, selectedTemplate, selectedParcellation ]) => ({ + selectedRegions, viewerMode, selectedFeature, selectedPoint, selectedTemplate, selectedParcellation + })) + ) + + #view1$ = combineLatest([ + this.#currentMap$, + ]).pipe( + map(( [ currentMap ] ) => ({ + currentMap + })) + ) + + public view$ = combineLatest([ + this.#view0$, + this.#view1$, + ]).pipe( + map(([v0, v1]) => ({ ...v0, ...v1 })), + map(({ selectedRegions, viewerMode, selectedFeature, selectedPoint, selectedTemplate, selectedParcellation, currentMap }) => { let spatialObjectTitle: string let spatialObjectSubtitle: string if (selectedPoint) { @@ -162,6 +188,8 @@ export class ViewerCmp implements OnDestroy { if (!!selectedTemplate) { spatialObjectSubtitle = selectedTemplate.name } + + const labelMappedRegionNames = currentMap && Object.keys(currentMap.indices) || [] return { viewerMode, selectedRegions, @@ -169,6 +197,7 @@ export class ViewerCmp implements OnDestroy { selectedPoint, selectedTemplate, selectedParcellation, + labelMappedRegionNames, /** * Selected Spatial Object diff --git a/src/viewerModule/viewerCmp/viewerCmp.template.html b/src/viewerModule/viewerCmp/viewerCmp.template.html index 459fb19e841d22944af9cf5a8bca36512bcb6d0c..283145b6593162e36d9512a269f3f5abd48cb37b 100644 --- a/src/viewerModule/viewerCmp/viewerCmp.template.html +++ b/src/viewerModule/viewerCmp/viewerCmp.template.html @@ -540,6 +540,7 @@ <sxplr-sapiviews-core-rich-regionshierarchy class="sxplr-w-100 sxplr-flex-var" [sxplr-sapiviews-core-rich-regionshierarchy-regions]="allAvailableRegions$ | async" + [sxplr-sapiviews-core-rich-regionshierarchy-label-mapped-region-names]="view.labelMappedRegionNames" [sxplr-sapiviews-core-rich-regionshierarchy-accent-regions]="view.selectedRegions" (sxplr-sapiviews-core-rich-regionshierarchy-region-select)="selectRoi($event)" (sxplr-sapiviews-core-rich-regionshierarchy-region-toggle)="toggleRoi($event)"