feat: Ionic v6 breadcrumbs in catalog module

This commit is contained in:
Thea Schöbl
2022-04-13 14:10:16 +00:00
parent 552911cfcf
commit 7b491ed3bb
66 changed files with 653 additions and 199 deletions

View File

@@ -1,16 +1,16 @@
/*
* Copyright (C) 2018-2021 StApps
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
* Software Foundation, version 3.
* Copyright (C) 2022 StApps
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
* Software Foundation, version 3.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <https://www.gnu.org/licenses/>.
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <https://www.gnu.org/licenses/>.
*/
import {NgModule} from '@angular/core';
import {RouterModule, Routes} from '@angular/router';

View File

@@ -1,16 +1,16 @@
/*
* Copyright (C) 2021 StApps
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
* Software Foundation, version 3.
* Copyright (C) 2022 StApps
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
* Software Foundation, version 3.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <https://www.gnu.org/licenses/>.
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <https://www.gnu.org/licenses/>.
*/
import {ScrollingModule} from '@angular/cdk/scrolling';
import {CommonModule} from '@angular/common';
@@ -82,6 +82,10 @@ import {FavoriteButtonComponent} from './elements/favorite-button.component';
import {SimpleDataListComponent} from './list/simple-data-list.component';
import {TitleCardComponent} from './elements/title-card.component';
import {CalendarService} from '../calendar/calendar.service';
import {RoutingStackService} from '../../util/routing-stack.service';
import {DataPathComponent} from './detail/data-path.component';
import {EventRoutePathComponent} from './types/event/event-route-path.component';
import {UtilModule} from '../../util/util.module';
/**
* Module for handling data
@@ -101,6 +105,8 @@ import {CalendarService} from '../calendar/calendar.service';
DataIconPipe,
DataListComponent,
DataListItemComponent,
DataPathComponent,
EventRoutePathComponent,
DateSeriesDetailContentComponent,
DateSeriesListItemComponent,
DishDetailContentComponent,
@@ -158,6 +164,7 @@ import {CalendarService} from '../calendar/calendar.service';
StorageModule,
TranslateModule.forChild(),
ThingTranslateModule.forChild(),
UtilModule,
],
providers: [
CoordinatedSearchProvider,
@@ -167,6 +174,7 @@ import {CalendarService} from '../calendar/calendar.service';
ScheduleProvider,
StAppsWebHttpClient,
CalendarService,
RoutingStackService,
],
exports: [
DataDetailComponent,

View File

@@ -30,6 +30,7 @@ import {
SCSaveableThing,
SCFeedbackRequest,
SCFeedbackResponse,
SCUuid,
} from '@openstapps/core';
import {environment} from '../../../environments/environment';
import {StorageProvider} from '../storage/storage.provider';
@@ -41,6 +42,11 @@ export enum DataScope {
Remote = 'remote',
}
interface CacheItem<T> {
data: Promise<T>;
timestamp: number;
}
/**
* Generated class for the DataProvider provider.
*
@@ -70,6 +76,10 @@ export class DataProvider {
*/
private _storagePrefix = 'stapps.data';
readonly cache: Record<SCUuid, CacheItem<SCThings> | undefined> = {};
private maxCacheAge = 3600;
/**
* Version of the app (used for the header in communication with the backend)
*/
@@ -229,7 +239,17 @@ export class DataProvider {
return this.storageProvider.get<SCSaveableThing>(this.getDataKey(uid));
}
if (scope === DataScope.Remote) {
return this.client.getThing(uid);
const timestamp = Date.now();
const cacheItem = this.cache[uid];
if (cacheItem && timestamp - cacheItem.timestamp < this.maxCacheAge) {
return cacheItem.data;
}
const item = this.client.getThing(uid);
this.cache[uid] = {
data: item,
timestamp: timestamp,
};
return item;
}
const map: Map<DataScope, SCThings | SCSaveableThing> = new Map();
map.set(DataScope.Local, await this.get(uid, DataScope.Local));

View File

@@ -6,7 +6,7 @@
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public Licens for
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with

View File

@@ -6,7 +6,7 @@
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public Licens for
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with

View File

@@ -6,7 +6,7 @@
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public Licens for
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
@@ -25,9 +25,9 @@ import {ViewWillEnter, ModalController} from '@ionic/angular';
import {LangChangeEvent, TranslateService} from '@ngx-translate/core';
import {
SCLanguageCode,
SCSaveableThing,
SCThings,
SCUuid,
SCSaveableThing,
} from '@openstapps/core';
import {DataProvider, DataScope} from '../data.provider';
import {FavoritesService} from '../../favorites/favorites.service';

