diff --git a/.storybook/preview-head.html b/.storybook/preview-head.html index 4fc7d43c724b20c459f30fe30003336909a341a5..e10e90c524e66a165ea6536fed9a6c91b6875f6f 100644 --- a/.storybook/preview-head.html +++ b/.storybook/preview-head.html @@ -1,7 +1,6 @@ <script> console.log("./storybook/preview-head.html working properly") </script> -<script src="https://unpkg.com/kg-dataset-previewer@1.2.0/dist/kg-dataset-previewer/kg-dataset-previewer.js" defer></script> <script src="main.bundle.js" defer></script> <style> body diff --git a/docs/releases/v2.13.0.md b/docs/releases/v2.13.0.md new file mode 100644 index 0000000000000000000000000000000000000000..415537c22be8f967c66af2346513514b03330348 --- /dev/null +++ b/docs/releases/v2.13.0.md @@ -0,0 +1,9 @@ +# v2.13.0 + +## Feature + +- reworked UI +- allow fsaverage grid to be toggled on/off +- disable surface face selection (until it becomes fully supported) +- allow feature to be downloaded +- main download button also downloads selected feature diff --git a/package.json b/package.json index 5362349f32bea024d80e831723fa469611008978..61905b375982273f0594ad19d1b873903bbb6768 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "siibra-explorer", - "version": "2.12.0", + "version": "2.13.0", "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/atlas-download/atlas-download.directive.ts b/src/atlas-download/atlas-download.directive.ts index 9b2ba98268b8f52cebec05803ca637a0d75e2353..ca0e8d23cf5d80d62f99cf36d790f3aa28ed94a2 100644 --- a/src/atlas-download/atlas-download.directive.ts +++ b/src/atlas-download/atlas-download.directive.ts @@ -6,6 +6,7 @@ import { distinctUntilChanged, shareReplay, take } from 'rxjs/operators'; import { SAPI } from 'src/atlasComponents/sapi'; import { MainState } from 'src/state'; import { fromRootStore, selectors } from "src/state/atlasSelection" +import { selectors as userInteractionSelectors } from "src/state/userInteraction" import { wait } from "src/util/fn" @Directive({ @@ -29,6 +30,11 @@ export class AtlasDownloadDirective { take(1) ).toPromise() + const selectedFeature = await this.store.pipe( + select(userInteractionSelectors.selectedFeature), + take(1) + ).toPromise() + const endpoint = await SAPI.BsEndpoint$.pipe( take(1) ).toPromise() @@ -41,11 +47,33 @@ export class AtlasDownloadDirective { if (selectedRegions.length === 1) { query['region_id'] = selectedRegions[0].name } + if (selectedFeature) { + query['feature_id'] = selectedFeature.id + } for (const key in query) { url.searchParams.set(key, query[key]) } const resp = await fetch(url) + const ct = resp.headers.get("content-type") + if (ct === "application/octet-stream") { + const cd = resp.headers.get("content-disposition") || "filename=download.zip" + const filename = cd.split("=")[1] + const blob = await resp.blob() + const url = URL.createObjectURL(blob) + + const a = document.createElement("a") + a.href = url + a.download = filename + document.body.appendChild(a) + a.click() + document.body.removeChild(a) + URL.revokeObjectURL(url) + + this.#busy$.next(false) + return + } + const { task_id } = await resp.json() if (!task_id) { diff --git a/src/atlasComponents/sapi/sxplrTypes.ts b/src/atlasComponents/sapi/sxplrTypes.ts index 95860602d584abe68740c2bbe9a5a4018e5e8641..81e478b29e3a6491838bd4d840afc6c82824f4fb 100644 --- a/src/atlasComponents/sapi/sxplrTypes.ts +++ b/src/atlasComponents/sapi/sxplrTypes.ts @@ -120,11 +120,6 @@ export type CorticalFeature<T extends CorticalDataType, IndexType extends string type TabularDataType = number | string | number[] -export type TabularFeature<T extends TabularDataType> = { - index: unknown[] - columns: unknown[] - data?: T[][] -} & Feature export type GenericInfo = { name: string diff --git a/src/atlasComponents/sapi/translateV3.ts b/src/atlasComponents/sapi/translateV3.ts index 71cb316e394b2dd43ecdb9f1da3ec6fb845acc36..93a04c90a90aa18c049acaa177e32b0d83102d91 100644 --- a/src/atlasComponents/sapi/translateV3.ts +++ b/src/atlasComponents/sapi/translateV3.ts @@ -1,5 +1,5 @@ import { - SxplrAtlas, SxplrParcellation, SxplrTemplate, SxplrRegion, NgLayerSpec, NgPrecompMeshSpec, NgSegLayerSpec, VoiFeature, Point, TThreeMesh, LabelledMap, CorticalFeature, Feature, TabularFeature, GenericInfo, BoundingBox + SxplrAtlas, SxplrParcellation, SxplrTemplate, SxplrRegion, NgLayerSpec, NgPrecompMeshSpec, NgSegLayerSpec, VoiFeature, Point, TThreeMesh, LabelledMap, CorticalFeature, Feature, GenericInfo, BoundingBox } from "./sxplrTypes" import { PathReturn } from "./typeV3" import { hexToRgb } from 'common/util' @@ -409,10 +409,7 @@ class TranslateV3 { } } - async translateFeature(feat: PathReturn<"/feature/{feature_id}">): Promise<TabularFeature<number|string|number[]>|VoiFeature|Feature> { - if (this.#isTabular(feat)) { - return await this.translateTabularFeature(feat) - } + async translateFeature(feat: PathReturn<"/feature/{feature_id}">): Promise<VoiFeature|Feature> { if (this.#isVoi(feat)) { return await this.translateVoiFeature(feat) } @@ -464,22 +461,6 @@ class TranslateV3 { ngVolume: precomputedVol } } - - #isTabular(feat: unknown): feat is PathReturn<"/feature/Tabular/{feature_id}"> { - return feat["@type"].includes("feature/tabular") - } - async translateTabularFeature(feat: unknown): Promise<TabularFeature<number | string| number[]>> { - if (!this.#isTabular(feat)) throw new Error(`Feature is not of tabular type`) - const superObj = await this.translateBaseFeature(feat) - const { data: _data } = feat - const { index, columns, data } = _data || {} - return { - ...superObj, - columns, - index, - data - } - } async translateCorticalProfile(feat: PathReturn<"/feature/CorticalProfile/{feature_id}">): Promise<CorticalFeature<number>> { return { diff --git a/src/atlasComponents/sapiViews/core/region/region/rich/region.rich.template.html b/src/atlasComponents/sapiViews/core/region/region/rich/region.rich.template.html index fa9e90bdc672512a632030df3af522c903af4b40..bfa0c7cd41ecc40131b9f23a7468fc72d0a67d2f 100644 --- a/src/atlasComponents/sapiViews/core/region/region/rich/region.rich.template.html +++ b/src/atlasComponents/sapiViews/core/region/region/rich/region.rich.template.html @@ -15,92 +15,20 @@ <ng-template [ngTemplateOutlet]="headerTmpl"></ng-template> - <ng-template sxplrExperimentalFlag [experimental]="true" #subtitleExpm="sxplrExperimentalFlag" [ngIf]="subtitleExpm.show$ | async"> <mat-card-subtitle> <span class="muted-text"> Brain region </span> </mat-card-subtitle> - </ng-template> <mat-card-title class="sxplr-custom-cmp text"> {{ region.name }} </mat-card-title> - - <ng-template sxplrExperimentalFlag [deprecated]="true" #subtitleDep="sxplrExperimentalFlag" [ngIf]="subtitleDep.show$ | async"> - <mat-card-subtitle> - {{ parcellation.name }} - </mat-card-subtitle> - - - <!-- subtitle on what it is --> - <mat-card-subtitle class="d-inline-flex align-items-center flex-wrap"> - <mat-icon fontSet="fas" fontIcon="fa-brain"></mat-icon> - <span> - Brain region - </span> - - <!-- origin datas format --> - - <mat-divider vertical="true" class="sxplr-pl-2 h-2rem"></mat-divider> - - <!-- position --> - <button mat-icon-button *ngIf="regionPosition" - (click)="navigateTo(regionPosition)" - [matTooltip]="ARIA_LABELS.GO_TO_REGION_CENTROID + ': ' + (regionPosition | numbers | addUnitAndJoin : 'mm')"> - <mat-icon fontSet="fas" fontIcon="fa-map-marked-alt"> - </mat-icon> - </button> - - <!-- explore doi --> - <a *ngFor="let doi of dois$ | async" - [href]="doi | parseDoi" - sxplr-hide-when-local - [matTooltip]="ARIA_LABELS.EXPLORE_DATASET_IN_KG" - target="_blank" - mat-icon-button> - <i class="fas fa-external-link-alt"></i> - </a> - - </mat-card-subtitle> - </ng-template> </div> </mat-card> - <!-- desc --> - <ng-template sxplrExperimentalFlag [deprecated]="true" #subtitleDep="sxplrExperimentalFlag" [ngIf]="subtitleDep.show$ | async"> - <ng-template [ngIf]="(desc$ | async) || region.desc" let-desc> - <readmore-component> - <markdown-dom class="sxplr-m-2 sxplr-muted" [markdown]="desc"> - </markdown-dom> - </readmore-component> - </ng-template> - </ng-template> - - <ng-template sxplrExperimentalFlag [deprecated]="true" #headerDep="sxplrExperimentalFlag" [ngIf]="headerDep.show$ | async"> - <!-- header for regional feature --> - <mat-card> - <mat-card-header> - <mat-card-title> - Features anchored to region - </mat-card-title> - </mat-card-header> - <mat-card-content *ngIf="!(featureEntryCmp.busyTallying$ | async) && (featureEntryCmp.totals$ | async) == 0" - class="text-muted"> - No regional features found. - </mat-card-content> - </mat-card> - - <sxplr-feature-entry - [template]="template" - [parcellation]="parcellation" - [region]="region" - #featureEntryCmp="featureEntryCmp"> - </sxplr-feature-entry> - </ng-template> - <ng-template sxplrExperimentalFlag [experimental]="true" #tabExpmpt="sxplrExperimentalFlag" [ngIf]="tabExpmpt.show$ | async"> <mat-tab-group> <!-- Overview --> @@ -167,6 +95,5 @@ </sxplr-feature-entry> </mat-tab> </mat-tab-group> - </ng-template> </ng-template> diff --git a/src/atlasComponents/sapiViews/core/rich/ATPSelector/pureDumb/pureATPSelector.style.scss b/src/atlasComponents/sapiViews/core/rich/ATPSelector/pureDumb/pureATPSelector.style.scss index ca8414023c4f8e6a8863d5ef9bce7a5bf9286d34..5ad8ab80f7c0182fe95a6c5415081faa564a26bf 100644 --- a/src/atlasComponents/sapiViews/core/rich/ATPSelector/pureDumb/pureATPSelector.style.scss +++ b/src/atlasComponents/sapiViews/core/rich/ATPSelector/pureDumb/pureATPSelector.style.scss @@ -35,7 +35,6 @@ sxplr-smart-chip:not(:last-child) } } -:host-context([experimental=true]) sxplr-smart-chip:not(:last-child) { .header diff --git a/src/components/smartChip/component/smartChip.style.scss b/src/components/smartChip/component/smartChip.style.scss index bed16c0901c9f0c34bba3011e24842fd641ea86f..a1e0f0116c533299fce7e4d25a5c9d792d60f0a5 100644 --- a/src/components/smartChip/component/smartChip.style.scss +++ b/src/components/smartChip/component/smartChip.style.scss @@ -7,64 +7,61 @@ } -:host-context([experimental=true]) +:host { - :host + margin: 0; + min-height: 44px; +} + +.smart-chip +{ + display: inline-flex; + flex-direction: row; + border-radius: 22px; + justify-content: center; + + >.text { - margin: 0; - min-height: 44px; + height: 0px; + overflow: visible; + display: inline-flex; + flex-direction: column; + justify-content: center; } - .smart-chip - { + >.icons + { + height: 0px; + overflow: visible; display: inline-flex; flex-direction: row; - border-radius: 22px; - justify-content: center; - - >.text - { - height: 0px; - overflow: visible; - display: inline-flex; - flex-direction: column; - justify-content: center; - } - - >.icons - { - height: 0px; - overflow: visible; - display: inline-flex; - flex-direction: row; - align-items: center; - } + align-items: center; } +} - .header - { +.header +{ - font-size: 80%; - margin-top:-0.5rem; - margin-bottom:0.3rem; - flex-basis: 1rem; - } + font-size: 80%; + margin-top:-0.5rem; + margin-bottom:0.3rem; + flex-basis: 1rem; +} - .body +.body +{ + width: 100%; + flex: 1 1 0; + display: flex; + align-items: flex-start; + + >.body-content-wrapper { + height: 1px; width: 100%; - flex: 1 1 0; + overflow: visible; display: flex; - align-items: start; - - >.body-content-wrapper - { - height: 1px; - width: 100%; - overflow: visible; - display: flex; - align-items: center; - } + align-items: center; } } @@ -74,7 +71,6 @@ height: 100%; padding: 0.8rem 1.6rem; - border-radius: 1rem; display: inline-flex; flex-direction: row; diff --git a/src/components/smartChip/component/smartChip.template.html b/src/components/smartChip/component/smartChip.template.html index e057e15013e0a3275e8a3f0b1bdadb761ddb116b..2baef9e66351cb05241be6d0b6ad7c3f8b102891 100644 --- a/src/components/smartChip/component/smartChip.template.html +++ b/src/components/smartChip/component/smartChip.template.html @@ -1,8 +1,3 @@ -<ng-template [ngIf]="experimental.show$ | async" - let-tmpl - sxplrExperimentalFlag - [experimental]="true" - #experimental="sxplrExperimentalFlag"> <div [style.background-color]="color" [matMenuTriggerFor]="noMenuFlag ? null : mainMenu" @@ -39,41 +34,6 @@ </div> -</ng-template> - - - -<ng-template [ngIf]="deprecated.show$ | async" - - sxplrExperimentalFlag - [deprecated]="true" - #deprecated="sxplrExperimentalFlag"> - -<div [style.background-color]="color" - [matMenuTriggerFor]="noMenuFlag ? null : mainMenu" - matRipple - [matRippleDisabled]="noMenuFlag" - [ngClass]="smartChipClass" - class="mat-body smart-chip body sxplr-custom-cmp text"> - <ng-template [ngTemplateOutlet]="contentTmpl?.templateRef || fallbackContentTmpl"> - </ng-template> -</div> - -<!-- header component --> -<ng-template [ngIf]="headerTmpl?.templateRef" let-tmpl> - <div class="mat-body smart-chip sxplr-custom-cmp text header mat-elevation-z2" - [style.background-color]="color" - matRipple - [matRippleDisabled]="noMenuFlag" - [matMenuTriggerFor]="noMenuFlag ? null : mainMenu"> - <ng-template [ngTemplateOutlet]="tmpl"> - </ng-template> - </div> -</ng-template> - -</ng-template> - - <!-- main menu is fired from chip --> <mat-menu #mainMenu="matMenu"> <ng-template ngFor [ngForOf]="items" let-item> diff --git a/src/environments/environment.common.ts b/src/environments/environment.common.ts index 75284adf0db83a1213cfb5f2b94293b46330e9b5..0253c2aeae7f71fcc509227607b4870a8d131dff 100644 --- a/src/environments/environment.common.ts +++ b/src/environments/environment.common.ts @@ -4,7 +4,7 @@ export const environment = { VERSION: 'unknown version', PRODUCTION: false, BACKEND_URL: null, - SIIBRA_API_ENDPOINTS: 'https://siibra-api-latest.apps-dev.hbp.eu/v3_0', //'https://siibra-api-stable.apps.hbp.eu/v2_0,https://siibra-api-stable.apps.jsc.hbp.eu/v2_0,https://siibra-api-stable-ns.apps.hbp.eu/v2_0', + SIIBRA_API_ENDPOINTS: 'http://localhost:8000/v3_0', // 'https://siibra-api-latest.apps-dev.hbp.eu/v3_0', //'https://siibra-api-stable.apps.hbp.eu/v2_0,https://siibra-api-stable.apps.jsc.hbp.eu/v2_0,https://siibra-api-stable-ns.apps.hbp.eu/v2_0', SPATIAL_TRANSFORM_BACKEND: 'https://hbp-spatial-backend.apps.hbp.eu', MATOMO_URL: null, MATOMO_ID: null, diff --git a/src/extra_styles.css b/src/extra_styles.css index e09f456a91c20007fbd2ac358e20b4de3828cfb2..2c01c2b2a82ba7e56f13353d55dd38de7f06dea1 100644 --- a/src/extra_styles.css +++ b/src/extra_styles.css @@ -703,12 +703,6 @@ body::after opacity: 0.0!important; } -kg-dataset-previewer > img -{ - max-width: 100%; - width: 100%; -} - .m-15 { margin: 15px; diff --git a/src/features/entry/entry.flattened.component.html b/src/features/entry/entry.flattened.component.html index a84bcbd119d259f038f947728ca8d869c90e13fd..bf4ba0534083eca964afb00bedea023bbb52f7d9 100644 --- a/src/features/entry/entry.flattened.component.html +++ b/src/features/entry/entry.flattened.component.html @@ -79,8 +79,6 @@ #filterFeatureCls="featureFilterDirective"> <div class="mat-chip-inner-container"> - - <ng-template sxplrExperimentalFlag [experimental]="true" #filterExmpt="sxplrExperimentalFlag" [ngIf]="filterExmpt.show$ | async"> <button mat-stroked-button matTooltip="Filters" [color]="(filterFeatureCls.unchecked$ | async).length > 0 ? 'primary' : 'default'" @@ -161,55 +159,6 @@ </ng-template> </ng-template> - </ng-template> - - - <ng-template sxplrExperimentalFlag [deprecated]="true" [ngIf]="filterDep.show$ | async" #filterDep="sxplrExperimentalFlag"> - <button mat-icon-button matTooltip="Reset filter" - (click)="filterFeatureCls.setAll(true)"> - <i class="fas fa-filter"></i> - </button> - - <ng-template ngFor [ngForOf]="filterFeatureCls.items" let-grpFeat> - <ng-template [ngIf]="grpFeat.meta.total > 0"> - - <ng-template [ngIf]="filterFeatureCls.checked$ | async | grpFeatToName | includes : grpFeat.meta.displayName" - [ngIfThen]="selectedTmpl" - [ngIfElse]="notSelectedTmpl"> - </ng-template> - - <ng-template #textTmpl> - <span> - {{ grpFeat.meta.displayName }} - </span> - <span class="text-muted1"> - ({{ grpFeat.meta.total }}) - </span> - </ng-template> - <ng-template #selectedTmpl> - <button mat-flat-button - (click)="filterFeatureCls.toggle(grpFeat)" - color="primary"> - <i class="fas fa-eye"></i> - <ng-template [ngTemplateOutlet]="textTmpl"> - </ng-template> - </button> - </ng-template> - - <ng-template #notSelectedTmpl> - <button mat-flat-button - (click)="filterFeatureCls.toggle(grpFeat)" - color="default"> - <i class="fas fa-eye-slash"></i> - <ng-template [ngTemplateOutlet]="textTmpl"> - </ng-template> - </button> - </ng-template> - - </ng-template> - </ng-template> - </ng-template> - </div> </div> diff --git a/src/features/entry/entry.flattened.component.scss b/src/features/entry/entry.flattened.component.scss index 22f832afcf5e1e65f52bfa281dbb30e3075feefb..7c69e0ef111a695a8eaf67be47dac6b7473fe6c8 100644 --- a/src/features/entry/entry.flattened.component.scss +++ b/src/features/entry/entry.flattened.component.scss @@ -9,7 +9,7 @@ cdk-virtual-scroll-viewport button height: 36px; display: block; } -:host-context([experimental=true]) + .mat-chip-container { overflow-x: unset!important; diff --git a/src/features/feature-view/feature-view.component.html b/src/features/feature-view/feature-view.component.html index 18b7d05a3e55d7a58a95d3618db251669160902f..3c4be84af0ff5834ab67407dacde7277d0848494 100644 --- a/src/features/feature-view/feature-view.component.html +++ b/src/features/feature-view/feature-view.component.html @@ -15,7 +15,6 @@ <ng-template [ngTemplateOutlet]="headerTmpl"></ng-template> - <ng-template sxplrExperimentalFlag #subtitleExmpt="sxplrExperimentalFlag" [experimental]="true" [ngIf]="subtitleExmpt.show$ | async"> <mat-card-subtitle> <ng-template [ngIf]="feature.category"> <span class="sxplr-m-a sxplr-pr-1"> @@ -28,7 +27,6 @@ </span> </ng-template> </mat-card-subtitle> - </ng-template> <mat-card-title> <div class="feature-title"> @@ -36,75 +34,8 @@ </div> </mat-card-title> - <ng-template sxplrExperimentalFlag [deprecated]="true" [ngIf]="subtitleDep.show$ | async" #subtitleDep="sxplrExperimentalFlag"> - <mat-card-subtitle class="sxplr-d-inline-flex sxplr-align-items-stretch"> - <ng-template [ngIf]="feature.category"> - <mat-icon class="sxplr-m-a" fontSet="fas" fontIcon="fa-database"></mat-icon> - <span class="sxplr-m-a sxplr-pr-1"> - <ng-template [ngIf]="feature.category !== 'Unknown category'" [ngIfElse]="fallbackTmpl"> - {{ feature.category }} - </ng-template> - <ng-template #fallbackTmpl> - Other - </ng-template> - </span> - </ng-template> - - <ng-template [ngIf]="warnings$ | async" let-warnings> - <mat-divider [vertical]="true"></mat-divider> - <ng-template ngFor [ngForOf]="warnings" let-warning> - <button mat-icon-button - [matTooltip]="warning"> - <i class="fas fa-exclamation-triangle"></i> - </button> - </ng-template> - </ng-template> - - <mat-divider [vertical]="true"></mat-divider> - - <ng-template [ngIf]="busy$ | async"> - <spinner-cmp></spinner-cmp> - </ng-template> - - <!-- template for external link --> - <ng-template #externalLinkTmpl let-url> - <a mat-icon-button sxplr-hide-when-local [href]="url" target="_blank"> - <i class="fas fa-external-link-alt"></i> - </a> - </ng-template> - - <!-- if link is prepopulated --> - <ng-template - ngFor - [ngForOf]="feature.link" - let-url> - <ng-template - [ngTemplateOutlet]="externalLinkTmpl" - [ngTemplateOutletContext]="{ - $implicit: url.href - }"> - </ng-template> - </ng-template> - - <!-- if link is lazy fetched --> - <ng-template - ngFor - [ngForOf]="additionalLinks$ | async" - let-url> - <ng-template - [ngTemplateOutlet]="externalLinkTmpl" - [ngTemplateOutletContext]="{ - $implicit: url - }"> - </ng-template> - </ng-template> - - </mat-card-subtitle> - </ng-template> - </mat-card> -<ng-template sxplrExperimentalFlag #newPanelExpmt="sxplrExperimentalFlag" [experimental]="true" [ngIf]="newPanelExpmt.show$ | async"> <mat-tab-group> <mat-tab label="Overview"> @@ -145,10 +76,8 @@ </mat-action-list> - <readmore-component [collapsedHeight]="240" class="sxplr-mb-8"> - <markdown-dom class="sxplr-m-2 sxplr-muted" [markdown]="feature.desc"> - </markdown-dom> - </readmore-component> + <markdown-dom class="sxplr-m-2 sxplr-muted" [markdown]="feature.desc"> + </markdown-dom> </mat-tab> <mat-tab *ngIf="busy$ | async"> @@ -157,51 +86,6 @@ </ng-template> </mat-tab> - <!-- radar special view --> - <ng-template [ngIf]="polar$ | async" let-polar> - <mat-tab label="Visualization"> - <kg-dataset-dumb-radar - [radar]="polar" - [attr.kg-ds-prv-darkmode]="darktheme$ | async"> - </kg-dataset-dumb-radar> - </mat-tab> - </ng-template> - - <!-- line special view --> - <ng-template [ngIf]="linear$ | async" let-linear> - <mat-tab label="Visualization"> - <kg-dataset-dumb-line - [profileBs]="linear" - [attr.kg-ds-prv-darkmode]="darktheme$ | async"> - </kg-dataset-dumb-line> - </mat-tab> - </ng-template> - - <!-- tabular special view --> - <!-- suppress tabuular view if linear or polar is visible --> - <ng-template [ngIf]="!(linear$ | async) && !(polar$ | async)"> - <ng-template [ngIf]="tabular$ | async" let-tabular> - - <mat-tab label="Visualization"> - <table class="feature-detail" mat-table [dataSource]="tabular | transformPdToDs"> - - <ng-container *ngFor="let column of columns$ | async" - [matColumnDef]="column"> - <th mat-header-cell *matHeaderCellDef> - {{ column }} - </th> - <td mat-cell *matCellDef="let element"> - {{ element[column] }} - </td> - </ng-container> - - <tr mat-header-row *matHeaderRowDef="columns$ | async"></tr> - <tr mat-row *matRowDef="let row; columns: columns$ | async;"></tr> - </table> - </mat-tab> - </ng-template> - </ng-template> - <!-- voi special view --> <ng-template [ngIf]="voi$ | async" let-voi> <mat-tab label="Volume Control"> @@ -218,7 +102,7 @@ <!-- plotly view --> <ng-template [ngIf]="plotly$ | async" let-plotly> - <mat-tab label="Plotly"> + <mat-tab label="Visualization"> <ng-template matTabContent> <sxplr-plotly-component [plotly-json]="plotly"></sxplr-plotly-component> </ng-template> @@ -226,65 +110,3 @@ </ng-template> </mat-tab-group> -</ng-template> - -<ng-template sxplrExperimentalFlag #oldpanelDep="sxplrExperimentalFlag" [deprecated]="true" [ngIf]="oldpanelDep.show$ | async"> -<mat-card *ngIf="feature" class="sxplr-z-0"> - <mat-card-content> - <!-- TODO fix feature typing! with proper translate fn --> - <markdown-dom class="sxplr-muted" [markdown]="feature.desc"> - </markdown-dom> - </mat-card-content> -</mat-card> - -<!-- radar special view --> -<ng-template [ngIf]="polar$ | async" let-polar> - <kg-dataset-dumb-radar - [radar]="polar" - [attr.kg-ds-prv-darkmode]="darktheme$ | async"> - </kg-dataset-dumb-radar> -</ng-template> - -<!-- line special view --> -<ng-template [ngIf]="linear$ | async" let-linear> - <kg-dataset-dumb-line - [profileBs]="linear" - [attr.kg-ds-prv-darkmode]="darktheme$ | async"> - </kg-dataset-dumb-line> -</ng-template> - -<!-- tabular special view --> -<!-- suppress tabuular view if linear or polar is visible --> -<ng-template [ngIf]="!(linear$ | async) && !(polar$ | async)"> - - <ng-template [ngIf]="tabular$ | async" let-tabular> - <table class="feature-detail" mat-table [dataSource]="tabular | transformPdToDs"> - - <ng-container *ngFor="let column of columns$ | async" - [matColumnDef]="column"> - <th mat-header-cell *matHeaderCellDef> - {{ column }} - </th> - <td mat-cell *matCellDef="let element"> - {{ element[column] }} - </td> - </ng-container> - - <tr mat-header-row *matHeaderRowDef="columns$ | async"></tr> - <tr mat-row *matRowDef="let row; columns: columns$ | async;"></tr> - </table> - </ng-template> -</ng-template> - -<!-- voi special view --> -<ng-template [ngIf]="voi$ | async" let-voi> - <ng-layer-ctl - [ng-layer-ctl-name]="voi.ngVolume.url" - [ng-layer-ctl-src]="voi.ngVolume.url" - [ng-layer-ctl-transform]="voi.ngVolume.transform" - [ng-layer-ctl-info]="voi.ngVolume.info" - [ng-layer-ctl-opacity]="1.0" - [ng-layer-ctrl-show]="true"> - </ng-layer-ctl> -</ng-template> -</ng-template> \ No newline at end of file diff --git a/src/features/feature-view/feature-view.component.scss b/src/features/feature-view/feature-view.component.scss index 85dbde349d4a8d0336355208c54df5093c921856..02064737f27bc462d44c78afed57c88a044a8e34 100644 --- a/src/features/feature-view/feature-view.component.scss +++ b/src/features/feature-view/feature-view.component.scss @@ -16,29 +16,18 @@ spinner-cmp margin-left: 0.5rem; } -kg-dataset-dumb-radar, -kg-dataset-dumb-line -{ - display: block; - max-height: 24rem; -} - readmore-component { width: 100%; } -:host-context([experimental="true"]) +.header-card { + background-color: #fee; +} + +:host-context([darktheme="true"]) { - .header-card { - background-color: #fee; - } - - &:host-context([darktheme="true"]) - { - .header-card { - background-color: #433; - } + background-color: #433; } -} +} \ No newline at end of file diff --git a/src/features/feature-view/feature-view.component.ts b/src/features/feature-view/feature-view.component.ts index c9d6b8bafaba8d55a05fa0d2f0165968d19a7cde..c640a110b29cf8144f9f6b2dda70df9ca9c183a6 100644 --- a/src/features/feature-view/feature-view.component.ts +++ b/src/features/feature-view/feature-view.component.ts @@ -2,9 +2,9 @@ import { ChangeDetectionStrategy, Component, Inject, Input, OnChanges } from '@a import { BehaviorSubject, Observable, Subject, combineLatest, of } from 'rxjs'; import { catchError, distinctUntilChanged, filter, map, shareReplay, switchMap } from 'rxjs/operators'; import { SAPI } from 'src/atlasComponents/sapi/sapi.service'; -import { Feature, TabularFeature, VoiFeature } from 'src/atlasComponents/sapi/sxplrTypes'; +import { Feature, VoiFeature } from 'src/atlasComponents/sapi/sxplrTypes'; import { DARKTHEME } from 'src/util/injectionTokens'; -import { isTabularData, isVoiData, notQuiteRight } from "../guards" +import { isVoiData, notQuiteRight } from "../guards" type PolarPlotData = { receptor: { @@ -59,44 +59,7 @@ export class FeatureViewComponent implements OnChanges { busy$ = new BehaviorSubject<boolean>(false) - tabular$ = new BehaviorSubject<TabularFeature<number|string|number[]>>(null) voi$ = new BehaviorSubject<VoiFeature>(null) - columns$: Observable<string[]> = this.tabular$.pipe( - map(data => data - ? ['index', ...data.columns] as string[] - : []), - ) - - polar$: Observable<PolarPlotData[]> = this.tabular$.pipe( - filter(v => v?.name.includes("ReceptorDensityFingerprint")), - map(v => { - return v.index.map((receptor, idx) => ({ - receptor: { - label: receptor as string - }, - density: { - mean: v.data[idx][0] as number, - sd: v.data[idx][1] as number, - unit: 'fmol/mg' - } - })) - }) - ) - - linear$: Observable<Record<number, number>> = this.tabular$.pipe( - filter(v => v && v.name.includes("ReceptorDensityProfile")), - map(v => { - const returnLbl: Record<number, number> = {} - - v.index.forEach((label, idx) => { - const val = v.data[idx][0] - if (typeof val === 'number') { - returnLbl[Math.round(Number(label)*100)] = val - } - }) - return returnLbl - }) - ) warnings$ = new Subject<string[]>() @@ -108,7 +71,6 @@ export class FeatureViewComponent implements OnChanges { ngOnChanges(): void { this.voi$.next(null) - this.tabular$.next(null) this.busy$.next(true) this.#featureId.next(this.feature.id) @@ -117,9 +79,6 @@ export class FeatureViewComponent implements OnChanges { val => { this.busy$.next(false) - if (isTabularData(val)) { - this.tabular$.next(val) - } if (isVoiData(val)) { this.voi$.next(val) } diff --git a/src/features/guards.ts b/src/features/guards.ts index eff1ea272787e87cee62e2fc5e10305880ea9452..480e10dbe0b27f0d286919c31c21270402718a8b 100644 --- a/src/features/guards.ts +++ b/src/features/guards.ts @@ -1,8 +1,5 @@ -import { TabularFeature, VoiFeature } from "src/atlasComponents/sapi/sxplrTypes" +import { VoiFeature } from "src/atlasComponents/sapi/sxplrTypes" -export function isTabularData(feature: unknown): feature is TabularFeature<number|string|number[]> { - return !!feature['index'] && !!feature['columns'] -} export function isVoiData(feature: unknown): feature is VoiFeature { return !!feature['bbox'] diff --git a/src/features/module.ts b/src/features/module.ts index a7130309ec69c9523652bd02ab8e35caf21f3cf4..371e30d4a502d47bb36cd93bf33f1618a76ef332 100644 --- a/src/features/module.ts +++ b/src/features/module.ts @@ -18,7 +18,6 @@ import { MatDividerModule } from "@angular/material/divider"; import { MarkdownModule } from "src/components/markdown"; import { MatTableModule } from "@angular/material/table"; import { FeatureViewComponent } from "./feature-view/feature-view.component"; -import { TransformPdToDsPipe } from "./transform-pd-to-ds.pipe"; import { NgLayerCtlModule } from "src/viewerModule/nehuba/ngLayerCtlModule/module"; import { VoiBboxDirective } from "./voi-bbox.directive"; import { FilterCategoriesPipe } from "./filterCategories.pipe"; @@ -70,7 +69,6 @@ import { PlotlyComponent } from "./plotly"; VoiBboxDirective, FeatureNamePipe, - TransformPdToDsPipe, GroupFeaturesToName, GroupFeatureTallyPipe, ], diff --git a/src/features/transform-pd-to-ds.pipe.spec.ts b/src/features/transform-pd-to-ds.pipe.spec.ts deleted file mode 100644 index 66eb0d5f6e111a63b285e8d1dcf3460759468bcc..0000000000000000000000000000000000000000 --- a/src/features/transform-pd-to-ds.pipe.spec.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { TransformPdToDsPipe } from './transform-pd-to-ds.pipe'; - -describe('TransformPdToDsPipe', () => { - it('create an instance', () => { - const pipe = new TransformPdToDsPipe(); - expect(pipe).toBeTruthy(); - }); -}); diff --git a/src/features/transform-pd-to-ds.pipe.ts b/src/features/transform-pd-to-ds.pipe.ts deleted file mode 100644 index c0cc94e292ffa751b4f0d979e58d05ade128ce3e..0000000000000000000000000000000000000000 --- a/src/features/transform-pd-to-ds.pipe.ts +++ /dev/null @@ -1,39 +0,0 @@ -import { CdkTableDataSourceInput } from '@angular/cdk/table'; -import { Pipe, PipeTransform } from '@angular/core'; -import { TabularFeature } from 'src/atlasComponents/sapi/sxplrTypes'; - -function typeGuard(input: unknown): input is string | number | number[]{ - return typeof input === "string" || typeof input === "number" || (Array.isArray(input) && input.every(v => typeof v === "number")) -} - -function isString(input: unknown): input is string { - return typeof input === "string" -} - -@Pipe({ - name: 'transformPdToDs', - pure: true -}) -export class TransformPdToDsPipe implements PipeTransform { - - transform(pd: TabularFeature<string|number|number[]>): CdkTableDataSourceInput<unknown> { - return pd.data.map((arr, idx) => { - const val = pd.index[idx] - if (!typeGuard(val)) { - throw new Error(`Expected val to be of type string, number or number[], but was none.`) - } - const returnVal: Record<string, string|number|number[]> = { - index: val, - } - arr.forEach((val, colIdx) => { - const key = pd.columns[colIdx] - if (!isString(key)) { - throw new Error(`Expected key to be of type string, number or number[], but was not`) - } - returnVal[key] = val - }) - return returnVal - }) - } - -} diff --git a/src/index.html b/src/index.html index bc5fe61eac95bc91fc9ff8f1197bae4945ceebc9..2c80ba7b77d4e34a17eb758f82a940d311cb1f4a 100644 --- a/src/index.html +++ b/src/index.html @@ -13,7 +13,6 @@ <link rel="stylesheet" href="version.css"> <link rel="icon" type="image/png" href="assets/favicons/favicon-128-light.png"/> <script src="extra_js.js"></script> - <script src="https://unpkg.com/kg-dataset-previewer@1.2.0/dist/kg-dataset-previewer/kg-dataset-previewer.js" defer></script> <script src="https://unpkg.com/three-surfer@0.0.13/dist/bundle.js" defer></script> <script type="module" src="https://unpkg.com/ng-layer-tune@0.0.14/dist/ng-layer-tune/ng-layer-tune.esm.js"></script> <script type="module" src="https://unpkg.com/hbp-connectivity-component@0.6.6/dist/connectivity-component/connectivity-component.js" ></script> diff --git a/src/ui/dialogInfo/tmpl/tmpl.template.html b/src/ui/dialogInfo/tmpl/tmpl.template.html index e8f9cf07a5ca56b40788006118994f106f92691c..01b8d202663d5ff56c8f2902c35735b89ea3def8 100644 --- a/src/ui/dialogInfo/tmpl/tmpl.template.html +++ b/src/ui/dialogInfo/tmpl/tmpl.template.html @@ -23,7 +23,6 @@ </markdown-dom> </div> - <ng-template sxplrExperimentalFlag [experimental]="true" #actionExpmt="sxplrExperimentalFlag" [ngIf]="actionExpmt.show$ | async"> <ng-template [ngIf]="data.actionsAsList"> <mat-action-list> <ng-template ngFor [ngForOf]="data.actions" let-action let-first="first"> @@ -36,35 +35,11 @@ </ng-template> </mat-action-list> </ng-template> - </ng-template> </mat-dialog-content> <mat-dialog-actions align="start"> - <ng-template sxplrExperimentalFlag [deprecated]="true" #actionDep="sxplrExperimentalFlag" [ngIf]="actionDep.show$ | async"> - <ng-template ngFor [ngForOf]="data.actions || []" let-action> - <a *ngIf="action.startsWith('http'); else defaultActionTmpl" - [href]="action" - sxplr-hide-when-local - target="_blank" - mat-raised-button - color="primary"> - <i class="fas fa-external-link-alt"></i> - <span>Detail</span> - </a> - - <ng-template #defaultActionTmpl> - <button mat-raised-button - color="primary" - [mat-dialog-close]="action"> - {{ action }} - </button> - </ng-template> - </ng-template> - </ng-template> - - <ng-template sxplrExperimentalFlag [experimental]="true" #actionDefaultExpmt="sxplrExperimentalFlag" [ngIf]="actionDefaultExpmt.show$ | async"> <ng-template [ngIf]="!data.actionsAsList"> <ng-template ngFor [ngForOf]="data.actions || []" let-action> <a *ngIf="action.startsWith('http'); else defaultActionTmpl" @@ -86,7 +61,6 @@ </ng-template> </ng-template> </ng-template> - </ng-template> <button mat-dialog-close mat-button> Close diff --git a/src/viewerModule/nehuba/nehubaViewer/nehubaViewer.component.ts b/src/viewerModule/nehuba/nehubaViewer/nehubaViewer.component.ts index 017187edb71c29fc59bc0dd589790a6dc3bb4e02..12009026cedae24d1a35cd2e5d1998a4b00749a2 100644 --- a/src/viewerModule/nehuba/nehubaViewer/nehubaViewer.component.ts +++ b/src/viewerModule/nehuba/nehubaViewer/nehubaViewer.component.ts @@ -505,7 +505,6 @@ export class NehubaViewerUnit implements OnDestroy { ...rest, ...(transform ? { transform } : {}) } - console.log(combined) viewer.layerManager.addManagedLayer( viewer.layerSpecification.getLayer(key, combined)) diff --git a/src/viewerModule/nehuba/ngLayerCtlModule/ngLayerCtl/ngLayerCtrl.component.ts b/src/viewerModule/nehuba/ngLayerCtlModule/ngLayerCtl/ngLayerCtrl.component.ts index 0b553f586b42b8b91a2624448a499df2c3e57680..c1bf962bdd845888ecdd3512a4c454d02b046482 100644 --- a/src/viewerModule/nehuba/ngLayerCtlModule/ngLayerCtl/ngLayerCtrl.component.ts +++ b/src/viewerModule/nehuba/ngLayerCtlModule/ngLayerCtl/ngLayerCtrl.component.ts @@ -6,6 +6,8 @@ import { Observable } from "rxjs"; import { atlasAppearance, atlasSelection } from "src/state"; import { NehubaViewerUnit, NEHUBA_INSTANCE_INJTKN } from "src/viewerModule/nehuba"; import { getExportNehuba } from "src/util/fn"; +import { getShader } from "src/util/constants"; +import { EnumColorMapName } from "src/util/colorMaps"; type Vec4 = [number, number, number, number] type Mat4 = [Vec4, Vec4, Vec4, Vec4] @@ -33,7 +35,7 @@ export class NgLayerCtrlCmp implements OnChanges, OnDestroy{ private onDestroyCb: (() => void)[] = [] private removeLayer: () => void - public hideNgTuneCtrl = 'lower_threshold,higher_threshold,brightness,contrast,colormap,hide-threshold-checkbox' + public hideNgTuneCtrl = '' public defaultOpacity = 1 @Input('ng-layer-ctrl-show') @@ -109,6 +111,7 @@ export class NgLayerCtrlCmp implements OnChanges, OnDestroy{ this.removeLayer() this.removeLayer = null } + console.log('foo', this.source) this.store.dispatch( atlasAppearance.actions.addCustomLayer({ customLayer: { diff --git a/src/viewerModule/threeSurfer/threeSurferGlue/threeSurfer.template.html b/src/viewerModule/threeSurfer/threeSurferGlue/threeSurfer.template.html index 7d319699166f995afbc215f2663188182aaff083..5b20603db318118e79511337f3ba4acc4ecd142b 100644 --- a/src/viewerModule/threeSurfer/threeSurferGlue/threeSurfer.template.html +++ b/src/viewerModule/threeSurfer/threeSurferGlue/threeSurfer.template.html @@ -5,9 +5,6 @@ <div class="button-container"> - <ng-template sxplrExperimentalFlag [ngIf]="exmptToggleGrid.show$ | async" - #exmptToggleGrid="sxplrExperimentalFlag" - [experimental]="true"> <!-- toggle grid line --> <ng-template [ngTemplateOutlet]="toggleGridVisTmpl" [ngTemplateOutletContext]="{ $implicit: gridVisible$ | async @@ -25,8 +22,6 @@ </button> </ng-template> - </ng-template> - <!-- selector & configurator --> <button mat-icon-button color="primary" diff --git a/src/viewerModule/viewerCmp/viewerCmp.template.html b/src/viewerModule/viewerCmp/viewerCmp.template.html index e7f25001cd06b42c83c70d0c121de780de7b2623..d213273186d4ad7fd5594dd228188efd770e7c07 100644 --- a/src/viewerModule/viewerCmp/viewerCmp.template.html +++ b/src/viewerModule/viewerCmp/viewerCmp.template.html @@ -288,50 +288,46 @@ </div> <!-- tab to minimize mini tray --> - <ng-template sxplrExperimentalFlag - [experimental]="true" - #minTray="sxplrExperimentalFlag" - [ngIf]="minTray.show$ | async"> - <div class="tab-toggle-container"> + + <div class="tab-toggle-container"> + + <div [ngClass]="(minTrayVisSwitch.switchState$ | async) ? '' : 'd-none'"> + + <ng-template [ngTemplateOutlet]="tabTmpl_defaultTmpl" [ngTemplateOutletContext]="{ + fontIcon: 'fas fa-chevron-left', + matColor: null, + click: minTrayVisSwitch.toggle.bind(minTrayVisSwitch) + }"> + </ng-template> + </div> - <div [ngClass]="(minTrayVisSwitch.switchState$ | async) ? '' : 'd-none'"> + <div [ngClass]="(minTrayVisSwitch.switchState$ | async) ? 'd-none' : ''"> + + <ng-template [ngIf]="voiFeatureEntryCmp && (voiFeatureEntryCmp.totals$ | async)" + [ngIfElse]="noBadgeTmpl" + let-totals> <ng-template [ngTemplateOutlet]="tabTmpl_defaultTmpl" [ngTemplateOutletContext]="{ - fontIcon: 'fas fa-chevron-left', - matColor: null, - click: minTrayVisSwitch.toggle.bind(minTrayVisSwitch) + fontIcon: 'fas fa-search', + matColor: 'primary', + click: minTrayVisSwitch.toggle.bind(minTrayVisSwitch), + badge: totals }"> </ng-template> - </div> - - <div [ngClass]="(minTrayVisSwitch.switchState$ | async) ? 'd-none' : ''"> - - <ng-template [ngIf]="voiFeatureEntryCmp && (voiFeatureEntryCmp.totals$ | async)" - [ngIfElse]="noBadgeTmpl" - let-totals> - - <ng-template [ngTemplateOutlet]="tabTmpl_defaultTmpl" [ngTemplateOutletContext]="{ - fontIcon: 'fas fa-search', - matColor: 'primary', - click: minTrayVisSwitch.toggle.bind(minTrayVisSwitch), - badge: totals - }"> - </ng-template> - </ng-template> + </ng-template> - <ng-template #noBadgeTmpl> + <ng-template #noBadgeTmpl> - <ng-template [ngTemplateOutlet]="tabTmpl_defaultTmpl" [ngTemplateOutletContext]="{ - fontIcon: 'fas fa-search', - matColor: 'primary', - click: minTrayVisSwitch.toggle.bind(minTrayVisSwitch) - }"> - </ng-template> + <ng-template [ngTemplateOutlet]="tabTmpl_defaultTmpl" [ngTemplateOutletContext]="{ + fontIcon: 'fas fa-search', + matColor: 'primary', + click: minTrayVisSwitch.toggle.bind(minTrayVisSwitch) + }"> </ng-template> - </div> - + </ng-template> </div> - </ng-template> + + </div> </ng-template> @@ -466,87 +462,7 @@ sxplr-of-y-hidden sxplr-align-items-stretch"> - <ng-template sxplrExperimentalFlag - #expmt="sxplrExperimentalFlag" - [experimental]="true" - [ngIf]="expmt.show$ | async"> - <sxplr-bottom-menu (onRegionClick)="showFullSideNav()"></sxplr-bottom-menu> - </ng-template> - - <ng-template sxplrExperimentalFlag - #deprec="sxplrExperimentalFlag" - [deprecated]="true" - [ngIf]="deprec.show$ | async"> - - <sxplr-wrapper-atp-selector class="sxplr-z-2"> - </sxplr-wrapper-atp-selector> - - <!-- selected region chip --> - <ng-template [ngIf]="view.selectedRegions" let-regions> - - <!-- single region --> - <ng-template [ngIf]="regions.length === 1"> - <sxplr-smart-chip - *ngFor="let region of regions" - [noMenu]="true" - [color]="sapiViewsCoreRegion.regionRgbString" - (click)="showFullSideNav()" - sxplr-sapiviews-core-region - [sxplr-sapiviews-core-region-atlas]="selectedAtlas$ | async" - [sxplr-sapiviews-core-region-template]="view.selectedTemplate" - [sxplr-sapiviews-core-region-parcellation]="view.selectedParcellation" - [sxplr-sapiviews-core-region-region]="region" - [sxplr-sapiviews-core-region-detail-flag]="true" - #sapiViewsCoreRegion="sapiViewsCoreRegion"> - - <ng-template sxplrSmartChipHeader> - <span class="regionname"> - Region - </span> - </ng-template> - - <ng-template sxplrSmartChipContent> - <span class="regionname"> - {{ region.name }} - </span> - <button class="sxplr-mr-n3" - mat-icon-button - (click)="clearRoi()"> - <i class="fas fa-times"></i> - </button> - </ng-template> - </sxplr-smart-chip> - </ng-template> - - - <!-- multiple-regions --> - <ng-template [ngIf]="regions.length > 1"> - <sxplr-smart-chip - [noMenu]="true" - - (click)="showFullSideNav()" - sxplr-sapiviews-core-region - [sxplr-sapiviews-core-region-atlas]="selectedAtlas$ | async" - [sxplr-sapiviews-core-region-template]="view.selectedTemplate" - [sxplr-sapiviews-core-region-parcellation]="view.selectedParcellation"> - <ng-template sxplrSmartChipContent> - <span class="regionname"> - {{ regions.length }} regions selected - </span> - <button class="sxplr-mr-n3" - mat-icon-button - (click)="clearRoi()"> - <i class="fas fa-times"></i> - </button> - </ng-template> - </sxplr-smart-chip> - - </ng-template> - - </ng-template> - - </ng-template> </div> @@ -970,11 +886,6 @@ </mat-card> </ng-template> -<ng-template - sxplrExperimentalFlag - [experimental]="true" - #lastSelPtExpmt="sxplrExperimentalFlag" - [ngIf]="lastSelPtExpmt.show$ | async"> <ng-template #lastViewedPointTmpl let-data> <div class="text-muted sxplr-m-2"> Last selected spatial object @@ -1028,8 +939,6 @@ <!-- {{ data.point | json }} --> </button> </ng-template> -</ng-template> - <!-- viewer status ctx menu --> <ng-template #viewerStatusCtxMenu let-data> @@ -1068,7 +977,8 @@ <ng-template [ngIf]="context.payload?.faceIndex" let-faceIndex> <ng-template [ngIf]="context.payload?.vertexIndices" let-vertexIndices> <button mat-button class="sxplr-list-like-button" - (click)="selectPoint({ face: faceIndex, vertices: vertexIndices }, data.metadata.template)"> + (click)="selectPoint({ face: faceIndex, vertices: vertexIndices }, data.metadata.template)" + disabled> <div class="sxplr-list-like-button-icon"> <i class="fas fa-map"></i> @@ -1085,6 +995,9 @@ <span class="sxplr-list-like-button-body-line text-muted"> {{ data.metadata.template.name }} </span> + <i class="sxplr-list-like-button-body-line text-muted"> + (Not selectable at the moment) + </i> </div> </button>