fix: route stack service causes needless network traffic

This commit is contained in:
2023-09-06 15:29:47 +02:00
parent f2c4ee308f
commit 3c49c4cf6d
6 changed files with 87 additions and 100 deletions

View File

@@ -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

View File

@@ -93,10 +93,6 @@ export class DataDetailComponent implements OnInit {
translateService: TranslateService, translateService: TranslateService,
) { ) {
this.inputItem = router.getCurrentNavigation()?.extras.state?.item; 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; this.language = translateService.currentLang as SCLanguageCode;
translateService.onLangChange.subscribe((event: LangChangeEvent) => { translateService.onLangChange.subscribe((event: LangChangeEvent) => {
this.language = event.lang as SCLanguageCode; this.language = event.lang as SCLanguageCode;

View File

@@ -37,32 +37,22 @@ export class DataPathComponent implements OnInit {
@Input() maxItems = 2; @Input() maxItems = 2;
@Input() set item(item: SCThings) { @Input() set item(item: SCThings) {
// eslint-disable-next-line unicorn/prefer-ternary
if (item.type === SCThingType.Catalog && item.superCatalogs) { if (item.type === SCThingType.Catalog && item.superCatalogs) {
this.path = new Promise(resolve => this.path = Promise.resolve([...item.superCatalogs!, item]);
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
resolve([...item.superCatalogs!, item]),
);
} else if (item.type === SCThingType.Assessment && item.superAssessments) { } else if (item.type === SCThingType.Assessment && item.superAssessments) {
this.path = new Promise(resolve => this.path = Promise.resolve([...item.superAssessments!, item]);
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
resolve([...item.superAssessments!, item]),
);
} else if ( } else if (
item.type === SCThingType.AcademicEvent && item.type === SCThingType.AcademicEvent &&
item.catalogs && item.catalogs &&
(item.catalogs.length === 1 || this.routeStack.lastDataDetail) (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<SCCatalog>;
this.path = new Promise(async resolve => { this.path = new Promise(async resolve => {
const catalog = await catalogPromise; const catalogWithoutReferences = item.catalogs![0];
const superCatalogs = catalog.superCatalogs; const catalog =
item.catalogs!.length === 1
? await this.dataProvider.get(catalogWithoutReferences.uid, DataScope.Remote)
: this.routeStack.lastDataDetail;
const superCatalogs = (catalog as SCCatalog).superCatalogs;
resolve( resolve(
superCatalogs superCatalogs

View File

@@ -13,16 +13,16 @@
~ this program. If not, see <https://www.gnu.org/licenses/>. ~ this program. If not, see <https://www.gnu.org/licenses/>.
--> -->
<ng-container *ngIf="items as items; else loading"> <ng-container *ngIf="items | async as items; else loading">
<ion-list> <ion-list>
<ng-container *ngIf="!listHeader; else header"></ng-container> <ng-container *ngIf="!listHeader; else header"></ng-container>
<ng-container *ngFor="let item of items | async"> <ng-container *ngFor="let item of items">
<ng-container <ng-container
*ngTemplateOutlet="listItemTemplateRef || defaultListItem; context: {$implicit: item}" *ngTemplateOutlet="listItemTemplateRef || defaultListItem; context: {$implicit: item}"
></ng-container> ></ng-container>
</ng-container> </ng-container>
</ion-list> </ion-list>
<ion-label class="empty-list-message" *ngIf="emptyListMessage && (items | async)?.length === 0" <ion-label class="empty-list-message" *ngIf="emptyListMessage && items.length === 0"
>{{ emptyListMessage }}</ion-label >{{ emptyListMessage }}</ion-label
> >
</ng-container> </ng-container>

View File

@@ -13,43 +13,44 @@
* this program. If not, see <https://www.gnu.org/licenses/>. * this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
import {Component, Input, OnInit} from '@angular/core'; import {Component, Input, OnInit} from '@angular/core';
import {SCCatalog, SCSearchBooleanFilter, SCDucetSort} from '@openstapps/core'; import {SCCatalog, SCThings} from '@openstapps/core';
import {SearchPageComponent} from '../../list/search-page.component'; import {DataProvider} from '../../data.provider';
@Component({ @Component({
selector: 'stapps-catalog-detail-content', selector: 'stapps-catalog-detail-content',
templateUrl: 'catalog-detail-content.html', templateUrl: 'catalog-detail-content.html',
styleUrls: ['catalog-detail-content.scss'], styleUrls: ['catalog-detail-content.scss'],
}) })
export class CatalogDetailContentComponent extends SearchPageComponent implements OnInit { export class CatalogDetailContentComponent implements OnInit {
/** /**
* SCCatalog to display * SCCatalog to display
*/ */
@Input() item: SCCatalog; @Input() item: SCCatalog;
ngOnInit() { items: Promise<SCThings[]>;
super.ngOnInit();
}
initialize() { constructor(private dataProvider: DataProvider) {}
this.showDefaultData = true;
this.pageSize = 100;
const nameSort: SCDucetSort = { async ngOnInit() {
arguments: {field: 'name'}, this.items = this.dataProvider
order: 'asc', .search({
type: 'ducet', size: 100,
}; sort: [
{
const typeSort: SCDucetSort = {
arguments: {field: 'type'}, arguments: {field: 'type'},
order: 'desc', order: 'desc',
type: 'ducet', type: 'ducet',
}; },
{
this.sortQuery = [typeSort, nameSort]; arguments: {field: 'name'},
order: 'asc',
const subCatalogFilter: SCSearchBooleanFilter = { type: 'ducet',
},
],
filter: {
arguments: {
filters: [
{
arguments: { arguments: {
operation: 'and', operation: 'and',
filters: [ filters: [
@@ -70,9 +71,8 @@ export class CatalogDetailContentComponent extends SearchPageComponent implement
], ],
}, },
type: 'boolean', type: 'boolean',
}; },
{
const subEventsFilter: SCSearchBooleanFilter = {
arguments: { arguments: {
operation: 'and', operation: 'and',
filters: [ filters: [
@@ -93,14 +93,13 @@ export class CatalogDetailContentComponent extends SearchPageComponent implement
], ],
}, },
type: 'boolean', type: 'boolean',
}; },
],
this.forcedFilter = {
arguments: {
filters: [subCatalogFilter, subEventsFilter],
operation: 'or', operation: 'or',
}, },
type: 'boolean', type: 'boolean',
}; },
})
.then(({data}) => data);
} }
} }

View File

@@ -12,11 +12,9 @@
* You should have received a copy of the GNU General Public License along with * You should have received a copy of the GNU General Public License along with
* this program. If not, see <https://www.gnu.org/licenses/>. * this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
import {Injectable} from '@angular/core'; import {Injectable} from '@angular/core';
import {NavigationEnd, Router} from '@angular/router'; import {NavigationEnd, Router} from '@angular/router';
import {SCSaveableThing, SCThings} from '@openstapps/core'; import {SCSaveableThing, SCThings} from '@openstapps/core';
import {DataProvider, DataScope} from '../modules/data/data.provider';
@Injectable({ @Injectable({
providedIn: 'root', providedIn: 'root',
@@ -30,15 +28,14 @@ export class RoutingStackService {
lastDataDetail?: Promise<SCSaveableThing | SCThings>; lastDataDetail?: Promise<SCSaveableThing | SCThings>;
constructor(private router: Router, private dataProvider: DataProvider) { constructor(private router: Router) {
this.router.events.subscribe(event => { this.router.events.subscribe(event => {
if (event instanceof NavigationEnd) { if (event instanceof NavigationEnd) {
this.lastRoute = this.currentRoute; this.lastRoute = this.currentRoute;
this.currentRoute = event.urlAfterRedirects; this.currentRoute = event.urlAfterRedirects;
const uid = this.currentRoute.match(/^\/data-detail\/([\w-]+)$/)?.[1];
this.lastDataDetail = this.currentDataDetail; this.lastDataDetail = this.currentDataDetail;
this.currentDataDetail = uid ? this.dataProvider.get(uid, DataScope.Remote) : undefined; this.currentDataDetail = this.router.getCurrentNavigation()!.extras.state?.item;
} }
}); });
} }