View File

@@ -1,7 +1,30 @@
<!--
~ Copyright (C) 2022 StApps
~ This program is free software: you can redistribute it and/or modify it
~ under the terms of the GNU General Public License as published by the Free
~ Software Foundation, version 3.
~
~ This program is distributed in the hope that it will be useful, but WITHOUT
~ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
~ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
~ more details.
~
~ You should have received a copy of the GNU General Public License along with
~ this program. If not, see <https://www.gnu.org/licenses/>.
-->
<ion-header *ngIf="defaultHeader">
<ion-toolbar color="primary">
<ion-buttons slot="start" *ngIf="!isModal">
<ion-back-button></ion-back-button>
<ion-back-button
[defaultHref]="
item?.superCatalog
? ['/data-detail', item.superCatalog.uid]
: item?.catalogs && item?.catalogs.length === 1
? ['/data-detail', item.catalogs[0].uid]
: undefined
"
></ion-back-button>
<ion-menu-button></ion-menu-button>
</ion-buttons>
<ion-title>{{ 'data.detail.TITLE' | translate }}</ion-title>
@@ -42,6 +65,7 @@
<stapps-skeleton-simple-card></stapps-skeleton-simple-card>
</ng-container>
<ng-container *ngSwitchDefault>
<stapps-data-path [item]="item"></stapps-data-path>
<stapps-data-detail-content
[item]="item"
[contentTemplateRef]="contentTemplateRef"

View File

@@ -0,0 +1,82 @@
/*
* Copyright (C) 2022 StApps
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
* Software Foundation, version 3.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <https://www.gnu.org/licenses/>.
*/
import {Component, Input, OnInit} from '@angular/core';
import {RoutingStackService} from '../../../util/routing-stack.service';
import {
SCCatalog,
SCThings,
SCThingType,
SCThingWithoutReferences,
} from '@openstapps/core';
import {DataProvider, DataScope} from '../data.provider';
import {fromEvent, Observable} from 'rxjs';
import {map} from 'rxjs/operators';
@Component({
selector: 'stapps-data-path',
templateUrl: './data-path.html',
styleUrls: ['./data-path.scss'],
})
export class DataPathComponent implements OnInit {
path: Promise<SCThingWithoutReferences[]>;
$width: Observable<number>;
ngOnInit() {
this.$width = fromEvent(window, 'resize').pipe(
map(() => window.innerWidth),
);
}
@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]),
);
} 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<SCCatalog>;
this.path = new Promise(async resolve => {
const catalog = await catalogPromise;
const superCatalogs = catalog.superCatalogs;
resolve(
superCatalogs
? [...superCatalogs, catalogWithoutReferences, item]
: [catalogWithoutReferences, item],
);
});
}
}
constructor(
readonly routeStack: RoutingStackService,
readonly dataProvider: DataProvider,
) {}
}

View File

@@ -0,0 +1,54 @@
<!--
~ Copyright (C) 2022 StApps
~ This program is free software: you can redistribute it and/or modify it
~ under the terms of the GNU General Public License as published by the Free
~ Software Foundation, version 3.
~
~ This program is distributed in the hope that it will be useful, but WITHOUT
~ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
~ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
~ more details.
~
~ You should have received a copy of the GNU General Public License along with
~ this program. If not, see <https://www.gnu.org/licenses/>.
-->
<ng-container *ngIf="path | async as stack">
<ion-breadcrumbs
[itemsBeforeCollapse]="1"
[itemsAfterCollapse]="($width | async) >= 768 ? 1 : 0"
[maxItems]="2"
(ionCollapsedClick)="popover.present($event)"
>
<ion-breadcrumb *ngFor="let fragment of stack">
<ion-label
[routerLink]="['/data-detail', fragment.uid]"
[routerDirection]="'back'"
[style.max-width]="
stack.length === 1
? '100%'
: stack.length === 2
? '40vw'
: ($width | async) >= 768
? '30vw'
: 'calc(100vw - 120px)'
"
class="crumb-label"
>{{ 'name' | thingTranslate: $any(fragment) }}</ion-label
>
</ion-breadcrumb>
</ion-breadcrumbs>
<ion-popover #popover>
<ng-template>
<ion-list>
<ion-item
*ngFor="let fragment of stack"
(click)="popover.dismiss()"
[routerLink]="['/data-detail', fragment.uid]"
[routerDirection]="'back'"
>{{ 'name' | thingTranslate: $any(fragment) }}</ion-item
>
</ion-list>
</ng-template>
</ion-popover>
</ng-container>

