mirror of
https://gitlab.com/openstapps/openstapps.git
synced 2026-01-21 17:12:43 +00:00
feat: expandable accordion in grades module
This commit is contained in:
@@ -1,19 +1,19 @@
|
||||
/*
|
||||
* 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 {Injectable} from '@angular/core';
|
||||
import {SCThings} from '@openstapps/core';
|
||||
import {SCThings, SCThingWithoutReferences} from '@openstapps/core';
|
||||
import {Subject} from 'rxjs';
|
||||
|
||||
/**
|
||||
@@ -28,6 +28,8 @@ export class DataRoutingService {
|
||||
*/
|
||||
private childSelectedEvent = new Subject<SCThings>();
|
||||
|
||||
private pathSelectedEvent = new Subject<SCThingWithoutReferences>();
|
||||
|
||||
/**
|
||||
* Provides the thing that was selected
|
||||
*
|
||||
@@ -37,10 +39,18 @@ export class DataRoutingService {
|
||||
this.childSelectedEvent.next(thing);
|
||||
}
|
||||
|
||||
emitPathEvent(thing: SCThingWithoutReferences) {
|
||||
this.pathSelectedEvent.next(thing);
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides a listener for the event
|
||||
*/
|
||||
itemSelectListener() {
|
||||
return this.childSelectedEvent.asObservable();
|
||||
}
|
||||
|
||||
pathSelectListener() {
|
||||
return this.pathSelectedEvent.asObservable();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -86,6 +86,8 @@ 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';
|
||||
import {TreeListComponent} from './list/tree-list.component';
|
||||
import {TreeListFragmentComponent} from './list/tree-list-fragment.component';
|
||||
|
||||
/**
|
||||
* Module for handling data
|
||||
@@ -140,6 +142,8 @@ import {UtilModule} from '../../util/util.module';
|
||||
SkeletonListItemComponent,
|
||||
SkeletonSegmentComponent,
|
||||
SkeletonSimpleCardComponent,
|
||||
TreeListComponent,
|
||||
TreeListFragmentComponent,
|
||||
VideoDetailContentComponent,
|
||||
VideoListItemComponent,
|
||||
SimpleDataListComponent,
|
||||
@@ -192,6 +196,7 @@ import {UtilModule} from '../../util/util.module';
|
||||
ArticleDetailContentComponent,
|
||||
OriginDetailComponent,
|
||||
FavoriteButtonComponent,
|
||||
TreeListComponent,
|
||||
],
|
||||
})
|
||||
export class DataModule {}
|
||||
|
||||
@@ -61,6 +61,8 @@ export class DataDetailComponent implements ViewWillEnter {
|
||||
|
||||
@Input() isModal = false;
|
||||
|
||||
@Input() autoRouteDataPath = true;
|
||||
|
||||
/**
|
||||
* The language of the item
|
||||
*/
|
||||
|
||||
@@ -46,7 +46,7 @@
|
||||
<div [ngSwitch]="true">
|
||||
<ng-container *ngSwitchCase="!item && (isDisconnected | async)">
|
||||
<div class="centeredMessageContainer">
|
||||
<ion-icon name="no-connection"> </ion-icon>
|
||||
<ion-icon name="no-connection"></ion-icon>
|
||||
<ion-label>
|
||||
{{ 'data.detail.COULD_NOT_CONNECT' | translate }}
|
||||
</ion-label>
|
||||
@@ -54,7 +54,7 @@
|
||||
</ng-container>
|
||||
<ng-container *ngSwitchCase="item === null">
|
||||
<div class="centeredMessageContainer">
|
||||
<ion-icon name="broken-link"> </ion-icon>
|
||||
<ion-icon name="broken-link"></ion-icon>
|
||||
<ion-label>
|
||||
{{ 'data.detail.NOT_FOUND' | translate }}
|
||||
</ion-label>
|
||||
@@ -65,7 +65,10 @@
|
||||
<stapps-skeleton-simple-card></stapps-skeleton-simple-card>
|
||||
</ng-container>
|
||||
<ng-container *ngSwitchDefault>
|
||||
<stapps-data-path [item]="item"></stapps-data-path>
|
||||
<stapps-data-path
|
||||
[item]="item"
|
||||
[autoRouting]="autoRouteDataPath"
|
||||
></stapps-data-path>
|
||||
<stapps-data-detail-content
|
||||
[item]="item"
|
||||
[contentTemplateRef]="contentTemplateRef"
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
* 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 {Component, Input, OnDestroy, OnInit} from '@angular/core';
|
||||
import {RoutingStackService} from '../../../util/routing-stack.service';
|
||||
import {
|
||||
SCCatalog,
|
||||
@@ -21,24 +21,24 @@ import {
|
||||
SCThingWithoutReferences,
|
||||
} from '@openstapps/core';
|
||||
import {DataProvider, DataScope} from '../data.provider';
|
||||
import {fromEvent, Observable} from 'rxjs';
|
||||
import {map} from 'rxjs/operators';
|
||||
import {fromEvent, Observable, Subscription} from 'rxjs';
|
||||
import {map, startWith} from 'rxjs/operators';
|
||||
import {DataRoutingService} from '../data-routing.service';
|
||||
import {NavController} from '@ionic/angular';
|
||||
|
||||
@Component({
|
||||
selector: 'stapps-data-path',
|
||||
templateUrl: './data-path.html',
|
||||
styleUrls: ['./data-path.scss'],
|
||||
})
|
||||
export class DataPathComponent implements OnInit {
|
||||
export class DataPathComponent implements OnInit, OnDestroy {
|
||||
path: Promise<SCThingWithoutReferences[]>;
|
||||
|
||||
$width: Observable<number>;
|
||||
|
||||
ngOnInit() {
|
||||
this.$width = fromEvent(window, 'resize').pipe(
|
||||
map(() => window.innerWidth),
|
||||
);
|
||||
}
|
||||
subscriptions: Subscription[] = [];
|
||||
|
||||
@Input() autoRouting = true;
|
||||
|
||||
@Input() set item(item: SCThings) {
|
||||
// eslint-disable-next-line unicorn/prefer-ternary
|
||||
@@ -47,6 +47,11 @@ export class DataPathComponent implements OnInit {
|
||||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
||||
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]),
|
||||
);
|
||||
} else if (
|
||||
item.type === SCThingType.AcademicEvent &&
|
||||
item.catalogs &&
|
||||
@@ -76,7 +81,27 @@ export class DataPathComponent implements OnInit {
|
||||
}
|
||||
|
||||
constructor(
|
||||
readonly dataRoutingService: DataRoutingService,
|
||||
readonly navController: NavController,
|
||||
readonly routeStack: RoutingStackService,
|
||||
readonly dataProvider: DataProvider,
|
||||
) {}
|
||||
|
||||
ngOnInit() {
|
||||
this.$width = fromEvent(window, 'resize').pipe(
|
||||
map(() => window.innerWidth),
|
||||
startWith(window.innerWidth),
|
||||
);
|
||||
|
||||
if (!this.autoRouting) return;
|
||||
this.subscriptions.push(
|
||||
this.dataRoutingService.pathSelectListener().subscribe(item => {
|
||||
void this.navController.navigateBack(['data-detail', item.uid]);
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
for (const sub of this.subscriptions) sub.unsubscribe();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,8 +22,7 @@
|
||||
>
|
||||
<ion-breadcrumb *ngFor="let fragment of stack">
|
||||
<ion-label
|
||||
[routerLink]="['/data-detail', fragment.uid]"
|
||||
[routerDirection]="'back'"
|
||||
(click)="dataRoutingService.emitPathEvent(fragment)"
|
||||
[style.max-width]="
|
||||
stack.length === 1
|
||||
? '100%'
|
||||
@@ -42,10 +41,11 @@
|
||||
<ng-template>
|
||||
<ion-list>
|
||||
<ion-item
|
||||
button
|
||||
*ngFor="let fragment of stack"
|
||||
(click)="popover.dismiss()"
|
||||
[routerLink]="['/data-detail', fragment.uid]"
|
||||
[routerDirection]="'back'"
|
||||
(click)="
|
||||
dataRoutingService.emitPathEvent(fragment); popover.dismiss()
|
||||
"
|
||||
>{{ 'name' | thingTranslate: $any(fragment) }}</ion-item
|
||||
>
|
||||
</ion-list>
|
||||
|
||||
44
src/app/modules/data/list/tree-list-fragment.component.ts
Normal file
44
src/app/modules/data/list/tree-list-fragment.component.ts
Normal file
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* 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, TemplateRef} from '@angular/core';
|
||||
import {SCThings, SCThingWithoutReferences, SCUuid} from '@openstapps/core';
|
||||
import {Tree} from '../../../_helpers/collections/tree-group';
|
||||
import {DataListContext} from './data-list.component';
|
||||
|
||||
@Component({
|
||||
selector: 'tree-list-fragment',
|
||||
templateUrl: 'tree-list-fragment.html',
|
||||
styleUrls: ['tree-list-fragment.scss'],
|
||||
})
|
||||
export class TreeListFragmentComponent {
|
||||
entries?: [string, Tree<SCThings>][];
|
||||
|
||||
@Input() set items(items: Tree<SCThings> | undefined) {
|
||||
if (!items) {
|
||||
delete this.entries;
|
||||
return;
|
||||
}
|
||||
const temporary = items._;
|
||||
delete items._;
|
||||
this.entries = Object.entries(items) as [string, Tree<SCThings>][];
|
||||
items._ = temporary;
|
||||
}
|
||||
|
||||
@Input() groupMap: Record<SCUuid, SCThingWithoutReferences>;
|
||||
|
||||
@Input() singleType = false;
|
||||
|
||||
@Input() listItemTemplateRef: TemplateRef<DataListContext<SCThings>>;
|
||||
}
|
||||
45
src/app/modules/data/list/tree-list-fragment.html
Normal file
45
src/app/modules/data/list/tree-list-fragment.html
Normal file
@@ -0,0 +1,45 @@
|
||||
<!--
|
||||
~ 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-accordion-group *ngIf="entries as entries" [value]="entries[0]?.[0]">
|
||||
<ion-accordion *ngFor="let entry of entries" [value]="entry[0]">
|
||||
<ion-item *ngIf="groupMap[entry[0]] as header" slot="header">
|
||||
<ion-label>{{ header.name }}</ion-label>
|
||||
</ion-item>
|
||||
<ion-list slot="content">
|
||||
<ng-container *ngFor="let item of entry[1]._ || []">
|
||||
<ng-container
|
||||
*ngTemplateOutlet="
|
||||
listItemTemplateRef || defaultListItem;
|
||||
context: {$implicit: item}
|
||||
"
|
||||
></ng-container>
|
||||
</ng-container>
|
||||
<tree-list-fragment
|
||||
[groupMap]="groupMap"
|
||||
[items]="entry[1]"
|
||||
[singleType]="singleType"
|
||||
[listItemTemplateRef]="listItemTemplateRef"
|
||||
></tree-list-fragment>
|
||||
</ion-list>
|
||||
</ion-accordion>
|
||||
</ion-accordion-group>
|
||||
|
||||
<ng-template let-item #defaultListItem>
|
||||
<stapps-data-list-item
|
||||
[item]="item"
|
||||
[hideThumbnail]="singleType"
|
||||
></stapps-data-list-item>
|
||||
</ng-template>
|
||||
18
src/app/modules/data/list/tree-list-fragment.scss
Normal file
18
src/app/modules/data/list/tree-list-fragment.scss
Normal file
@@ -0,0 +1,18 @@
|
||||
/*!
|
||||
* 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-list {
|
||||
margin-left: 16px;
|
||||
}
|
||||
76
src/app/modules/data/list/tree-list.component.ts
Normal file
76
src/app/modules/data/list/tree-list.component.ts
Normal file
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
* 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, ContentChild, Input, TemplateRef} from '@angular/core';
|
||||
import {DataListContext} from './data-list.component';
|
||||
import {SCThings, SCThingWithoutReferences, SCUuid} from '@openstapps/core';
|
||||
import {Tree, treeGroupBy} from '../../../_helpers/collections/tree-group';
|
||||
|
||||
@Component({
|
||||
selector: 'tree-list',
|
||||
templateUrl: 'tree-list.html',
|
||||
styleUrls: ['tree-list.scss'],
|
||||
})
|
||||
export class TreeListComponent {
|
||||
_items?: Promise<SCThings[] | undefined>;
|
||||
|
||||
_groupingKey?: string;
|
||||
|
||||
_groups?: Promise<Tree<SCThings> | undefined>;
|
||||
|
||||
_groupItems?: Record<SCUuid, SCThingWithoutReferences>;
|
||||
|
||||
@Input() set groupingKey(value: keyof SCThings | string | undefined) {
|
||||
this._groupingKey = value;
|
||||
this.groupItems();
|
||||
}
|
||||
|
||||
@Input() set items(items: Promise<SCThings[] | undefined> | undefined) {
|
||||
this._items = items;
|
||||
this.groupItems();
|
||||
}
|
||||
|
||||
@Input() singleType = false;
|
||||
|
||||
@ContentChild(TemplateRef) listItemTemplateRef: TemplateRef<
|
||||
DataListContext<SCThings>
|
||||
>;
|
||||
|
||||
groupItems() {
|
||||
if (!this._items || !this._groupingKey) return;
|
||||
|
||||
this._groups = this._items.then(items => {
|
||||
if (!items || !this._groupingKey) return;
|
||||
|
||||
this._groupItems = {};
|
||||
for (const item of items) {
|
||||
const path = (
|
||||
item as unknown as Record<string, SCThingWithoutReferences[]>
|
||||
)[this._groupingKey];
|
||||
|
||||
for (const pathFragment of path) {
|
||||
this._groupItems[pathFragment.uid] = pathFragment;
|
||||
}
|
||||
}
|
||||
|
||||
const tree = treeGroupBy(items, item =>
|
||||
(item as unknown as Record<string, SCThingWithoutReferences[]>)[
|
||||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
||||
this._groupingKey!
|
||||
].map(thing => thing.uid),
|
||||
);
|
||||
return tree;
|
||||
});
|
||||
}
|
||||
}
|
||||
22
src/app/modules/data/list/tree-list.html
Normal file
22
src/app/modules/data/list/tree-list.html
Normal file
@@ -0,0 +1,22 @@
|
||||
<!--
|
||||
~ 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/>.
|
||||
-->
|
||||
|
||||
<tree-list-fragment
|
||||
*ngIf="_groups | async as groups"
|
||||
[items]="groups"
|
||||
[groupMap]="_groupItems"
|
||||
[singleType]="singleType"
|
||||
[listItemTemplateRef]="listItemTemplateRef"
|
||||
></tree-list-fragment>
|
||||
15
src/app/modules/data/list/tree-list.scss
Normal file
15
src/app/modules/data/list/tree-list.scss
Normal file
@@ -0,0 +1,15 @@
|
||||
/*!
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user