From 7232eb0b54d4fab60bd351b12deb6b5415073337 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Agneray?= <francois.agneray@lam.fr> Date: Tue, 20 Jul 2021 11:39:06 +0200 Subject: [PATCH] Datatable => done --- client/package.json | 1 + .../result/datatable-tab.component.html | 25 ++++++++ .../result/datatable-tab.component.ts | 46 +++++++++++++ .../search/components/result/index.ts | 2 + .../containers/abstract-search.component.ts | 2 +- .../search/containers/result.component.html | 12 ++-- .../search/containers/result.component.ts | 17 ++--- .../src/app/instance/search/search.module.ts | 4 +- .../datatable/datatable.component.html | 18 +++--- .../datatable/datatable.component.ts | 64 ++++++++++++------- .../renderer/image-renderer.component.ts | 2 +- .../shared-search/components/index.ts | 4 +- .../shared-search/shared-search.module.ts | 4 +- .../instance/store/reducers/search.reducer.ts | 27 +++++++- .../store/selectors/search.selector.ts | 20 ++++-- client/src/app/shared/shared.module.ts | 5 +- client/src/styles.scss | 1 + client/tsconfig.json | 3 +- client/yarn.lock | 8 ++- 19 files changed, 204 insertions(+), 61 deletions(-) create mode 100644 client/src/app/instance/search/components/result/datatable-tab.component.html create mode 100644 client/src/app/instance/search/components/result/datatable-tab.component.ts diff --git a/client/package.json b/client/package.json index 502facc1..7e7cad96 100644 --- a/client/package.json +++ b/client/package.json @@ -29,6 +29,7 @@ "keycloak-angular": "^8.2.0", "keycloak-js": "^14.0.0", "ngx-bootstrap": "^7.0.0-rc.1", + "ngx-json-viewer": "^3.0.2", "ngx-toastr": "^14.0.0", "rxjs": "~6.6.0", "tslib": "^2.1.0", diff --git a/client/src/app/instance/search/components/result/datatable-tab.component.html b/client/src/app/instance/search/components/result/datatable-tab.component.html new file mode 100644 index 00000000..670acae1 --- /dev/null +++ b/client/src/app/instance/search/components/result/datatable-tab.component.html @@ -0,0 +1,25 @@ +<accordion *ngIf="getDataset().config.datatable.datatable_enabled" [isAnimated]="true"> + <accordion-group #ag [isOpen]="getDataset().config.datatable.datatable_opened" [panelClass]="'custom-accordion'" class="my-2"> + <button class="btn btn-link btn-block clearfix" accordion-heading> + <span class="pull-left float-left"> + Display result details + + <span *ngIf="ag.isOpen"><span class="fas fa-chevron-up"></span></span> + <span *ngIf="!ag.isOpen"><span class="fas fa-chevron-down"></span></span> + </span> + </button> + <app-datatable + [dataset]="getDataset()" + [attributeList]="attributeList" + [outputList]="outputList" + [dataLength]="dataLength" + [data]="data" + [dataIsLoading]="dataIsLoading" + [dataIsLoaded]="dataIsLoaded" + [selectedData]="selectedData" + (retrieveData)="retrieveData.emit($event)" + (addSelectedData)="addSelectedData.emit($event)" + (deleteSelectedData)="deleteSelectedData.emit($event)"> + </app-datatable> + </accordion-group> +</accordion> diff --git a/client/src/app/instance/search/components/result/datatable-tab.component.ts b/client/src/app/instance/search/components/result/datatable-tab.component.ts new file mode 100644 index 00000000..0b7b2258 --- /dev/null +++ b/client/src/app/instance/search/components/result/datatable-tab.component.ts @@ -0,0 +1,46 @@ +/** + * This file is part of Anis Client. + * + * @copyright Laboratoire d'Astrophysique de Marseille / CNRS + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +import { ChangeDetectionStrategy, Component, EventEmitter, Input, Output } from '@angular/core'; + +import { Attribute, Dataset } from 'src/app/metamodel/models'; +import { Pagination } from 'src/app/instance/store/models'; + +@Component({ + selector: 'app-datatable-tab', + templateUrl: 'datatable-tab.component.html', + changeDetection: ChangeDetectionStrategy.OnPush +}) +/** + * @class + * @classdesc Search result datatable tab component. + */ +export class DatatableTabComponent { + @Input() datasetSelected: string; + @Input() datasetList: Dataset[]; + @Input() attributeList: Attribute[]; + @Input() outputList: number[]; + @Input() dataLength: number; + @Input() data: any[]; + @Input() dataIsLoading: boolean; + @Input() dataIsLoaded: boolean; + @Input() selectedData: any[]; + @Output() retrieveData: EventEmitter<Pagination> = new EventEmitter(); + @Output() addSelectedData: EventEmitter<number | string> = new EventEmitter(); + @Output() deleteSelectedData: EventEmitter<number | string> = new EventEmitter(); + + /** + * Returns selected dataset for the search. + * + * @return Dataset + */ + getDataset(): Dataset { + return this.datasetList.find(dataset => dataset.name === this.datasetSelected); + } +} diff --git a/client/src/app/instance/search/components/result/index.ts b/client/src/app/instance/search/components/result/index.ts index 68174bc2..f710426a 100644 --- a/client/src/app/instance/search/components/result/index.ts +++ b/client/src/app/instance/search/components/result/index.ts @@ -1,9 +1,11 @@ +import { DatatableTabComponent } from './datatable-tab.component'; import { DownloadComponent } from './download.component'; import { ReminderComponent } from './reminder.component'; import { SampComponent } from './samp.component'; import { UrlDisplayComponent } from './url-display.component'; export const resultComponents = [ + DatatableTabComponent, DownloadComponent, ReminderComponent, SampComponent, diff --git a/client/src/app/instance/search/containers/abstract-search.component.ts b/client/src/app/instance/search/containers/abstract-search.component.ts index a1a3340b..a6ebdbbe 100644 --- a/client/src/app/instance/search/containers/abstract-search.component.ts +++ b/client/src/app/instance/search/containers/abstract-search.component.ts @@ -73,7 +73,7 @@ export abstract class AbstractSearchComponent implements OnInit, OnDestroy { Promise.resolve(null).then(() => this.store.dispatch(searchActions.initSearch())); this.attributeListIsLoadedSubscription = this.attributeListIsLoaded.subscribe(attributeListIsLoaded => { if (attributeListIsLoaded) { - this.store.dispatch(searchActions.loadDefaultFormParameters()); + Promise.resolve(null).then(() => this.store.dispatch(searchActions.loadDefaultFormParameters())); } }); } diff --git a/client/src/app/instance/search/containers/result.component.html b/client/src/app/instance/search/containers/result.component.html index 3bb295f6..9eacc2ff 100644 --- a/client/src/app/instance/search/containers/result.component.html +++ b/client/src/app/instance/search/containers/result.component.html @@ -60,19 +60,21 @@ [dataLength]="dataLength | async" [isConeSearchAdded]="isConeSearchAdded | async" [coneSearch]="coneSearch | async"> - </app-cone-search-plot-tab> + </app-cone-search-plot-tab> --> <app-datatable-tab - [datasetName]="datasetName | async" + [datasetSelected]="datasetSelected | async" [datasetList]="datasetList | async" [attributeList]="attributeList | async" [outputList]="outputList | async" - [searchData]="searchData | async" [dataLength]="dataLength | async" + [data]="data | async" + [dataIsLoading]="dataIsLoading | async" + [dataIsLoaded]="dataIsLoaded | async" [selectedData]="selectedData | async" - (getSearchData)="getSearchData($event)" + (retrieveData)="retrieveData($event)" (addSelectedData)="addSearchData($event)" (deleteSelectedData)="deleteSearchData($event)"> - </app-datatable-tab> --> + </app-datatable-tab> </ng-container> </div> </div> diff --git a/client/src/app/instance/search/containers/result.component.ts b/client/src/app/instance/search/containers/result.component.ts index 85bd6dc4..1e1c3359 100644 --- a/client/src/app/instance/search/containers/result.component.ts +++ b/client/src/app/instance/search/containers/result.component.ts @@ -34,6 +34,10 @@ export class ResultComponent extends AbstractSearchComponent { public dataLength: Observable<number>; public dataLengthIsLoading: Observable<boolean>; public dataLengthIsLoaded: Observable<boolean>; + public data: Observable<any>; + public dataIsLoading: Observable<boolean>; + public dataIsLoaded: Observable<boolean>; + public selectedData: Observable<any>; public sampRegistered: Observable<boolean>; private pristineSubscription: Subscription; @@ -43,6 +47,10 @@ export class ResultComponent extends AbstractSearchComponent { this.dataLength = this.store.select(searchSelector.selectDataLength); this.dataLengthIsLoading = this.store.select(searchSelector.selectDataLengthIsLoading); this.dataLengthIsLoaded = this.store.select(searchSelector.selectDataLengthIsLoaded); + this.data = this.store.select(searchSelector.selectData); + this.dataIsLoading = this.store.select(searchSelector.selectDataIsLoading); + this.dataIsLoaded = this.store.select(searchSelector.selectDataIsLoaded); + this.selectedData = this.store.select(searchSelector.selectSelectedData); this.sampRegistered = this.store.select(sampSelector.selectRegistered); } @@ -71,19 +79,12 @@ export class ResultComponent extends AbstractSearchComponent { this.store.dispatch(sampActions.broadcastVotable({ url })); } - /** - * Dispatches action to retrieve result number. - */ - getDataLength(): void { - // this.store.dispatch(searchActions.retrieveDataLength()); - } - /** * Dispatches action to retrieve data with the given pagination. * * @param {Pagination} pagination - The pagination parameters. */ - getSearchData(pagination: Pagination): void { + retrieveData(pagination: Pagination): void { this.store.dispatch(searchActions.retrieveData({ pagination })); } diff --git a/client/src/app/instance/search/search.module.ts b/client/src/app/instance/search/search.module.ts index 8ae63a5d..63eef0ff 100644 --- a/client/src/app/instance/search/search.module.ts +++ b/client/src/app/instance/search/search.module.ts @@ -10,14 +10,14 @@ import { NgModule } from '@angular/core'; import { SharedModule } from 'src/app/shared/shared.module'; -// import { SharedSearchModule } from '../shared-search/shared-search.module'; +import { SharedSearchModule } from '../shared-search/shared-search.module'; import { SearchRoutingModule, routedComponents } from './search-routing.module'; import { dummiesComponents } from './components'; @NgModule({ imports: [ SharedModule, - // SharedSearchModule, + SharedSearchModule, SearchRoutingModule ], declarations: [ diff --git a/client/src/app/instance/shared-search/components/datatable/datatable.component.html b/client/src/app/instance/shared-search/components/datatable/datatable.component.html index fb1fdb31..8a373adc 100644 --- a/client/src/app/instance/shared-search/components/datatable/datatable.component.html +++ b/client/src/app/instance/shared-search/components/datatable/datatable.component.html @@ -1,8 +1,10 @@ -<div class="table-responsive"> +<app-spinner *ngIf="(dataIsLoading)"></app-spinner> + +<div *ngIf="(dataIsLoaded)" class="table-responsive"> <table class="table table-bordered table-hover"> <thead> <tr> - <th *ngIf="dataset.config.datatable.selectable_row">#</th> + <th *ngIf="dataset.config.datatable.datatable_selectable_rows">#</th> <th *ngFor="let attribute of getOutputList()" scope="col" class="clickable" (click)="sort(attribute.id)"> {{ attribute.label }} <span *ngIf="attribute.id === sortedCol" class="pl-2"> @@ -26,7 +28,7 @@ </thead> <tbody> <tr *ngFor="let datum of data"> - <td *ngIf="dataset.config.datatable.selectable_row" class="data-selected" + <td *ngIf="dataset.config.datatable.datatable_selectable_rows" class="data-selected" (click)="toggleSelection(datum)"> <button class="btn btn-block text-left p-0 m-0"> <span *ngIf="!isSelected(datum)"> @@ -43,35 +45,35 @@ <app-detail-renderer [value]="datum[attribute.label]" [datasetName]="dataset.name" - [config]="attribute.renderer_config"> + [config]="getRendererConfig(attribute)"> </app-detail-renderer> </div> <div *ngSwitchCase="'link'"> <app-link-renderer [value]="datum[attribute.label]" [datasetName]="dataset.name" - [config]="attribute.renderer_config"> + [config]="getRendererConfig(attribute)"> </app-link-renderer> </div> <div *ngSwitchCase="'download'"> <app-download-renderer [value]="datum[attribute.label]" [datasetName]="dataset.name" - [config]="attribute.renderer_config"> + [config]="getRendererConfig(attribute)"> </app-download-renderer> </div> <div *ngSwitchCase="'image'"> <app-image-renderer [value]="datum[attribute.label]" [datasetName]="dataset.name" - [config]="attribute.renderer_config"> + [config]="getRendererConfig(attribute)"> </app-image-renderer> </div> <div *ngSwitchCase="'json'"> <app-json-renderer [value]="datum[attribute.label]" [attributeLabel]="attribute.label" - [config]="attribute.renderer_config"> + [config]="getRendererConfig(attribute)"> </app-json-renderer> </div> <div *ngSwitchDefault> diff --git a/client/src/app/instance/shared-search/components/datatable/datatable.component.ts b/client/src/app/instance/shared-search/components/datatable/datatable.component.ts index 8cfef40a..56d115ee 100644 --- a/client/src/app/instance/shared-search/components/datatable/datatable.component.ts +++ b/client/src/app/instance/shared-search/components/datatable/datatable.component.ts @@ -9,7 +9,7 @@ import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core'; -import { Attribute, Dataset } from 'src/app/metamodel/models'; +import { Attribute, Dataset, DetailRendererConfig, DownloadRendererConfig, ImageRendererConfig, LinkRendererConfig, RendererConfig } from 'src/app/metamodel/models'; import { Pagination, PaginationOrder } from 'src/app/instance/store/models'; @@ -25,36 +25,56 @@ import { Pagination, PaginationOrder } from 'src/app/instance/store/models'; * @implements OnInit */ export class DatatableComponent implements OnInit { - @Input() datasetSelected: string; - @Input() datasetList: Dataset[]; + @Input() dataset: Dataset; @Input() attributeList: Attribute[]; @Input() outputList: number[]; - @Input() data: any[]; @Input() dataLength: number; + @Input() data: any[]; + @Input() dataIsLoading: boolean; + @Input() dataIsLoaded: boolean; @Input() selectedData: any[] = []; - @Output() getData: EventEmitter<Pagination> = new EventEmitter(); + @Output() retrieveData: EventEmitter<Pagination> = new EventEmitter(); @Output() addSelectedData: EventEmitter<number | string> = new EventEmitter(); @Output() deleteSelectedData: EventEmitter<number | string> = new EventEmitter(); - nbItems = 10; - page = 1; - sortedCol: number = null; - sortedOrder: PaginationOrder = PaginationOrder.a; + + public page = 1; + public nbItems = 10; + public sortedCol: number = null; + public sortedOrder: PaginationOrder = PaginationOrder.a; ngOnInit() { this.sortedCol = this.attributeList.find(a => a.order_by).id; + Promise.resolve(null).then(() => this.retrieveData.emit({ + dname: this.dataset.name, + page: this.page, + nbItems: this.nbItems, + sortedCol: this.sortedCol, + order: this.sortedOrder + })); } - getDataset() { - return this.datasetList.find(dataset => dataset.name === this.datasetSelected); - } - - /** - * Checks if there is no data selected. - * - * @return boolean - */ - noSelectedData(): boolean { - return this.selectedData.length < 1; + getRendererConfig(attribute: Attribute) { + let config = null; + switch(attribute.renderer) { + case 'detail': + config = attribute.renderer_config as DetailRendererConfig; + break; + case 'link': + config = attribute.renderer_config as LinkRendererConfig; + break; + case 'download': + config = attribute.renderer_config as DownloadRendererConfig; + break; + case 'image': + config = attribute.renderer_config as ImageRendererConfig; + break; + case 'json': + config = attribute.renderer_config as RendererConfig; + break; + default: + config = null; + } + return config; } /** @@ -111,13 +131,13 @@ export class DatatableComponent implements OnInit { changePage(nb: number): void { this.page = nb; const pagination: Pagination = { - dname: this.getDataset().name, + dname: this.dataset.name, page: this.page, nbItems: this.nbItems, sortedCol: this.sortedCol, order: this.sortedOrder }; - this.getData.emit(pagination); + this.retrieveData.emit(pagination); } /** diff --git a/client/src/app/instance/shared-search/components/datatable/renderer/image-renderer.component.ts b/client/src/app/instance/shared-search/components/datatable/renderer/image-renderer.component.ts index dac78788..75521e7d 100644 --- a/client/src/app/instance/shared-search/components/datatable/renderer/image-renderer.component.ts +++ b/client/src/app/instance/shared-search/components/datatable/renderer/image-renderer.component.ts @@ -12,7 +12,7 @@ import { Component, Input, ChangeDetectionStrategy, TemplateRef } from '@angular import { BsModalService } from 'ngx-bootstrap/modal'; import { BsModalRef } from 'ngx-bootstrap/modal/bs-modal-ref.service'; -import { ImageRendererConfig } from 'src/app/metamodel/models/renderers/image-renderer-config.model'; +import { ImageRendererConfig } from 'src/app/metamodel/models/renderers'; import { environment } from 'src/environments/environment'; @Component({ diff --git a/client/src/app/instance/shared-search/components/index.ts b/client/src/app/instance/shared-search/components/index.ts index 1bd2ebbd..f3ee95d0 100644 --- a/client/src/app/instance/shared-search/components/index.ts +++ b/client/src/app/instance/shared-search/components/index.ts @@ -1,7 +1,7 @@ -import { coneSearchComponents } from './cone-search'; +// import { coneSearchComponents } from './cone-search'; import { datatableComponents } from './datatable'; export const sharedComponents = [ - coneSearchComponents, + // coneSearchComponents, datatableComponents ]; diff --git a/client/src/app/instance/shared-search/shared-search.module.ts b/client/src/app/instance/shared-search/shared-search.module.ts index e43fcc5e..8d66fd66 100644 --- a/client/src/app/instance/shared-search/shared-search.module.ts +++ b/client/src/app/instance/shared-search/shared-search.module.ts @@ -8,6 +8,7 @@ */ import { NgModule } from '@angular/core'; +import { RouterModule } from '@angular/router'; import { SharedModule } from 'src/app/shared/shared.module'; import { sharedComponents } from './components'; @@ -15,7 +16,8 @@ import { sharedPipes } from './pipes'; @NgModule({ imports: [ - SharedModule + SharedModule, + RouterModule ], declarations: [ sharedComponents, diff --git a/client/src/app/instance/store/reducers/search.reducer.ts b/client/src/app/instance/store/reducers/search.reducer.ts index 66221436..ee7d006a 100644 --- a/client/src/app/instance/store/reducers/search.reducer.ts +++ b/client/src/app/instance/store/reducers/search.reducer.ts @@ -22,10 +22,12 @@ export interface State { coneSearchAdded: boolean; criteriaList: Criterion[]; outputList: number[]; - searchData: any[]; dataLengthIsLoading: boolean; dataLengthIsLoaded: boolean; dataLength: number; + data: any[], + dataIsLoading: boolean, + dataIsLoaded: boolean, selectedData: any[]; } @@ -39,10 +41,12 @@ export const initialState: State = { coneSearchAdded: false, criteriaList: [], outputList: [], - searchData: [], dataLengthIsLoading: false, dataLengthIsLoaded: false, dataLength: null, + data: [], + dataIsLoading: false, + dataIsLoaded: false, selectedData: [] }; @@ -115,6 +119,21 @@ export const searchReducer = createReducer( ...state, dataLengthIsLoading: false })), + on(searchActions.retrieveData, state => ({ + ...state, + dataIsLoading: true, + dataIsLoaded: false + })), + on(searchActions.retrieveDataSuccess, (state, { data }) => ({ + ...state, + data, + dataIsLoading: false, + dataIsLoaded: true + })), + on(searchActions.retrieveDataFail, state => ({ + ...state, + dataIsLoading: false + })), on(searchActions.destroyResults, state => ({ ...state, searchData: [], @@ -135,8 +154,10 @@ export const selectResultStepChecked = (state: State) => state.resultStepChecked export const selectIsConeSearchAdded = (state: State) => state.coneSearchAdded; export const selectCriteriaList = (state: State) => state.criteriaList; export const selectOutputList = (state: State) => state.outputList; -export const selectSearchData = (state: State) => state.searchData; export const selectDataLengthIsLoading = (state: State) => state.dataLengthIsLoading; export const selectDataLengthIsLoaded = (state: State) => state.dataLengthIsLoaded; export const selectDataLength = (state: State) => state.dataLength; +export const selectData = (state: State) => state.data; +export const selectDataIsLoading = (state: State) => state.dataIsLoading; +export const selectDataIsLoaded = (state: State) => state.dataIsLoaded; export const selectSelectedData = (state: State) => state.selectedData; diff --git a/client/src/app/instance/store/selectors/search.selector.ts b/client/src/app/instance/store/selectors/search.selector.ts index 57c9c1ba..ee70032c 100644 --- a/client/src/app/instance/store/selectors/search.selector.ts +++ b/client/src/app/instance/store/selectors/search.selector.ts @@ -63,11 +63,6 @@ export const selectOutputList = createSelector( fromSearch.selectOutputList ); -export const selectSearchData = createSelector( - selectInstanceState, - fromSearch.selectSearchData -); - export const selectDataLengthIsLoading = createSelector( selectInstanceState, fromSearch.selectDataLengthIsLoading @@ -83,6 +78,21 @@ export const selectDataLength = createSelector( fromSearch.selectDataLength ); +export const selectDataIsLoading = createSelector( + selectInstanceState, + fromSearch.selectDataIsLoading +); + +export const selectDataIsLoaded = createSelector( + selectInstanceState, + fromSearch.selectDataIsLoaded +); + +export const selectData = createSelector( + selectInstanceState, + fromSearch.selectData +); + export const selectSelectedData = createSelector( selectInstanceState, fromSearch.selectSelectedData diff --git a/client/src/app/shared/shared.module.ts b/client/src/app/shared/shared.module.ts index b9c2adcc..b402511e 100644 --- a/client/src/app/shared/shared.module.ts +++ b/client/src/app/shared/shared.module.ts @@ -23,6 +23,7 @@ import { BsDatepickerModule } from 'ngx-bootstrap/datepicker'; import { TabsModule } from 'ngx-bootstrap/tabs'; import { PaginationModule } from 'ngx-bootstrap/pagination'; import { NgSelectModule } from '@ng-select/ng-select'; +import { NgxJsonViewerModule } from 'ngx-json-viewer'; import { sharedComponents } from './components'; import { sharedPipes } from './pipes'; @@ -47,7 +48,8 @@ import { sharedPipes } from './pipes'; BsDatepickerModule.forRoot(), TabsModule.forRoot(), PaginationModule.forRoot(), - NgSelectModule + NgSelectModule, + NgxJsonViewerModule ], exports: [ CommonModule, @@ -64,6 +66,7 @@ import { sharedPipes } from './pipes'; TabsModule, PaginationModule, NgSelectModule, + NgxJsonViewerModule, sharedComponents, sharedPipes ] diff --git a/client/src/styles.scss b/client/src/styles.scss index 89e28473..93c9c212 100644 --- a/client/src/styles.scss +++ b/client/src/styles.scss @@ -27,6 +27,7 @@ @import "~bootstrap/scss/popover"; @import "~bootstrap/scss/tooltip"; @import "~bootstrap/scss/progress"; +@import "~bootstrap/scss/pagination"; @import "~bootstrap/scss/utilities"; /* Import ngx-toastr bootstrap 4 alert styled design */ diff --git a/client/tsconfig.json b/client/tsconfig.json index 12fb7bd5..824b803c 100644 --- a/client/tsconfig.json +++ b/client/tsconfig.json @@ -25,6 +25,7 @@ "enableI18nLegacyMessageIdFormat": false, "strictInjectionParameters": true, "strictInputAccessModifiers": true, - "strictTemplates": true + "strictTemplates": true, + "strictDomEventTypes": false } } diff --git a/client/yarn.lock b/client/yarn.lock index 922a5191..2a005f93 100644 --- a/client/yarn.lock +++ b/client/yarn.lock @@ -4908,7 +4908,6 @@ minipass-fetch@^1.3.0, minipass-fetch@^1.3.2: resolved "https://registry.yarnpkg.com/minipass-fetch/-/minipass-fetch-1.3.3.tgz#34c7cea038c817a8658461bf35174551dce17a0a" integrity sha512-akCrLDWfbdAWkMLBxJEeWTdNsjML+dt5YgOI4gJ53vuO0vrmYQkUPxa6j6V65s9CcePIr2SSWqjT2EcrNseryQ== dependencies: - encoding "^0.1.12" minipass "^3.1.0" minipass-sized "^1.0.3" minizlib "^2.0.0" @@ -5070,6 +5069,13 @@ ngx-bootstrap@^7.0.0-rc.1: dependencies: tslib "^2.0.0" +ngx-json-viewer@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/ngx-json-viewer/-/ngx-json-viewer-3.0.2.tgz#91e72fe41f80756181aa0d36b4bfaeac5df5b1b1" + integrity sha512-XBj0DgUDIBOeJuAczlFQIIMCaELJGoEbvjBWIXHIh2QebiB5lY6itslRkbE5TAgFn1bYK+2ToxqwspLgP4DDJg== + dependencies: + tslib "^2.0.0" + ngx-toastr@^14.0.0: version "14.0.0" resolved "https://registry.yarnpkg.com/ngx-toastr/-/ngx-toastr-14.0.0.tgz#20e4737ef330b892a453768cd98b980558aeb286" -- GitLab