diff --git a/backend/app/index_html.py b/backend/app/index_html.py index 504ec7bb1300c221a2d44753a619f48fc6f5c3f2..c054d76ca6c23eae8c06446d5d009c05c2e526f6 100644 --- a/backend/app/index_html.py +++ b/backend/app/index_html.py @@ -26,7 +26,7 @@ async def get_index_html(request: Request): error = None attributes_to_append: Dict[str, str] = {} if ERROR_KEY in request.session: - error = request.session[ERROR_KEY] + error = request.session.pop(ERROR_KEY) attributes_to_append[DATA_ERROR_ATTR] = error if OVERWRITE_API_ENDPOINT: @@ -38,7 +38,7 @@ async def get_index_html(request: Request): if EXPERIMENTAL_FLAG: attributes_to_append[OVERWRITE_EXPERIMENTAL_FLAG_ATTR] = EXPERIMENTAL_FLAG - attr_string = " ".join([f"{key}={_monkey_sanitize(value)}" for key, value in attributes_to_append.items()]) + attr_string = " ".join([f'{key}="{_monkey_sanitize(value)}"' for key, value in attributes_to_append.items()]) resp_string = index_html.replace("<atlas-viewer>", f"<atlas-viewer {attr_string}>") diff --git a/backend/app/sane_url.py b/backend/app/sane_url.py index e65c1982c355af6d836593be71a274b553e54eea..8a68cf8847d1e12e0c281767212da85e577f3a19 100644 --- a/backend/app/sane_url.py +++ b/backend/app/sane_url.py @@ -10,7 +10,7 @@ from io import StringIO from pydantic import BaseModel from .config import SXPLR_EBRAINS_IAM_SA_CLIENT_ID, SXPLR_EBRAINS_IAM_SA_CLIENT_SECRET, SXPLR_BUCKET_NAME, HOST_PATHNAME -from .const import EBRAINS_IAM_DISCOVERY_URL +from .const import EBRAINS_IAM_DISCOVERY_URL, ERROR_KEY from ._store import DataproxyStore from .user import get_user_from_request @@ -135,10 +135,11 @@ data_proxy_store = SaneUrlDPStore() @router.get("/{short_id:str}") async def get_short(short_id:str, request: Request): + accept = request.headers.get("Accept", "") + is_browser = "text/html" in accept try: existing_json: Dict[str, Any] = data_proxy_store.get(short_id) - accept = request.headers.get("Accept", "") - if "text/html" in accept: + if is_browser: hashed_path = existing_json.get("hashPath") extra_routes = [] for key in existing_json: @@ -151,8 +152,14 @@ async def get_short(short_id:str, request: Request): return RedirectResponse(f"{HOST_PATHNAME}/#{hashed_path}{extra_routes_str}") return JSONResponse(existing_json) except DataproxyStore.NotFound as e: + if is_browser: + request.session[ERROR_KEY] = f"Short ID {short_id} not found." + return RedirectResponse(HOST_PATHNAME or "/") raise HTTPException(404, str(e)) except DataproxyStore.GenericException as e: + if is_browser: + request.session[ERROR_KEY] = f"Error: {str(e)}" + return RedirectResponse(HOST_PATHNAME or "/") raise HTTPException(500, str(e)) diff --git a/docs/releases/v2.14.5.md b/docs/releases/v2.14.5.md index 895c81d443cc0fd6106c42dee6ac1d7ae2da13ff..634e1029640bbf2888e736988f7db82f3e7ba995 100644 --- a/docs/releases/v2.14.5.md +++ b/docs/releases/v2.14.5.md @@ -10,14 +10,17 @@ - Added legend to region hierarchy - Allow experimental flag to be set to be on at runtime (this also shows the button, allow toggling of experimental features) - (experimental) allow addition of custom linear coordinate space +- (experimental) show BigBrain slice number ## Bugfix - Copy of free text (Ctrl + C) now works properly +- Fixes issue where annotation mode was not displaying correctly, after selecting volume of interest +- When saneURL is not found, siibra-explorer will not correctly redirects to default app, and show the error message ## Behind the Scenes - Removed dependency on connectivity-component - Removed reference to JSC OKD instance, as the instance is no longer available - Updated google-site-verification -- Allow inter space transform to be configured at runtime +- Allow inter-space transform to be configured at runtime diff --git a/src/atlasComponents/annotations/annotation.service.ts b/src/atlasComponents/annotations/annotation.service.ts index d8242e62f15ccb006a0447a18c3a578348d0971f..a7590df026c82aac0867c911e77f5570bd37f12a 100644 --- a/src/atlasComponents/annotations/annotation.service.ts +++ b/src/atlasComponents/annotations/annotation.service.ts @@ -82,7 +82,10 @@ export class AnnotationLayer { distinctUntilChanged((o, n) => o?.id === n?.id) ) private onDestroyCb: (() => void)[] = [] - private nglayer: NgAnnotationLayer + + get nglayer(): NgAnnotationLayer{ + return this.viewer.layerManager.getLayerByName(this.name) + } private idset = new Set<string>() constructor( private name: string = getUuid(), @@ -99,7 +102,7 @@ export class AnnotationLayer { transform: affine, } ) - this.nglayer = this.viewer.layerManager.addManagedLayer(layerSpec) + this.viewer.layerManager.addManagedLayer(layerSpec) const mouseState = this.viewer.mouseState const res: () => void = mouseState.changed.add(() => { const payload = mouseState.active @@ -131,7 +134,6 @@ export class AnnotationLayer { try { const l = this.viewer.layerManager.getLayerByName(this.name) this.viewer.layerManager.removeManagedLayer(l) - this.nglayer = null // eslint-disable-next-line no-empty } catch (e) { console.error("removing layer failed", e) diff --git a/src/components/coordTextBox/index.ts b/src/components/coordTextBox/index.ts index fe8e63ce12dec965848966a2e5ca41dd810fb49f..a157bc32eda85d905ba713c48cb1666cede82cb5 100644 --- a/src/components/coordTextBox/index.ts +++ b/src/components/coordTextBox/index.ts @@ -1 +1,10 @@ +import { TAffine } from "./coordTextBox.component" + export * from "./coordTextBox.component" + +export const ID_AFFINE = [ + [1, 0, 0, 0], + [0, 1, 0, 0], + [0, 0, 1, 0], + [0, 0, 0, 1], +] as TAffine diff --git a/src/sharedModules/angularMaterial.exports.ts b/src/sharedModules/angularMaterial.exports.ts index 09611d70f3f6c8afdcacd927a0cbe3be40339fae..4c83edd6418f9fcbcb909b083664f654292e3a49 100644 --- a/src/sharedModules/angularMaterial.exports.ts +++ b/src/sharedModules/angularMaterial.exports.ts @@ -1,3 +1,4 @@ +export { MatTab, MatTabGroup } from "@angular/material/tabs"; export { ErrorStateMatcher } from "@angular/material/core"; export { MatDialogConfig, MatDialog, MatDialogRef } from "@angular/material/dialog"; export { MatSnackBar, MatSnackBarRef, SimpleSnackBar, MatSnackBarConfig } from "@angular/material/snack-bar"; @@ -12,5 +13,4 @@ export { MatTreeFlatDataSource, MatTreeFlattener } from "@angular/material/tree" export { MatAutocompleteSelectedEvent } from "@angular/material/autocomplete"; export { MatPaginator } from "@angular/material/paginator"; export { MatInput } from "@angular/material/input"; - export { MatSlideToggleHarness } from '@angular/material/slide-toggle/testing' diff --git a/src/ui/bottomMenu/bottomMenuCmp/bottomMenu.template.html b/src/ui/bottomMenu/bottomMenuCmp/bottomMenu.template.html index f0e7a78b0748d74afc54d2abce7e40ce921f6b58..3703c36339245818f11e9fa7efff1a535d86d224 100644 --- a/src/ui/bottomMenu/bottomMenuCmp/bottomMenu.template.html +++ b/src/ui/bottomMenu/bottomMenuCmp/bottomMenu.template.html @@ -1,5 +1,3 @@ -<ng-template #deprec> - <sxplr-wrapper-atp-selector (sxplr-wrapper-atp-selector-menu-open)="onATPMenuOpen($event)" class="sxplr-z-2"> </sxplr-wrapper-atp-selector> @@ -83,49 +81,3 @@ </ng-template> </ng-template> - -</ng-template> - - -<ng-template #expmttmpl> - -<ng-template [ngIf]="view$ | async" let-view> - <ng-template [ngIf]="view.selectedFeature" [ngIfElse]="deprec" let-feature> - <sxplr-smart-chip - mat-ripple - [noMenu]="true" - (click)="onRegionClick.emit()"> - - <ng-template sxplrSmartChipHeader> - <span> - Feature - </span> - </ng-template> - - <ng-template sxplrSmartChipContent> - <span> - {{ feature.name }} - </span> - </ng-template> - - <ng-template sxplrSmartChipAction> - <button class="sxplr-mr-n3" - mat-icon-button - (click)="clearFeature()"> - <i class="fas fa-times"></i> - </button> - </ng-template> - </sxplr-smart-chip> - - </ng-template> -</ng-template> -</ng-template> - - -<ng-template sxplrExperimentalFlag [experimental]="true"> -<ng-template [ngTemplateOutlet]="expmttmpl"></ng-template> -</ng-template> - -<ng-template sxplrExperimentalFlag [deprecated]="true"> -<ng-template [ngTemplateOutlet]="deprec"></ng-template> -</ng-template> diff --git a/src/util/directives/floatingMouseContextualContainer.directive.ts b/src/util/directives/floatingMouseContextualContainer.directive.ts index d924d7133e90299e137469a9b49b512695424271..2c2f0def8de300178264589e6abcd96ad5f239c5 100644 --- a/src/util/directives/floatingMouseContextualContainer.directive.ts +++ b/src/util/directives/floatingMouseContextualContainer.directive.ts @@ -3,6 +3,7 @@ import { DomSanitizer, SafeUrl } from "@angular/platform-browser"; @Directive({ selector: '[floatingMouseContextualContainerDirective]', + standalone: true, }) export class FloatingMouseContextualContainerDirective { diff --git a/src/util/directives/mediaQuery.directive.ts b/src/util/directives/mediaQuery.directive.ts index 08d77130d030ccb4bd08347e5f53a8dd527e42d9..68fa61fd2a8c7fa1f8ad62c2e01d99bdff366145 100644 --- a/src/util/directives/mediaQuery.directive.ts +++ b/src/util/directives/mediaQuery.directive.ts @@ -24,7 +24,8 @@ enum EnumMediaBreakPoints{ @Directive({ selector: '[iav-media-query]', - exportAs: 'iavMediaQuery' + exportAs: 'iavMediaQuery', + standalone: true }) export class MediaQueryDirective{ diff --git a/src/util/util.module.ts b/src/util/util.module.ts index f2b7ccc2185b5f29ce80f2d397b08ab9cebed43e..210445361910ba4eea83a0a5b9d4fcc8dfaaa79f 100644 --- a/src/util/util.module.ts +++ b/src/util/util.module.ts @@ -5,7 +5,6 @@ import { SafeResourcePipe } from "./pipes/safeResource.pipe"; import { CaptureClickListenerDirective } from "./directives/captureClickListener.directive"; import { NmToMm } from "./pipes/nmToMm.pipe"; import { SwitchDirective } from "./directives/switch.directive"; -import { MediaQueryDirective } from './directives/mediaQuery.directive' import { LayoutModule } from "@angular/cdk/layout"; import { MapToPropertyPipe } from "./pipes/mapToProperty.pipe"; import { ClickOutsideDirective } from "src/util/directives/clickOutside.directive"; @@ -38,7 +37,6 @@ import { PrettyPresentPipe } from './pretty-present.pipe'; CaptureClickListenerDirective, NmToMm, SwitchDirective, - MediaQueryDirective, MapToPropertyPipe, ClickOutsideDirective, GetNthElementPipe, @@ -62,7 +60,6 @@ import { PrettyPresentPipe } from './pretty-present.pipe'; CaptureClickListenerDirective, NmToMm, SwitchDirective, - MediaQueryDirective, MapToPropertyPipe, ClickOutsideDirective, GetNthElementPipe, diff --git a/src/viewerModule/module.ts b/src/viewerModule/module.ts index 2ecdfdf8b203769783b1f47623f60f3c3244ee45..0d2d8192545d269615b02e654782c9415abbc5b0 100644 --- a/src/viewerModule/module.ts +++ b/src/viewerModule/module.ts @@ -42,6 +42,7 @@ import { TabComponent } from "src/components/tab/tab.components"; import { ExperimentalFlagDirective } from "src/experimental/experimental-flag.directive"; import { HOVER_INTERCEPTOR_INJECTOR } from "src/util/injectionTokens"; import { ViewerWrapper } from "./viewerWrapper/viewerWrapper.component"; +import { MediaQueryDirective } from "src/util/directives/mediaQuery.directive"; @NgModule({ imports: [ @@ -71,6 +72,8 @@ import { ViewerWrapper } from "./viewerWrapper/viewerWrapper.component"; TabComponent, MouseOver, + MediaQueryDirective, + FloatingMouseContextualContainerDirective, ExperimentalFlagDirective, ...(environment.ENABLE_LEAP_MOTION ? [LeapModule] : []) @@ -79,7 +82,6 @@ import { ViewerWrapper } from "./viewerWrapper/viewerWrapper.component"; ViewerCmp, NehubaVCtxToBbox, LogoContainer, - FloatingMouseContextualContainerDirective, ViewerWrapper, ], providers: [ diff --git a/src/viewerModule/nehuba/module.ts b/src/viewerModule/nehuba/module.ts index d6fb5813fc69c786158e2ac560541bd206ceb0a1..76b1be3db1e3a5046702286313b63e6e6ebe3edc 100644 --- a/src/viewerModule/nehuba/module.ts +++ b/src/viewerModule/nehuba/module.ts @@ -30,6 +30,7 @@ import { NehubaUserLayerModule } from "./userLayers"; import { DialogModule } from "src/ui/dialogInfo"; import { CoordTextBox } from "src/components/coordTextBox"; import { ExperimentalFlagDirective } from "src/experimental/experimental-flag.directive"; +import { MediaQueryDirective } from "src/util/directives/mediaQuery.directive"; @NgModule({ imports: [ @@ -42,6 +43,7 @@ import { ExperimentalFlagDirective } from "src/experimental/experimental-flag.di ShareModule, WindowResizeModule, NehubaUserLayerModule, + MediaQueryDirective, /** * should probably break this into its own... diff --git a/src/viewerModule/nehuba/statusCard/statusCard.component.spec.ts b/src/viewerModule/nehuba/statusCard/statusCard.component.spec.ts index df15daa10962bb9b2a739d65da5535bd6c8ab8fd..d582da672cc85279753633b6e187b6ca9692fecb 100644 --- a/src/viewerModule/nehuba/statusCard/statusCard.component.spec.ts +++ b/src/viewerModule/nehuba/statusCard/statusCard.component.spec.ts @@ -15,6 +15,7 @@ import { QuickTourModule } from "src/ui/quickTour/module"; import { atlasSelection } from "src/state" import { SxplrTemplate } from "src/atlasComponents/sapi/sxplrTypes" import { NEHUBA_INSTANCE_INJTKN } from "../util" +import { MediaQueryDirective } from "src/util/directives/mediaQuery.directive" const mockNehubaConfig = { dataset: { @@ -60,7 +61,8 @@ describe('> statusCard.component.ts', () => { ReactiveFormsModule, NoopAnimationsModule, UtilModule, - QuickTourModule + QuickTourModule, + MediaQueryDirective, ], declarations: [ StatusCardComponent, diff --git a/src/viewerModule/nehuba/statusCard/statusCard.component.ts b/src/viewerModule/nehuba/statusCard/statusCard.component.ts index 7dc07eb9a27de9fc9f78a6814becbad955449716..2f14e22015fcb803cbc06c168dbfcae5eae4540b 100644 --- a/src/viewerModule/nehuba/statusCard/statusCard.component.ts +++ b/src/viewerModule/nehuba/statusCard/statusCard.component.ts @@ -8,7 +8,7 @@ import { import { select, Store } from "@ngrx/store"; import { LoggingService } from "src/logging"; import { NehubaViewerUnit } from "../nehubaViewer/nehubaViewer.component"; -import { Observable, Subject, concat, of } from "rxjs"; +import { Observable, Subject, combineLatest, concat, of } from "rxjs"; import { map, filter, takeUntil, switchMap, shareReplay, debounceTime, scan } from "rxjs/operators"; import { Clipboard, MatBottomSheet, MatSnackBar } from "src/sharedModules/angularMaterial.exports" import { ARIA_LABELS, QUICKTOUR_DESC } from 'common/constants' @@ -22,11 +22,13 @@ import { SxplrTemplate } from "src/atlasComponents/sapi/sxplrTypes"; import { NEHUBA_CONFIG_SERVICE_TOKEN, NehubaConfigSvc } from "../config.service"; import { DestroyDirective } from "src/util/directives/destroy.directive"; import { getUuid } from "src/util/fn"; -import { Render, TAffine, isAffine } from "src/components/coordTextBox" +import { Render, TAffine, isAffine, ID_AFFINE } from "src/components/coordTextBox" +import { IDS } from "src/atlasComponents/sapi"; type TSpace = { label: string affine: TAffine + render?: Render } @Component({ @@ -40,8 +42,29 @@ type TSpace = { export class StatusCardComponent { #newSpace = new Subject<TSpace>() - additionalSpace$ = this.#newSpace.pipe( - scan((acc, v) => acc.concat(v), [] as TSpace[]) + additionalSpace$ = combineLatest([ + this.store$.pipe( + select(atlasSelection.selectors.selectedTemplate), + map(tmpl => { + if (tmpl.id === IDS.TEMPLATES.BIG_BRAIN) { + const tspace: TSpace = { + affine: ID_AFFINE, + label: "BigBrain slice index", + render: v => `Slice ${Math.ceil((v[1] + 70.010) / 0.02)}` + } + return [tspace] + } + return [] + }) + ), + concat( + of([] as TSpace[]), + this.#newSpace.pipe( + scan((acc, v) => acc.concat(v), [] as TSpace[]), + ) + ) + ]).pipe( + map(([predefined, custom]) => [...predefined, ...custom]) ) readonly idAffStr = `[ [1, 0, 0, 0], diff --git a/src/viewerModule/nehuba/statusCard/statusCard.template.html b/src/viewerModule/nehuba/statusCard/statusCard.template.html index 2b17c8e751bf2220ca576e772f96eaea3a9114ea..f3226b50c6573e27c7d75dbb619065ca5a5200e8 100644 --- a/src/viewerModule/nehuba/statusCard/statusCard.template.html +++ b/src/viewerModule/nehuba/statusCard/statusCard.template.html @@ -72,13 +72,15 @@ </coordinate-text-input> </div> + <ng-template sxplrExperimentalFlag [experimental]="true"> <!-- custom coord --> <div class="d-flex" *ngFor="let f of additionalSpace$ | async"> <coordinate-text-input - [coordinates]="navigation$ | async" + *ngIf="navigation$ | async as navigation" + [coordinates]="navigation" [affine]="f.affine" [label]="f.label" - [render]="renderDefault" + [render]="f.render || renderDefault" #customInput> <ng-container ngProjectAs="[suffix]"> @@ -91,6 +93,7 @@ </ng-container> </coordinate-text-input> </div> + </ng-template> <ng-template sxplrExperimentalFlag [experimental]="true"> <button mat-button diff --git a/src/viewerModule/nehuba/userLayers/userlayerInfo/userlayerInfo.component.ts b/src/viewerModule/nehuba/userLayers/userlayerInfo/userlayerInfo.component.ts index e44b5b4d0d737ba05602c20f8b8c6b5532587a88..2df5d159377044c8fd32dbeecc86885c38cdd6c3 100644 --- a/src/viewerModule/nehuba/userLayers/userlayerInfo/userlayerInfo.component.ts +++ b/src/viewerModule/nehuba/userLayers/userlayerInfo/userlayerInfo.component.ts @@ -1,8 +1,8 @@ -import { Component, Inject, ViewChild } from "@angular/core"; +import { Component, Inject, inject } from "@angular/core"; import { MAT_DIALOG_DATA } from "src/sharedModules/angularMaterial.exports" import { ARIA_LABELS, CONST } from 'common/constants' -import { BehaviorSubject, Subject, combineLatest, concat, of, timer } from "rxjs"; -import { map, switchMap, take } from "rxjs/operators"; +import { BehaviorSubject, combineLatest, concat, of, timer } from "rxjs"; +import { map, take } from "rxjs/operators"; import { MediaQueryDirective } from "src/util/directives/mediaQuery.directive"; export type UserLayerInfoData = { @@ -16,23 +16,22 @@ export type UserLayerInfoData = { templateUrl: './userlayerInfo.template.html', styleUrls: [ './userlayerInfo.style.css' + ], + hostDirectives: [ + MediaQueryDirective ] }) export class UserLayerInfoCmp { + + private readonly mediaQuery = inject(MediaQueryDirective) + ARIA_LABELS = ARIA_LABELS CONST = CONST public HIDE_NG_TUNE_CTRL = { ONLY_SHOW_OPACITY: 'export-mode,lower_threshold,higher_threshold,brightness,contrast,colormap,hide-threshold-checkbox,hide-zero-value-checkbox' } - #mediaQuery = new Subject<MediaQueryDirective>() - - @ViewChild(MediaQueryDirective, { read: MediaQueryDirective }) - set mediaQuery(val: MediaQueryDirective) { - this.#mediaQuery.next(val) - } - constructor( @Inject(MAT_DIALOG_DATA) public data: UserLayerInfoData ){ @@ -50,13 +49,9 @@ export class UserLayerInfoCmp { this.#showMore, concat( of(null as MediaQueryDirective), - this.#mediaQuery, - ).pipe( - switchMap(mediaQueryD => mediaQueryD - ? mediaQueryD.mediaBreakPoint$.pipe( - map(val => val >= 2) - ) - : of(false)) + this.mediaQuery.mediaBreakPoint$.pipe( + map(val => val >= 2) + ), ) ]).pipe( map(([ showMore, compact ]) => ({ diff --git a/src/viewerModule/nehuba/userLayers/userlayerInfo/userlayerInfo.template.html b/src/viewerModule/nehuba/userLayers/userlayerInfo/userlayerInfo.template.html index dfd465617e0aaa243293f289028362d66f7f6c65..7963b83432609094ff322a690162bbc3c1e58c39 100644 --- a/src/viewerModule/nehuba/userLayers/userlayerInfo/userlayerInfo.template.html +++ b/src/viewerModule/nehuba/userLayers/userlayerInfo/userlayerInfo.template.html @@ -1,6 +1,3 @@ -<!-- TODO replace with hostdirective after upgrading to angular 15 --> -<div iav-media-query></div> - <ng-template [ngIf]="view$ | async" [ngIfElse]="spinnerTmpl" let-view> <div class="grid grid-col-4 sxplr-custom-cmp text"> diff --git a/src/viewerModule/viewerCmp/viewerCmp.template.html b/src/viewerModule/viewerCmp/viewerCmp.template.html index 4e15b6b1c9644acb5357bc8ad01376bab9e6e144..dea9c8548f2613e3661c87bda264b8e297598281 100644 --- a/src/viewerModule/viewerCmp/viewerCmp.template.html +++ b/src/viewerModule/viewerCmp/viewerCmp.template.html @@ -10,11 +10,13 @@ </div> </ng-template> - - <div *ngIf="(media.mediaBreakPoint$ | async) < 2" - floatingMouseContextualContainerDirective> - <mouseover-info class="contextual-block"></mouseover-info> - </div> + <ng-template [ngIf]="(media.mediaBreakPoint$ | async) < 2"> + <div floatingMouseContextualContainerDirective> + <mouseover-info + class="contextual-block"> + </mouseover-info> + </div> + </ng-template> </div> </div> @@ -504,12 +506,10 @@ <!-- region search autocomplete --> <!-- [@openCloseAnchor]="sideNavFullLeftSwitch.switchState ? 'open' : 'closed'" --> - <ng-template sxplrExperimentalFlag [deprecated]="true"> <div class="h-0 w-100 region-text-search-autocomplete-position"> <ng-container *ngTemplateOutlet="autocompleteTmpl"> </ng-container> </div> - </ng-template> <div class="flex-shrink-1 flex-grow-1 d-flex flex-column sxplr-h-100" [ngClass]="{'region-populated': (view.selectedRegions || []).length > 0 }"> @@ -537,17 +537,7 @@ <ng-container ngProjectAs="[header]"> - - <ng-template sxplrExperimentalFlag [deprecated]="true"> - <div class="sapi-container"></div> - </ng-template> - - <ng-template sxplrExperimentalFlag [experimental]="true"> - <button mat-button (click)="clearRoi()"> - <i class="fas fa-times"></i> - <span>Dismiss</span> - </button> - </ng-template> + <div class="sapi-container"></div> </ng-container> </sxplr-sapiviews-core-region-region-rich> @@ -588,17 +578,6 @@ </ng-template> -<!-- expansion tmpl --> -<ng-template #ngMatAccordionTmpl - let-title="title" - let-desc="desc" - let-iconClass="iconClass" - let-iconTooltip="iconTooltip" - let-iavNgIf="iavNgIf" - let-content="content"> -</ng-template> - - <!-- multi region tmpl --> <ng-template #multiRegionTmpl let-regions="regions"> <ng-template [ngIf]="regions.length > 0" [ngIfElse]="regionPlaceholderTmpl">