View File

@@ -0,0 +1,21 @@
/*!
* Copyright (C) 2022 StApps
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
* Software Foundation, version 3.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <https://www.gnu.org/licenses/>.
*/
.crumb-label {
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
cursor: pointer;
}

View File

@@ -1,19 +1,19 @@
/*
* Copyright (C) 2019 StApps
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
* Software Foundation, version 3.
* Copyright (C) 2022 StApps
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
* Software Foundation, version 3.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <https://www.gnu.org/licenses/>.
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <https://www.gnu.org/licenses/>.
*/
import {Component, Input} from '@angular/core';
import {isThing, SCThing} from '@openstapps/core';
import {SCThingWithoutReferences} from '@openstapps/core';
/**
* TODO
@@ -31,7 +31,7 @@ export class SimpleCardComponent {
/**
* TODO
*/
@Input() content: string | string[] | SCThing[];
@Input() content: string | string[] | SCThingWithoutReferences[];
/**
* TODO
@@ -55,7 +55,8 @@ export class SimpleCardComponent {
* TODO
*/
// eslint-disable-next-line class-methods-use-this
isThing(something: unknown): something is SCThing {
return isThing(something);
isThing(something: unknown): something is SCThingWithoutReferences {
// bypass the 'type' field check because of translated values
return typeof something === 'object';
}
}

View File

@@ -6,7 +6,7 @@
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public Licens for
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with

View File

@@ -6,7 +6,7 @@
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public Licens for
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with

View File

@@ -6,7 +6,7 @@
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public Licens for
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with

View File

@@ -6,7 +6,7 @@
~
~ This program is distributed in the hope that it will be useful, but WITHOUT
~ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
~ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public Licens for
~ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
~ more details.
~
~ You should have received a copy of the GNU General Public License along with

View File

@@ -1,25 +1,25 @@
/*
* Copyright (C) 2019 StApps
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
* Software Foundation, version 3.
* Copyright (C) 2022 StApps
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
* Software Foundation, version 3.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <https://www.gnu.org/licenses/>.
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <https://www.gnu.org/licenses/>.
*/
import {Component, Input} from '@angular/core';
import {
SCAcademicEvent,
SCSportCourse,
SCThing,
SCThingTranslator,
SCTranslations,
} from '@openstapps/core';
import {SCThingTranslator} from '@openstapps/core';
/**
* TODO

View File

@@ -1,48 +1,62 @@
<ng-container *ngIf="item.type === 'academic event'">
<stapps-add-event-action-chip [item]="item" style="margin: 2px">
</stapps-add-event-action-chip>
<stapps-simple-card
*ngIf="item.categories"
[title]="'Categories'"
[content]="translator.translate(item).categories"
>
</stapps-simple-card>
<stapps-simple-card
*ngIf="item.catalogs"
[title]="'Catalogs'"
[content]="item.catalogs"
></stapps-simple-card>
<stapps-simple-card
*ngIf="item.performers"
[title]="'Performers'"
[content]="item.performers"
></stapps-simple-card>
<stapps-simple-card
*ngIf="item.organizers"
[title]="'Organizers'"
[content]="item.organizers"
></stapps-simple-card>
<stapps-simple-card
*ngIf="item.majors"
[title]="'Majors'"
[content]="item.majors"
></stapps-simple-card>
</ng-container>
<!--
~ Copyright (C) 2022 StApps
~ This program is free software: you can redistribute it and/or modify it
~ under the terms of the GNU General Public License as published by the Free
~ Software Foundation, version 3.
~
~ This program is distributed in the hope that it will be useful, but WITHOUT
~ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
~ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
~ more details.
~
~ You should have received a copy of the GNU General Public License along with
~ this program. If not, see <https://www.gnu.org/licenses/>.
-->
<ng-container *ngIf="item.type === 'sport course'">
<stapps-simple-card
*ngIf="item.catalogs"
[title]="'Catalogs'"
[content]="item.catalogs"
></stapps-simple-card>
<stapps-simple-card
*ngIf="item.performers"
[title]="'Performers'"
[content]="item.performers"
></stapps-simple-card>
<stapps-simple-card
*ngIf="item.organizers"
[title]="'Organizers'"
[content]="item.organizers"
></stapps-simple-card>
</ng-container>
<ion-card>
<ion-card-content>
<stapps-add-event-action-chip
*ngIf="item.type === 'academic event'"
[item]="item"
>
</stapps-add-event-action-chip>
</ion-card-content>
</ion-card>
<stapps-simple-card
*ngIf="item.type === 'academic event' && item.categories"
[title]="'categories' | propertyNameTranslate: item"
[content]="'categories' | thingTranslate: item"
>
</stapps-simple-card>
<ion-card *ngIf="item.catalogs">
<ion-card-header>{{
$any('superCatalogs' | propertyNameTranslate: 'catalog') | titlecase
}}</ion-card-header>
<ion-card-content>
<event-route-path
*ngFor="let item of item.catalogs"
[maxItems]="1"
[itemsAfterCollapse]="1"
[itemsBeforeCollapse]="0"
[items]="[undefined, item]"
[more]="item.uid | lazyThing: 'superCatalogs'"
>
</event-route-path>
</ion-card-content>
</ion-card>
<stapps-simple-card
*ngIf="item.performers"
[title]="'performers' | propertyNameTranslate: item"
[content]="item.performers"
></stapps-simple-card>
<stapps-simple-card
*ngIf="item.organizers"
[title]="'organizers' | propertyNameTranslate: item"
[content]="item.organizers"
></stapps-simple-card>
<stapps-simple-card
*ngIf="item.type === 'academic event' && item.majors"
[title]="'majors' | propertyNameTranslate: item"
[content]="item.majors"
></stapps-simple-card>

View File

@@ -0,0 +1,40 @@
/*
* Copyright (C) 2022 StApps
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
* Software Foundation, version 3.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <https://www.gnu.org/licenses/>.
*/
import {Component, Input} from '@angular/core';
import {SCThingWithoutReferences} from '@openstapps/core';
import {Observable} from 'rxjs';
/**
* This was originally intended to be used in more than one place.
* I kept this in place to make it easier to adapt it in the future, if needed.
*/
@Component({
selector: 'event-route-path',
templateUrl: 'event-route-path.html',
styleUrls: ['event-route-path.scss'],
})
export class EventRoutePathComponent {
@Input() maxItems?: number;
@Input() itemsAfterCollapse?: number;
@Input() itemsBeforeCollapse?: number;
@Input() items: Array<SCThingWithoutReferences | undefined> = [];
@Input() more?: Observable<SCThingWithoutReferences[]>;
@Input() moreAnchor: 'start' | 'end' = 'start';
}

