diff --git a/.changeset/sour-carpets-flash.md b/.changeset/sour-carpets-flash.md new file mode 100644 index 00000000..542241a3 --- /dev/null +++ b/.changeset/sour-carpets-flash.md @@ -0,0 +1,5 @@ +--- +'@openstapps/app': patch +--- + +Fixed an issue that caused double and triple loading of data detail items through the route stack service diff --git a/frontend/app/src/app/modules/data/detail/data-detail.component.ts b/frontend/app/src/app/modules/data/detail/data-detail.component.ts index 263a992b..d64e98a2 100644 --- a/frontend/app/src/app/modules/data/detail/data-detail.component.ts +++ b/frontend/app/src/app/modules/data/detail/data-detail.component.ts @@ -93,10 +93,6 @@ export class DataDetailComponent implements OnInit { translateService: TranslateService, ) { this.inputItem = router.getCurrentNavigation()?.extras.state?.item; - if (!this.inputItem) { - // TODO: remove - console.warn('Did you forget to pass a state?'); - } this.language = translateService.currentLang as SCLanguageCode; translateService.onLangChange.subscribe((event: LangChangeEvent) => { this.language = event.lang as SCLanguageCode; diff --git a/frontend/app/src/app/modules/data/detail/data-path.component.ts b/frontend/app/src/app/modules/data/detail/data-path.component.ts index d65069ff..c0c343f4 100644 --- a/frontend/app/src/app/modules/data/detail/data-path.component.ts +++ b/frontend/app/src/app/modules/data/detail/data-path.component.ts @@ -37,32 +37,22 @@ export class DataPathComponent implements OnInit { @Input() maxItems = 2; @Input() set item(item: SCThings) { - // eslint-disable-next-line unicorn/prefer-ternary if (item.type === SCThingType.Catalog && item.superCatalogs) { - this.path = new Promise(resolve => - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - resolve([...item.superCatalogs!, item]), - ); + this.path = Promise.resolve([...item.superCatalogs!, item]); } else if (item.type === SCThingType.Assessment && item.superAssessments) { - this.path = new Promise(resolve => - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - resolve([...item.superAssessments!, item]), - ); + this.path = Promise.resolve([...item.superAssessments!, item]); } else if ( item.type === SCThingType.AcademicEvent && item.catalogs && (item.catalogs.length === 1 || this.routeStack.lastDataDetail) ) { - const catalogWithoutReferences = item.catalogs[0]; - const catalogPromise = ( - item.catalogs.length === 1 - ? this.dataProvider.get(catalogWithoutReferences.uid, DataScope.Remote) - : this.routeStack.lastDataDetail - ) as Promise; - this.path = new Promise(async resolve => { - const catalog = await catalogPromise; - const superCatalogs = catalog.superCatalogs; + const catalogWithoutReferences = item.catalogs![0]; + const catalog = + item.catalogs!.length === 1 + ? await this.dataProvider.get(catalogWithoutReferences.uid, DataScope.Remote) + : this.routeStack.lastDataDetail; + const superCatalogs = (catalog as SCCatalog).superCatalogs; resolve( superCatalogs diff --git a/frontend/app/src/app/modules/data/list/simple-data-list.html b/frontend/app/src/app/modules/data/list/simple-data-list.html index 4c8e12ea..f9aede4d 100644 --- a/frontend/app/src/app/modules/data/list/simple-data-list.html +++ b/frontend/app/src/app/modules/data/list/simple-data-list.html @@ -13,16 +13,16 @@ ~ this program. If not, see . --> - + - + - {{ emptyListMessage }} diff --git a/frontend/app/src/app/modules/data/types/catalog/catalog-detail-content.component.ts b/frontend/app/src/app/modules/data/types/catalog/catalog-detail-content.component.ts index 26fa24c9..d4ecf2ca 100644 --- a/frontend/app/src/app/modules/data/types/catalog/catalog-detail-content.component.ts +++ b/frontend/app/src/app/modules/data/types/catalog/catalog-detail-content.component.ts @@ -13,94 +13,93 @@ * this program. If not, see . */ import {Component, Input, OnInit} from '@angular/core'; -import {SCCatalog, SCSearchBooleanFilter, SCDucetSort} from '@openstapps/core'; -import {SearchPageComponent} from '../../list/search-page.component'; +import {SCCatalog, SCThings} from '@openstapps/core'; +import {DataProvider} from '../../data.provider'; @Component({ selector: 'stapps-catalog-detail-content', templateUrl: 'catalog-detail-content.html', styleUrls: ['catalog-detail-content.scss'], }) -export class CatalogDetailContentComponent extends SearchPageComponent implements OnInit { +export class CatalogDetailContentComponent implements OnInit { /** * SCCatalog to display */ @Input() item: SCCatalog; - ngOnInit() { - super.ngOnInit(); - } + items: Promise; - initialize() { - this.showDefaultData = true; - this.pageSize = 100; + constructor(private dataProvider: DataProvider) {} - const nameSort: SCDucetSort = { - arguments: {field: 'name'}, - order: 'asc', - type: 'ducet', - }; - - const typeSort: SCDucetSort = { - arguments: {field: 'type'}, - order: 'desc', - type: 'ducet', - }; - - this.sortQuery = [typeSort, nameSort]; - - const subCatalogFilter: SCSearchBooleanFilter = { - arguments: { - operation: 'and', - filters: [ + async ngOnInit() { + this.items = this.dataProvider + .search({ + size: 100, + sort: [ { - type: 'value', - arguments: { - field: 'type', - value: 'catalog', - }, + arguments: {field: 'type'}, + order: 'desc', + type: 'ducet', }, { - type: 'value', - arguments: { - field: 'superCatalog.uid', - value: this.item.uid, - }, + arguments: {field: 'name'}, + order: 'asc', + type: 'ducet', }, ], - }, - type: 'boolean', - }; - - const subEventsFilter: SCSearchBooleanFilter = { - arguments: { - operation: 'and', - filters: [ - { - type: 'value', - arguments: { - field: 'type', - value: 'academic event', - }, + filter: { + arguments: { + filters: [ + { + arguments: { + operation: 'and', + filters: [ + { + type: 'value', + arguments: { + field: 'type', + value: 'catalog', + }, + }, + { + type: 'value', + arguments: { + field: 'superCatalog.uid', + value: this.item.uid, + }, + }, + ], + }, + type: 'boolean', + }, + { + arguments: { + operation: 'and', + filters: [ + { + type: 'value', + arguments: { + field: 'type', + value: 'academic event', + }, + }, + { + type: 'value', + arguments: { + field: 'catalogs.uid', + value: this.item.uid, + }, + }, + ], + }, + type: 'boolean', + }, + ], + operation: 'or', }, - { - type: 'value', - arguments: { - field: 'catalogs.uid', - value: this.item.uid, - }, - }, - ], - }, - type: 'boolean', - }; - - this.forcedFilter = { - arguments: { - filters: [subCatalogFilter, subEventsFilter], - operation: 'or', - }, - type: 'boolean', - }; + type: 'boolean', + }, + }) + .then(({data}) => data); } } diff --git a/frontend/app/src/app/util/routing-stack.service.ts b/frontend/app/src/app/util/routing-stack.service.ts index cbd3c1be..8faef8bb 100644 --- a/frontend/app/src/app/util/routing-stack.service.ts +++ b/frontend/app/src/app/util/routing-stack.service.ts @@ -12,11 +12,9 @@ * You should have received a copy of the GNU General Public License along with * this program. If not, see . */ - import {Injectable} from '@angular/core'; import {NavigationEnd, Router} from '@angular/router'; import {SCSaveableThing, SCThings} from '@openstapps/core'; -import {DataProvider, DataScope} from '../modules/data/data.provider'; @Injectable({ providedIn: 'root', @@ -30,15 +28,14 @@ export class RoutingStackService { lastDataDetail?: Promise; - constructor(private router: Router, private dataProvider: DataProvider) { + constructor(private router: Router) { this.router.events.subscribe(event => { if (event instanceof NavigationEnd) { this.lastRoute = this.currentRoute; this.currentRoute = event.urlAfterRedirects; - const uid = this.currentRoute.match(/^\/data-detail\/([\w-]+)$/)?.[1]; this.lastDataDetail = this.currentDataDetail; - this.currentDataDetail = uid ? this.dataProvider.get(uid, DataScope.Remote) : undefined; + this.currentDataDetail = this.router.getCurrentNavigation()!.extras.state?.item; } }); }