View File

@@ -0,0 +1,65 @@
<!--
~ Copyright (C) 2022 StApps
~ This program is free software: you can redistribute it and/or modify it
~ under the terms of the GNU General Public License as published by the Free
~ Software Foundation, version 3.
~
~ This program is distributed in the hope that it will be useful, but WITHOUT
~ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
~ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
~ more details.
~
~ You should have received a copy of the GNU General Public License along with
~ this program. If not, see <https://www.gnu.org/licenses/>.
-->
<ion-breadcrumbs
(ionCollapsedClick)="popover.present($event)"
[maxItems]="maxItems"
[itemsAfterCollapse]="itemsAfterCollapse"
[itemsBeforeCollapse]="itemsBeforeCollapse"
>
<ion-breadcrumb *ngFor="let item of items">
<ion-label
class="crumb-label"
*ngIf="item"
[routerLink]="['/data-detail', item.uid]"
>{{ 'name' | thingTranslate: $any(item) }}</ion-label
>
</ion-breadcrumb>
</ion-breadcrumbs>
<ion-popover #popover>
<ng-template>
<ion-list>
<ng-container *ngIf="moreAnchor === 'start' && more | async as more">
<ng-container
*ngFor="let item of more"
[ngTemplateOutlet]="popoverItem"
[ngTemplateOutletContext]="{item}"
></ng-container>
</ng-container>
<ng-container
*ngFor="let item of items"
[ngTemplateOutlet]="popoverItem"
[ngTemplateOutletContext]="{item}"
></ng-container>
<ng-container *ngIf="moreAnchor === 'end' && more | async as more">
<ng-container
*ngFor="let item of more"
[ngTemplateOutlet]="popoverItem"
[ngTemplateOutletContext]="{item}"
></ng-container>
</ng-container>
</ion-list>
</ng-template>
</ion-popover>
<ng-template #popoverItem let-item="item">
<ion-item
*ngIf="item"
[routerLink]="['/data-detail', item.uid]"
(click)="popover.dismiss()"
>
{{ 'name' | thingTranslate: $any(item) }}
</ion-item>
</ng-template>

View File

@@ -0,0 +1,23 @@
/*!
* Copyright (C) 2022 StApps
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
* Software Foundation, version 3.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <https://www.gnu.org/licenses/>.
*/
ion-breadcrumb:last-child {
overflow: hidden;
flex: 1;
}
.crumb-label {
cursor: pointer;
}