@sumaris-net/ngx-components 2.4.142 → 2.4.144
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/esm2020/src/app/admin/users/users.mjs +17 -27
- package/esm2020/src/app/core/menu/menu.component.mjs +7 -55
- package/esm2020/src/app/core/menu/menu.model.mjs +33 -13
- package/esm2020/src/app/core/menu/menu.service.mjs +191 -50
- package/esm2020/src/app/core/services/model/tree-item-entity.model.mjs +6 -4
- package/esm2020/src/environments/environment.mjs +5 -5
- package/fesm2015/sumaris-net.ngx-components.mjs +313 -212
- package/fesm2015/sumaris-net.ngx-components.mjs.map +1 -1
- package/fesm2020/sumaris-net.ngx-components.mjs +301 -201
- package/fesm2020/sumaris-net.ngx-components.mjs.map +1 -1
- package/package.json +1 -1
- package/src/app/core/menu/menu.component.d.ts +2 -4
- package/src/app/core/menu/menu.model.d.ts +21 -8
- package/src/app/core/menu/menu.service.d.ts +14 -4
- package/src/app/core/services/model/tree-item-entity.model.d.ts +1 -1
- package/src/assets/i18n/fr.json +1 -0
|
@@ -11546,10 +11546,12 @@ class TreeItemEntityUtils {
|
|
|
11546
11546
|
if (isEmptyArray(node.children))
|
|
11547
11547
|
return []; // Skip
|
|
11548
11548
|
// Delete children
|
|
11549
|
-
const
|
|
11550
|
-
node.children = node.children.filter((c) => !
|
|
11549
|
+
const deletedChildren = node.children.filter(filterFn);
|
|
11550
|
+
node.children = node.children.filter((c) => !deletedChildren.includes(c));
|
|
11551
|
+
// TODO: add an options to clean the parent
|
|
11552
|
+
//deletedChildren.forEach(child => child.parent = null);
|
|
11551
11553
|
// Recursive call, in still existing children
|
|
11552
|
-
return node.children.reduce((res, c) => res.concat(...this.deleteRecursively(c, filterFn)),
|
|
11554
|
+
return node.children.reduce((res, c) => res.concat(...this.deleteRecursively(c, filterFn)), deletedChildren);
|
|
11553
11555
|
}
|
|
11554
11556
|
/**
|
|
11555
11557
|
* Visit each node, from root to leaf
|
|
@@ -11920,10 +11922,10 @@ const environment = Object.freeze({
|
|
|
11920
11922
|
helpUrl: 'https://gitlab.ifremer.fr/sih-public/sumaris/sumaris-doc/-/blob/master/user-manual/index_fr.md',
|
|
11921
11923
|
// Development
|
|
11922
11924
|
defaultAuthValues: {
|
|
11923
|
-
|
|
11924
|
-
|
|
11925
|
-
|
|
11926
|
-
|
|
11925
|
+
// Basic auth (using Person.username)
|
|
11926
|
+
// username: 'admq2', password: 'q22006'
|
|
11927
|
+
// Token auth (using Person.pubkey)
|
|
11928
|
+
//username: 'admin@sumaris.net', password: 'admin',
|
|
11927
11929
|
},
|
|
11928
11930
|
account: {
|
|
11929
11931
|
enableListenChanges: true,
|
|
@@ -22800,80 +22802,15 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
|
|
|
22800
22802
|
args: [{ providedIn: 'root' }]
|
|
22801
22803
|
}] });
|
|
22802
22804
|
|
|
22803
|
-
const APP_ABOUT_DEVELOPERS = new InjectionToken('aboutDevelopers');
|
|
22804
|
-
const APP_ABOUT_PARTNERS = new InjectionToken('aboutPartners');
|
|
22805
|
-
class AboutModal {
|
|
22806
|
-
constructor(translate, modalController, configService, environment, developers, partners) {
|
|
22807
|
-
this.translate = translate;
|
|
22808
|
-
this.modalController = modalController;
|
|
22809
|
-
this.configService = configService;
|
|
22810
|
-
this.environment = environment;
|
|
22811
|
-
this.developers = developers;
|
|
22812
|
-
this.partners = partners;
|
|
22813
|
-
this._subscription = new Subscription();
|
|
22814
|
-
this.name = translate.instant('APP_NAME');
|
|
22815
|
-
if (this.name === 'APP_NAME') {
|
|
22816
|
-
// Not translated: use name from the environnement
|
|
22817
|
-
this.name = environment && environment.name && capitalizeFirstLetter(environment.name) || undefined;
|
|
22818
|
-
}
|
|
22819
|
-
this.version = environment && environment.version;
|
|
22820
|
-
this.sourceUrl = environment && environment.sourceUrl;
|
|
22821
|
-
this.reportIssueUrl = environment && environment.reportIssueUrl;
|
|
22822
|
-
this.forumUrl = environment && environment.forumUrl;
|
|
22823
|
-
this.helpUrl = environment && environment.helpUrl;
|
|
22824
|
-
this.config$ = configService.config;
|
|
22825
|
-
this._subscription.add(this.config$.subscribe(config => this.setConfig(config)));
|
|
22826
|
-
}
|
|
22827
|
-
ngOnDestroy() {
|
|
22828
|
-
this._subscription.unsubscribe();
|
|
22829
|
-
}
|
|
22830
|
-
async close() {
|
|
22831
|
-
await this.modalController.dismiss();
|
|
22832
|
-
}
|
|
22833
|
-
/* -- protected functions -- */
|
|
22834
|
-
setConfig(config) {
|
|
22835
|
-
this.forumUrl = config?.getProperty(CORE_CONFIG_OPTIONS.FORUM_URL) || this.environment.forumUrl;
|
|
22836
|
-
this.helpUrl = config?.getProperty(CORE_CONFIG_OPTIONS.HELP_URL) || this.environment.helpUrl;
|
|
22837
|
-
}
|
|
22838
|
-
}
|
|
22839
|
-
AboutModal.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: AboutModal, deps: [{ token: i1$1.TranslateService }, { token: i2.ModalController }, { token: ConfigService }, { token: ENVIRONMENT, optional: true }, { token: APP_ABOUT_DEVELOPERS, optional: true }, { token: APP_ABOUT_PARTNERS, optional: true }], target: i0.ɵɵFactoryTarget.Component });
|
|
22840
|
-
AboutModal.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: AboutModal, selector: "app-about-modal", ngImport: i0, template: "<ion-header>\n <ion-toolbar color=\"light\">\n\n <ion-title>\n {{'ABOUT.TITLE'|translate}}\n </ion-title>\n\n <ion-buttons slot=\"end\">\n <ion-button (click)=\"close()\" visible-xs visible-sm visible-mobile>\n {{'COMMON.BTN_CLOSE'|translate}}\n </ion-button>\n </ion-buttons>\n </ion-toolbar>\n</ion-header>\n\n<ion-content class=\"ion-padding\">\n\n <ion-list lines=\"none\">\n\n <!-- Peer info -->\n <ion-item *ngIf=\"config$ | async; let config\">\n <span slot=\"start\"> </span>\n <ion-label class=\"ion-text-wrap\" >\n <h2>\n <b>{{config.label}}</b> - <span [innerHTML]=\"config.name\"></span>\n </h2>\n <p *ngIf=\"config.description\">\n <markdown [data]=\"config.description\"\n emoji>\n </markdown>\n </p>\n </ion-label>\n </ion-item>\n\n <!-- Version info -->\n <ion-item>\n <span slot=\"start\"> </span>\n <ion-label class=\"ion-text-wrap\">\n <h2>\n <small *ngIf=\"name\">{{'ABOUT.POWERED_BY'|translate}}</small> {{name}}\n <span *ngIf=\"version\" [innerHTML]=\"'ABOUT.VERSION'| translate: {version: version}\"></span>\n </h2>\n <p [innerHTML]=\"'ABOUT.LICENSE'| translate\"></p>\n </ion-label>\n </ion-item>\n\n <!-- Help -->\n <ion-item *ngIf=\"forumUrl || helpUrl\">\n <mat-icon slot=\"start\">help_outline</mat-icon>\n <ion-label>\n <p>\n {{'ABOUT.HELP'|translate}}\n </p>\n <p>\n <ion-button fill=\"solid\" color=\"accent\" href=\"{{helpUrl}}\" target=\"help\" size=\"default\">\n <mat-icon slot=\"start\">description</mat-icon>\n <ion-text translate>ABOUT.USER_MANUAL</ion-text>\n </ion-button>\n <ion-button fill=\"solid\" color=\"secondary\" href=\"{{forumUrl}}\" target=\"forum\" size=\"default\">\n <ion-icon slot=\"start\" name=\"chatbubbles\"></ion-icon>\n <ion-text translate>ABOUT.FORUM</ion-text>\n </ion-button>\n </p>\n </ion-label>\n </ion-item>\n\n <!-- Report issue -->\n <ion-item *ngIf=\"reportIssueUrl\">\n <ion-icon slot=\"start\" name=\"bug\" color=\"dark\"></ion-icon>\n <ion-label>\n <p>\n {{'ABOUT.REPORT_ISSUE'|translate}}\n </p>\n <p>\n <a color=\"primary\" href=\"{{reportIssueUrl}}\" target=\"_system\" translate>ABOUT.BTN_REPORT_ISSUE</a>\n </p>\n </ion-label>\n </ion-item>\n\n\n <!-- Source code -->\n <ion-item *ngIf=\"sourceUrl\">\n <ion-icon slot=\"start\" name=\"code\" color=\"dark\"></ion-icon>\n <ion-label>\n <p>\n {{'ABOUT.SOURCE_CODE'|translate}}\n </p>\n <p>\n <a color=\"primary\" href=\"{{sourceUrl}}\" target=\"_system\">{{sourceUrl}}</a>\n </p>\n </ion-label>\n </ion-item>\n\n <!-- Developers -->\n <ion-item *ngIf=\"developers | isNotEmptyArray\">\n <ion-icon slot=\"start\" name=\"people\" color=\"dark\"></ion-icon>\n <ion-label>\n <p>\n {{'ABOUT.DEVELOPED_BY'|translate}}\n </p>\n <ion-list lines=\"none\">\n <ion-item *ngFor=\"let item of developers\"\n class=\"ion-no-padding\">\n <img slot=\"end\" src=\"{{item.logo}}\">\n <ion-label>\n <p>\n <a color=\"primary\" href=\"{{item.siteUrl}}\" target=\"_system\">{{item.name||item.label}}</a>\n </p>\n </ion-label>\n </ion-item>\n </ion-list>\n </ion-label>\n </ion-item>\n\n <!-- Partners -->\n <ion-item class=\"item-partners\" *ngIf=\"partners | isNotEmptyArray\">\n <ion-icon slot=\"start\" name=\"megaphone\" color=\"dark\"></ion-icon>\n <ion-text>\n <p>{{'ABOUT.PARTNERS'|translate}}</p>\n <p>\n <a *ngFor=\"let item of partners\" href=\"{{item.siteUrl}}\" class=\"partners\" target=\"_system\">\n <img src=\"{{item.logo}}\">\n </a>\n </p>\n </ion-text>\n </ion-item>\n </ion-list>\n\n</ion-content>\n\n<ion-footer hidden-xs hidden-sm hidden-mobile>\n <ion-toolbar>\n <ion-row class=\"ion-no-padding\" nowrap>\n <ion-col></ion-col>\n <ion-col size=\"auto\">\n <ion-button fill=\"solid\" color=\"tertiary\" (click)=\"close()\">{{'COMMON.BTN_CLOSE'|translate}}</ion-button>\n </ion-col>\n </ion-row>\n </ion-toolbar>\n</ion-footer>\n", styles: [".item-partners ion-text{height:auto}.item-partners ion-text p:last-child{display:flex;flex-wrap:wrap;flex-direction:row;justify-content:space-between}.item-partners ion-text p:last-child a{padding:2px}.item-partners ion-text p:last-child a img{text-align:center;display:inline-block;max-height:40px}\n"], dependencies: [{ kind: "directive", type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i2.IonButton, selector: "ion-button", inputs: ["buttonType", "color", "disabled", "download", "expand", "fill", "form", "href", "mode", "rel", "routerAnimation", "routerDirection", "shape", "size", "strong", "target", "type"] }, { kind: "component", type: i2.IonButtons, selector: "ion-buttons", inputs: ["collapse"] }, { kind: "component", type: i2.IonCol, selector: "ion-col", inputs: ["offset", "offsetLg", "offsetMd", "offsetSm", "offsetXl", "offsetXs", "pull", "pullLg", "pullMd", "pullSm", "pullXl", "pullXs", "push", "pushLg", "pushMd", "pushSm", "pushXl", "pushXs", "size", "sizeLg", "sizeMd", "sizeSm", "sizeXl", "sizeXs"] }, { kind: "component", type: i2.IonContent, selector: "ion-content", inputs: ["color", "forceOverscroll", "fullscreen", "scrollEvents", "scrollX", "scrollY"] }, { kind: "component", type: i2.IonFooter, selector: "ion-footer", inputs: ["collapse", "mode", "translucent"] }, { kind: "component", type: i2.IonHeader, selector: "ion-header", inputs: ["collapse", "mode", "translucent"] }, { kind: "component", type: i2.IonIcon, selector: "ion-icon", inputs: ["color", "flipRtl", "icon", "ios", "lazy", "md", "mode", "name", "sanitize", "size", "src"] }, { kind: "component", type: i2.IonItem, selector: "ion-item", inputs: ["button", "color", "counter", "counterFormatter", "detail", "detailIcon", "disabled", "download", "fill", "href", "lines", "mode", "rel", "routerAnimation", "routerDirection", "shape", "target", "type"] }, { kind: "component", type: i2.IonLabel, selector: "ion-label", inputs: ["color", "mode", "position"] }, { kind: "component", type: i2.IonList, selector: "ion-list", inputs: ["inset", "lines", "mode"] }, { kind: "component", type: i2.IonRow, selector: "ion-row" }, { kind: "component", type: i2.IonText, selector: "ion-text", inputs: ["color", "mode"] }, { kind: "component", type: i2.IonTitle, selector: "ion-title", inputs: ["color", "size"] }, { kind: "component", type: i2.IonToolbar, selector: "ion-toolbar", inputs: ["color", "mode"] }, { kind: "directive", type: i1$1.TranslateDirective, selector: "[translate],[ngx-translate]", inputs: ["translate", "translateParams"] }, { kind: "component", type: i6$4.MarkdownComponent, selector: "markdown, [markdown]", inputs: ["data", "src", "inline", "clipboard", "clipboardButtonComponent", "clipboardButtonTemplate", "emoji", "katex", "katexOptions", "mermaid", "mermaidOptions", "lineHighlight", "line", "lineOffset", "lineNumbers", "start", "commandLine", "filterOutput", "host", "prompt", "output", "user"], outputs: ["error", "load", "ready"] }, { kind: "component", type: i8.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "pipe", type: i3.AsyncPipe, name: "async" }, { kind: "pipe", type: i1$1.TranslatePipe, name: "translate" }, { kind: "pipe", type: NotEmptyArrayPipe, name: "isNotEmptyArray" }] });
|
|
22841
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: AboutModal, decorators: [{
|
|
22842
|
-
type: Component,
|
|
22843
|
-
args: [{ selector: 'app-about-modal', template: "<ion-header>\n <ion-toolbar color=\"light\">\n\n <ion-title>\n {{'ABOUT.TITLE'|translate}}\n </ion-title>\n\n <ion-buttons slot=\"end\">\n <ion-button (click)=\"close()\" visible-xs visible-sm visible-mobile>\n {{'COMMON.BTN_CLOSE'|translate}}\n </ion-button>\n </ion-buttons>\n </ion-toolbar>\n</ion-header>\n\n<ion-content class=\"ion-padding\">\n\n <ion-list lines=\"none\">\n\n <!-- Peer info -->\n <ion-item *ngIf=\"config$ | async; let config\">\n <span slot=\"start\"> </span>\n <ion-label class=\"ion-text-wrap\" >\n <h2>\n <b>{{config.label}}</b> - <span [innerHTML]=\"config.name\"></span>\n </h2>\n <p *ngIf=\"config.description\">\n <markdown [data]=\"config.description\"\n emoji>\n </markdown>\n </p>\n </ion-label>\n </ion-item>\n\n <!-- Version info -->\n <ion-item>\n <span slot=\"start\"> </span>\n <ion-label class=\"ion-text-wrap\">\n <h2>\n <small *ngIf=\"name\">{{'ABOUT.POWERED_BY'|translate}}</small> {{name}}\n <span *ngIf=\"version\" [innerHTML]=\"'ABOUT.VERSION'| translate: {version: version}\"></span>\n </h2>\n <p [innerHTML]=\"'ABOUT.LICENSE'| translate\"></p>\n </ion-label>\n </ion-item>\n\n <!-- Help -->\n <ion-item *ngIf=\"forumUrl || helpUrl\">\n <mat-icon slot=\"start\">help_outline</mat-icon>\n <ion-label>\n <p>\n {{'ABOUT.HELP'|translate}}\n </p>\n <p>\n <ion-button fill=\"solid\" color=\"accent\" href=\"{{helpUrl}}\" target=\"help\" size=\"default\">\n <mat-icon slot=\"start\">description</mat-icon>\n <ion-text translate>ABOUT.USER_MANUAL</ion-text>\n </ion-button>\n <ion-button fill=\"solid\" color=\"secondary\" href=\"{{forumUrl}}\" target=\"forum\" size=\"default\">\n <ion-icon slot=\"start\" name=\"chatbubbles\"></ion-icon>\n <ion-text translate>ABOUT.FORUM</ion-text>\n </ion-button>\n </p>\n </ion-label>\n </ion-item>\n\n <!-- Report issue -->\n <ion-item *ngIf=\"reportIssueUrl\">\n <ion-icon slot=\"start\" name=\"bug\" color=\"dark\"></ion-icon>\n <ion-label>\n <p>\n {{'ABOUT.REPORT_ISSUE'|translate}}\n </p>\n <p>\n <a color=\"primary\" href=\"{{reportIssueUrl}}\" target=\"_system\" translate>ABOUT.BTN_REPORT_ISSUE</a>\n </p>\n </ion-label>\n </ion-item>\n\n\n <!-- Source code -->\n <ion-item *ngIf=\"sourceUrl\">\n <ion-icon slot=\"start\" name=\"code\" color=\"dark\"></ion-icon>\n <ion-label>\n <p>\n {{'ABOUT.SOURCE_CODE'|translate}}\n </p>\n <p>\n <a color=\"primary\" href=\"{{sourceUrl}}\" target=\"_system\">{{sourceUrl}}</a>\n </p>\n </ion-label>\n </ion-item>\n\n <!-- Developers -->\n <ion-item *ngIf=\"developers | isNotEmptyArray\">\n <ion-icon slot=\"start\" name=\"people\" color=\"dark\"></ion-icon>\n <ion-label>\n <p>\n {{'ABOUT.DEVELOPED_BY'|translate}}\n </p>\n <ion-list lines=\"none\">\n <ion-item *ngFor=\"let item of developers\"\n class=\"ion-no-padding\">\n <img slot=\"end\" src=\"{{item.logo}}\">\n <ion-label>\n <p>\n <a color=\"primary\" href=\"{{item.siteUrl}}\" target=\"_system\">{{item.name||item.label}}</a>\n </p>\n </ion-label>\n </ion-item>\n </ion-list>\n </ion-label>\n </ion-item>\n\n <!-- Partners -->\n <ion-item class=\"item-partners\" *ngIf=\"partners | isNotEmptyArray\">\n <ion-icon slot=\"start\" name=\"megaphone\" color=\"dark\"></ion-icon>\n <ion-text>\n <p>{{'ABOUT.PARTNERS'|translate}}</p>\n <p>\n <a *ngFor=\"let item of partners\" href=\"{{item.siteUrl}}\" class=\"partners\" target=\"_system\">\n <img src=\"{{item.logo}}\">\n </a>\n </p>\n </ion-text>\n </ion-item>\n </ion-list>\n\n</ion-content>\n\n<ion-footer hidden-xs hidden-sm hidden-mobile>\n <ion-toolbar>\n <ion-row class=\"ion-no-padding\" nowrap>\n <ion-col></ion-col>\n <ion-col size=\"auto\">\n <ion-button fill=\"solid\" color=\"tertiary\" (click)=\"close()\">{{'COMMON.BTN_CLOSE'|translate}}</ion-button>\n </ion-col>\n </ion-row>\n </ion-toolbar>\n</ion-footer>\n", styles: [".item-partners ion-text{height:auto}.item-partners ion-text p:last-child{display:flex;flex-wrap:wrap;flex-direction:row;justify-content:space-between}.item-partners ion-text p:last-child a{padding:2px}.item-partners ion-text p:last-child a img{text-align:center;display:inline-block;max-height:40px}\n"] }]
|
|
22844
|
-
}], ctorParameters: function () { return [{ type: i1$1.TranslateService }, { type: i2.ModalController }, { type: ConfigService }, { type: undefined, decorators: [{
|
|
22845
|
-
type: Optional
|
|
22846
|
-
}, {
|
|
22847
|
-
type: Inject,
|
|
22848
|
-
args: [ENVIRONMENT]
|
|
22849
|
-
}] }, { type: undefined, decorators: [{
|
|
22850
|
-
type: Optional
|
|
22851
|
-
}, {
|
|
22852
|
-
type: Inject,
|
|
22853
|
-
args: [APP_ABOUT_DEVELOPERS]
|
|
22854
|
-
}] }, { type: undefined, decorators: [{
|
|
22855
|
-
type: Optional
|
|
22856
|
-
}, {
|
|
22857
|
-
type: Inject,
|
|
22858
|
-
args: [APP_ABOUT_PARTNERS]
|
|
22859
|
-
}] }]; } });
|
|
22860
|
-
|
|
22861
22805
|
var _a;
|
|
22862
|
-
|
|
22806
|
+
var MenuItem_1;
|
|
22807
|
+
// @dynamic
|
|
22808
|
+
let MenuItem = MenuItem_1 = class MenuItem extends Entity {
|
|
22863
22809
|
constructor() {
|
|
22864
22810
|
super(...arguments);
|
|
22865
22811
|
this.$children = new BehaviorSubject([]);
|
|
22866
22812
|
this.$title = new BehaviorSubject(undefined);
|
|
22867
22813
|
}
|
|
22868
|
-
static fromObject(source, opts) {
|
|
22869
|
-
if (!source)
|
|
22870
|
-
return null;
|
|
22871
|
-
if (source instanceof MenuItem)
|
|
22872
|
-
return source;
|
|
22873
|
-
const target = new MenuItem();
|
|
22874
|
-
target.fromObject(source, opts);
|
|
22875
|
-
return target;
|
|
22876
|
-
}
|
|
22877
22814
|
fromObject(source, opts) {
|
|
22878
22815
|
this.id = source.id;
|
|
22879
22816
|
this.title = source.title;
|
|
@@ -22900,12 +22837,13 @@ class MenuItem extends Entity {
|
|
|
22900
22837
|
this.cssClass = source.cssClass;
|
|
22901
22838
|
this.ifProperty = source.ifProperty;
|
|
22902
22839
|
this.pinned = toBoolean(source.pinned, false);
|
|
22840
|
+
this.static = isNotNil(source.static) ? source.static : undefined; // If undefined, will be set by service
|
|
22903
22841
|
// Icon
|
|
22904
22842
|
this.icon = source.icon;
|
|
22905
22843
|
this.matIcon = source.matIcon;
|
|
22906
22844
|
this.matSvgIcon = source.matSvgIcon;
|
|
22907
22845
|
if (!opts || opts.withChildren === false) {
|
|
22908
|
-
this.children = (source.children || []).map((json) =>
|
|
22846
|
+
this.children = (source.children || []).map((json) => MenuItem_1.fromObject(json, opts)) || [];
|
|
22909
22847
|
}
|
|
22910
22848
|
}
|
|
22911
22849
|
asObject(opts) {
|
|
@@ -22947,6 +22885,12 @@ class MenuItem extends Entity {
|
|
|
22947
22885
|
get detached() {
|
|
22948
22886
|
return !this.parentPath || !this.parent;
|
|
22949
22887
|
}
|
|
22888
|
+
get visible() {
|
|
22889
|
+
return this.static || !this.detached;
|
|
22890
|
+
}
|
|
22891
|
+
get expanded() {
|
|
22892
|
+
return this.action !== 'expand' || this.matIcon === 'expand_less';
|
|
22893
|
+
}
|
|
22950
22894
|
get ancestor() {
|
|
22951
22895
|
if (!this.parent)
|
|
22952
22896
|
return null; // root = not ancestor
|
|
@@ -22954,12 +22898,21 @@ class MenuItem extends Entity {
|
|
|
22954
22898
|
return this; // first sub menu = ancestor
|
|
22955
22899
|
return this.parent?.ancestor; // loop
|
|
22956
22900
|
}
|
|
22901
|
+
get divider() {
|
|
22902
|
+
return !this.action && !this.path;
|
|
22903
|
+
}
|
|
22904
|
+
get pinnable() {
|
|
22905
|
+
return !this.static && (typeof this.action !== 'function');
|
|
22906
|
+
}
|
|
22957
22907
|
isPinned() {
|
|
22958
22908
|
if (this.pinned)
|
|
22959
22909
|
return true;
|
|
22960
22910
|
return (this.children || []).some(child => child.isPinned());
|
|
22961
22911
|
}
|
|
22962
|
-
}
|
|
22912
|
+
};
|
|
22913
|
+
MenuItem = MenuItem_1 = __decorate([
|
|
22914
|
+
EntityClass({ typename: 'MenuItemVO' })
|
|
22915
|
+
], MenuItem);
|
|
22963
22916
|
class MenuItems {
|
|
22964
22917
|
/**
|
|
22965
22918
|
* Compare, without checking the children
|
|
@@ -23041,11 +22994,16 @@ class MenuItems {
|
|
|
23041
22994
|
static checkIfSubMenuVisible(item, currentPathParam) {
|
|
23042
22995
|
if (!item.parentPath)
|
|
23043
22996
|
return false; // Should have a parent
|
|
22997
|
+
if (item.static)
|
|
22998
|
+
return true; // Always keep static items
|
|
23044
22999
|
if (item.isPinned())
|
|
23045
23000
|
return true; // Always keep pinned items
|
|
23046
23001
|
// Keep each menu items in the scope of the current url path
|
|
23047
23002
|
if (currentPathParam?.path.startsWith(item.path))
|
|
23048
23003
|
return true;
|
|
23004
|
+
// Keep if parent is an expanded item
|
|
23005
|
+
if (item.parent?.action === 'expand' && item.parent.expanded)
|
|
23006
|
+
return true;
|
|
23049
23007
|
// Not visible
|
|
23050
23008
|
return false;
|
|
23051
23009
|
}
|
|
@@ -23078,19 +23036,84 @@ class MenuItems {
|
|
|
23078
23036
|
}
|
|
23079
23037
|
_a = MenuItems;
|
|
23080
23038
|
MenuItems.sortByTabOrId = _a.sortByParamOrIdComparator('tab');
|
|
23039
|
+
/**
|
|
23040
|
+
* Options to configure specific behavior on projects
|
|
23041
|
+
*/
|
|
23081
23042
|
class MenuOptions {
|
|
23082
23043
|
}
|
|
23083
23044
|
|
|
23045
|
+
const APP_ABOUT_DEVELOPERS = new InjectionToken('aboutDevelopers');
|
|
23046
|
+
const APP_ABOUT_PARTNERS = new InjectionToken('aboutPartners');
|
|
23047
|
+
class AboutModal {
|
|
23048
|
+
constructor(translate, modalController, configService, environment, developers, partners) {
|
|
23049
|
+
this.translate = translate;
|
|
23050
|
+
this.modalController = modalController;
|
|
23051
|
+
this.configService = configService;
|
|
23052
|
+
this.environment = environment;
|
|
23053
|
+
this.developers = developers;
|
|
23054
|
+
this.partners = partners;
|
|
23055
|
+
this._subscription = new Subscription();
|
|
23056
|
+
this.name = translate.instant('APP_NAME');
|
|
23057
|
+
if (this.name === 'APP_NAME') {
|
|
23058
|
+
// Not translated: use name from the environnement
|
|
23059
|
+
this.name = environment && environment.name && capitalizeFirstLetter(environment.name) || undefined;
|
|
23060
|
+
}
|
|
23061
|
+
this.version = environment && environment.version;
|
|
23062
|
+
this.sourceUrl = environment && environment.sourceUrl;
|
|
23063
|
+
this.reportIssueUrl = environment && environment.reportIssueUrl;
|
|
23064
|
+
this.forumUrl = environment && environment.forumUrl;
|
|
23065
|
+
this.helpUrl = environment && environment.helpUrl;
|
|
23066
|
+
this.config$ = configService.config;
|
|
23067
|
+
this._subscription.add(this.config$.subscribe(config => this.setConfig(config)));
|
|
23068
|
+
}
|
|
23069
|
+
ngOnDestroy() {
|
|
23070
|
+
this._subscription.unsubscribe();
|
|
23071
|
+
}
|
|
23072
|
+
async close() {
|
|
23073
|
+
await this.modalController.dismiss();
|
|
23074
|
+
}
|
|
23075
|
+
/* -- protected functions -- */
|
|
23076
|
+
setConfig(config) {
|
|
23077
|
+
this.forumUrl = config?.getProperty(CORE_CONFIG_OPTIONS.FORUM_URL) || this.environment.forumUrl;
|
|
23078
|
+
this.helpUrl = config?.getProperty(CORE_CONFIG_OPTIONS.HELP_URL) || this.environment.helpUrl;
|
|
23079
|
+
}
|
|
23080
|
+
}
|
|
23081
|
+
AboutModal.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: AboutModal, deps: [{ token: i1$1.TranslateService }, { token: i2.ModalController }, { token: ConfigService }, { token: ENVIRONMENT, optional: true }, { token: APP_ABOUT_DEVELOPERS, optional: true }, { token: APP_ABOUT_PARTNERS, optional: true }], target: i0.ɵɵFactoryTarget.Component });
|
|
23082
|
+
AboutModal.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: AboutModal, selector: "app-about-modal", ngImport: i0, template: "<ion-header>\n <ion-toolbar color=\"light\">\n\n <ion-title>\n {{'ABOUT.TITLE'|translate}}\n </ion-title>\n\n <ion-buttons slot=\"end\">\n <ion-button (click)=\"close()\" visible-xs visible-sm visible-mobile>\n {{'COMMON.BTN_CLOSE'|translate}}\n </ion-button>\n </ion-buttons>\n </ion-toolbar>\n</ion-header>\n\n<ion-content class=\"ion-padding\">\n\n <ion-list lines=\"none\">\n\n <!-- Peer info -->\n <ion-item *ngIf=\"config$ | async; let config\">\n <span slot=\"start\"> </span>\n <ion-label class=\"ion-text-wrap\" >\n <h2>\n <b>{{config.label}}</b> - <span [innerHTML]=\"config.name\"></span>\n </h2>\n <p *ngIf=\"config.description\">\n <markdown [data]=\"config.description\"\n emoji>\n </markdown>\n </p>\n </ion-label>\n </ion-item>\n\n <!-- Version info -->\n <ion-item>\n <span slot=\"start\"> </span>\n <ion-label class=\"ion-text-wrap\">\n <h2>\n <small *ngIf=\"name\">{{'ABOUT.POWERED_BY'|translate}}</small> {{name}}\n <span *ngIf=\"version\" [innerHTML]=\"'ABOUT.VERSION'| translate: {version: version}\"></span>\n </h2>\n <p [innerHTML]=\"'ABOUT.LICENSE'| translate\"></p>\n </ion-label>\n </ion-item>\n\n <!-- Help -->\n <ion-item *ngIf=\"forumUrl || helpUrl\">\n <mat-icon slot=\"start\">help_outline</mat-icon>\n <ion-label>\n <p>\n {{'ABOUT.HELP'|translate}}\n </p>\n <p>\n <ion-button fill=\"solid\" color=\"accent\" href=\"{{helpUrl}}\" target=\"help\" size=\"default\">\n <mat-icon slot=\"start\">description</mat-icon>\n <ion-text translate>ABOUT.USER_MANUAL</ion-text>\n </ion-button>\n <ion-button fill=\"solid\" color=\"secondary\" href=\"{{forumUrl}}\" target=\"forum\" size=\"default\">\n <ion-icon slot=\"start\" name=\"chatbubbles\"></ion-icon>\n <ion-text translate>ABOUT.FORUM</ion-text>\n </ion-button>\n </p>\n </ion-label>\n </ion-item>\n\n <!-- Report issue -->\n <ion-item *ngIf=\"reportIssueUrl\">\n <ion-icon slot=\"start\" name=\"bug\" color=\"dark\"></ion-icon>\n <ion-label>\n <p>\n {{'ABOUT.REPORT_ISSUE'|translate}}\n </p>\n <p>\n <a color=\"primary\" href=\"{{reportIssueUrl}}\" target=\"_system\" translate>ABOUT.BTN_REPORT_ISSUE</a>\n </p>\n </ion-label>\n </ion-item>\n\n\n <!-- Source code -->\n <ion-item *ngIf=\"sourceUrl\">\n <ion-icon slot=\"start\" name=\"code\" color=\"dark\"></ion-icon>\n <ion-label>\n <p>\n {{'ABOUT.SOURCE_CODE'|translate}}\n </p>\n <p>\n <a color=\"primary\" href=\"{{sourceUrl}}\" target=\"_system\">{{sourceUrl}}</a>\n </p>\n </ion-label>\n </ion-item>\n\n <!-- Developers -->\n <ion-item *ngIf=\"developers | isNotEmptyArray\">\n <ion-icon slot=\"start\" name=\"people\" color=\"dark\"></ion-icon>\n <ion-label>\n <p>\n {{'ABOUT.DEVELOPED_BY'|translate}}\n </p>\n <ion-list lines=\"none\">\n <ion-item *ngFor=\"let item of developers\"\n class=\"ion-no-padding\">\n <img slot=\"end\" src=\"{{item.logo}}\">\n <ion-label>\n <p>\n <a color=\"primary\" href=\"{{item.siteUrl}}\" target=\"_system\">{{item.name||item.label}}</a>\n </p>\n </ion-label>\n </ion-item>\n </ion-list>\n </ion-label>\n </ion-item>\n\n <!-- Partners -->\n <ion-item class=\"item-partners\" *ngIf=\"partners | isNotEmptyArray\">\n <ion-icon slot=\"start\" name=\"megaphone\" color=\"dark\"></ion-icon>\n <ion-text>\n <p>{{'ABOUT.PARTNERS'|translate}}</p>\n <p>\n <a *ngFor=\"let item of partners\" href=\"{{item.siteUrl}}\" class=\"partners\" target=\"_system\">\n <img src=\"{{item.logo}}\">\n </a>\n </p>\n </ion-text>\n </ion-item>\n </ion-list>\n\n</ion-content>\n\n<ion-footer hidden-xs hidden-sm hidden-mobile>\n <ion-toolbar>\n <ion-row class=\"ion-no-padding\" nowrap>\n <ion-col></ion-col>\n <ion-col size=\"auto\">\n <ion-button fill=\"solid\" color=\"tertiary\" (click)=\"close()\">{{'COMMON.BTN_CLOSE'|translate}}</ion-button>\n </ion-col>\n </ion-row>\n </ion-toolbar>\n</ion-footer>\n", styles: [".item-partners ion-text{height:auto}.item-partners ion-text p:last-child{display:flex;flex-wrap:wrap;flex-direction:row;justify-content:space-between}.item-partners ion-text p:last-child a{padding:2px}.item-partners ion-text p:last-child a img{text-align:center;display:inline-block;max-height:40px}\n"], dependencies: [{ kind: "directive", type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i2.IonButton, selector: "ion-button", inputs: ["buttonType", "color", "disabled", "download", "expand", "fill", "form", "href", "mode", "rel", "routerAnimation", "routerDirection", "shape", "size", "strong", "target", "type"] }, { kind: "component", type: i2.IonButtons, selector: "ion-buttons", inputs: ["collapse"] }, { kind: "component", type: i2.IonCol, selector: "ion-col", inputs: ["offset", "offsetLg", "offsetMd", "offsetSm", "offsetXl", "offsetXs", "pull", "pullLg", "pullMd", "pullSm", "pullXl", "pullXs", "push", "pushLg", "pushMd", "pushSm", "pushXl", "pushXs", "size", "sizeLg", "sizeMd", "sizeSm", "sizeXl", "sizeXs"] }, { kind: "component", type: i2.IonContent, selector: "ion-content", inputs: ["color", "forceOverscroll", "fullscreen", "scrollEvents", "scrollX", "scrollY"] }, { kind: "component", type: i2.IonFooter, selector: "ion-footer", inputs: ["collapse", "mode", "translucent"] }, { kind: "component", type: i2.IonHeader, selector: "ion-header", inputs: ["collapse", "mode", "translucent"] }, { kind: "component", type: i2.IonIcon, selector: "ion-icon", inputs: ["color", "flipRtl", "icon", "ios", "lazy", "md", "mode", "name", "sanitize", "size", "src"] }, { kind: "component", type: i2.IonItem, selector: "ion-item", inputs: ["button", "color", "counter", "counterFormatter", "detail", "detailIcon", "disabled", "download", "fill", "href", "lines", "mode", "rel", "routerAnimation", "routerDirection", "shape", "target", "type"] }, { kind: "component", type: i2.IonLabel, selector: "ion-label", inputs: ["color", "mode", "position"] }, { kind: "component", type: i2.IonList, selector: "ion-list", inputs: ["inset", "lines", "mode"] }, { kind: "component", type: i2.IonRow, selector: "ion-row" }, { kind: "component", type: i2.IonText, selector: "ion-text", inputs: ["color", "mode"] }, { kind: "component", type: i2.IonTitle, selector: "ion-title", inputs: ["color", "size"] }, { kind: "component", type: i2.IonToolbar, selector: "ion-toolbar", inputs: ["color", "mode"] }, { kind: "directive", type: i1$1.TranslateDirective, selector: "[translate],[ngx-translate]", inputs: ["translate", "translateParams"] }, { kind: "component", type: i6$4.MarkdownComponent, selector: "markdown, [markdown]", inputs: ["data", "src", "inline", "clipboard", "clipboardButtonComponent", "clipboardButtonTemplate", "emoji", "katex", "katexOptions", "mermaid", "mermaidOptions", "lineHighlight", "line", "lineOffset", "lineNumbers", "start", "commandLine", "filterOutput", "host", "prompt", "output", "user"], outputs: ["error", "load", "ready"] }, { kind: "component", type: i8.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "pipe", type: i3.AsyncPipe, name: "async" }, { kind: "pipe", type: i1$1.TranslatePipe, name: "translate" }, { kind: "pipe", type: NotEmptyArrayPipe, name: "isNotEmptyArray" }] });
|
|
23083
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: AboutModal, decorators: [{
|
|
23084
|
+
type: Component,
|
|
23085
|
+
args: [{ selector: 'app-about-modal', template: "<ion-header>\n <ion-toolbar color=\"light\">\n\n <ion-title>\n {{'ABOUT.TITLE'|translate}}\n </ion-title>\n\n <ion-buttons slot=\"end\">\n <ion-button (click)=\"close()\" visible-xs visible-sm visible-mobile>\n {{'COMMON.BTN_CLOSE'|translate}}\n </ion-button>\n </ion-buttons>\n </ion-toolbar>\n</ion-header>\n\n<ion-content class=\"ion-padding\">\n\n <ion-list lines=\"none\">\n\n <!-- Peer info -->\n <ion-item *ngIf=\"config$ | async; let config\">\n <span slot=\"start\"> </span>\n <ion-label class=\"ion-text-wrap\" >\n <h2>\n <b>{{config.label}}</b> - <span [innerHTML]=\"config.name\"></span>\n </h2>\n <p *ngIf=\"config.description\">\n <markdown [data]=\"config.description\"\n emoji>\n </markdown>\n </p>\n </ion-label>\n </ion-item>\n\n <!-- Version info -->\n <ion-item>\n <span slot=\"start\"> </span>\n <ion-label class=\"ion-text-wrap\">\n <h2>\n <small *ngIf=\"name\">{{'ABOUT.POWERED_BY'|translate}}</small> {{name}}\n <span *ngIf=\"version\" [innerHTML]=\"'ABOUT.VERSION'| translate: {version: version}\"></span>\n </h2>\n <p [innerHTML]=\"'ABOUT.LICENSE'| translate\"></p>\n </ion-label>\n </ion-item>\n\n <!-- Help -->\n <ion-item *ngIf=\"forumUrl || helpUrl\">\n <mat-icon slot=\"start\">help_outline</mat-icon>\n <ion-label>\n <p>\n {{'ABOUT.HELP'|translate}}\n </p>\n <p>\n <ion-button fill=\"solid\" color=\"accent\" href=\"{{helpUrl}}\" target=\"help\" size=\"default\">\n <mat-icon slot=\"start\">description</mat-icon>\n <ion-text translate>ABOUT.USER_MANUAL</ion-text>\n </ion-button>\n <ion-button fill=\"solid\" color=\"secondary\" href=\"{{forumUrl}}\" target=\"forum\" size=\"default\">\n <ion-icon slot=\"start\" name=\"chatbubbles\"></ion-icon>\n <ion-text translate>ABOUT.FORUM</ion-text>\n </ion-button>\n </p>\n </ion-label>\n </ion-item>\n\n <!-- Report issue -->\n <ion-item *ngIf=\"reportIssueUrl\">\n <ion-icon slot=\"start\" name=\"bug\" color=\"dark\"></ion-icon>\n <ion-label>\n <p>\n {{'ABOUT.REPORT_ISSUE'|translate}}\n </p>\n <p>\n <a color=\"primary\" href=\"{{reportIssueUrl}}\" target=\"_system\" translate>ABOUT.BTN_REPORT_ISSUE</a>\n </p>\n </ion-label>\n </ion-item>\n\n\n <!-- Source code -->\n <ion-item *ngIf=\"sourceUrl\">\n <ion-icon slot=\"start\" name=\"code\" color=\"dark\"></ion-icon>\n <ion-label>\n <p>\n {{'ABOUT.SOURCE_CODE'|translate}}\n </p>\n <p>\n <a color=\"primary\" href=\"{{sourceUrl}}\" target=\"_system\">{{sourceUrl}}</a>\n </p>\n </ion-label>\n </ion-item>\n\n <!-- Developers -->\n <ion-item *ngIf=\"developers | isNotEmptyArray\">\n <ion-icon slot=\"start\" name=\"people\" color=\"dark\"></ion-icon>\n <ion-label>\n <p>\n {{'ABOUT.DEVELOPED_BY'|translate}}\n </p>\n <ion-list lines=\"none\">\n <ion-item *ngFor=\"let item of developers\"\n class=\"ion-no-padding\">\n <img slot=\"end\" src=\"{{item.logo}}\">\n <ion-label>\n <p>\n <a color=\"primary\" href=\"{{item.siteUrl}}\" target=\"_system\">{{item.name||item.label}}</a>\n </p>\n </ion-label>\n </ion-item>\n </ion-list>\n </ion-label>\n </ion-item>\n\n <!-- Partners -->\n <ion-item class=\"item-partners\" *ngIf=\"partners | isNotEmptyArray\">\n <ion-icon slot=\"start\" name=\"megaphone\" color=\"dark\"></ion-icon>\n <ion-text>\n <p>{{'ABOUT.PARTNERS'|translate}}</p>\n <p>\n <a *ngFor=\"let item of partners\" href=\"{{item.siteUrl}}\" class=\"partners\" target=\"_system\">\n <img src=\"{{item.logo}}\">\n </a>\n </p>\n </ion-text>\n </ion-item>\n </ion-list>\n\n</ion-content>\n\n<ion-footer hidden-xs hidden-sm hidden-mobile>\n <ion-toolbar>\n <ion-row class=\"ion-no-padding\" nowrap>\n <ion-col></ion-col>\n <ion-col size=\"auto\">\n <ion-button fill=\"solid\" color=\"tertiary\" (click)=\"close()\">{{'COMMON.BTN_CLOSE'|translate}}</ion-button>\n </ion-col>\n </ion-row>\n </ion-toolbar>\n</ion-footer>\n", styles: [".item-partners ion-text{height:auto}.item-partners ion-text p:last-child{display:flex;flex-wrap:wrap;flex-direction:row;justify-content:space-between}.item-partners ion-text p:last-child a{padding:2px}.item-partners ion-text p:last-child a img{text-align:center;display:inline-block;max-height:40px}\n"] }]
|
|
23086
|
+
}], ctorParameters: function () { return [{ type: i1$1.TranslateService }, { type: i2.ModalController }, { type: ConfigService }, { type: undefined, decorators: [{
|
|
23087
|
+
type: Optional
|
|
23088
|
+
}, {
|
|
23089
|
+
type: Inject,
|
|
23090
|
+
args: [ENVIRONMENT]
|
|
23091
|
+
}] }, { type: undefined, decorators: [{
|
|
23092
|
+
type: Optional
|
|
23093
|
+
}, {
|
|
23094
|
+
type: Inject,
|
|
23095
|
+
args: [APP_ABOUT_DEVELOPERS]
|
|
23096
|
+
}] }, { type: undefined, decorators: [{
|
|
23097
|
+
type: Optional
|
|
23098
|
+
}, {
|
|
23099
|
+
type: Inject,
|
|
23100
|
+
args: [APP_ABOUT_PARTNERS]
|
|
23101
|
+
}] }]; } });
|
|
23102
|
+
|
|
23084
23103
|
const DEFAULT_MENU_SHOW_WHEN = 'lg';
|
|
23085
23104
|
const APP_MENU_ITEMS = new InjectionToken('menuItems');
|
|
23086
23105
|
const APP_MENU_OPTIONS = new InjectionToken('menuOptions');
|
|
23087
23106
|
class MenuService extends StartableObservableService {
|
|
23088
|
-
constructor(settings, configService, accountService, router, environment, options, staticItems) {
|
|
23107
|
+
constructor(settings, configService, accountService, router, modalCtrl, alertController, navController, translate, environment, options, staticItems) {
|
|
23089
23108
|
super(settings);
|
|
23090
23109
|
this.settings = settings;
|
|
23091
23110
|
this.configService = configService;
|
|
23092
23111
|
this.accountService = accountService;
|
|
23093
23112
|
this.router = router;
|
|
23113
|
+
this.modalCtrl = modalCtrl;
|
|
23114
|
+
this.alertController = alertController;
|
|
23115
|
+
this.navController = navController;
|
|
23116
|
+
this.translate = translate;
|
|
23094
23117
|
this.environment = environment;
|
|
23095
23118
|
this.accountChanges = new BehaviorSubject(undefined);
|
|
23096
23119
|
this.onPinned = new EventEmitter(true);
|
|
@@ -23102,14 +23125,28 @@ class MenuService extends StartableObservableService {
|
|
|
23102
23125
|
this._$enabled = new BehaviorSubject(true);
|
|
23103
23126
|
this._$listenRoute = new BehaviorSubject(false);
|
|
23104
23127
|
this._options = {
|
|
23105
|
-
enableSubMenuIcon: true,
|
|
23106
23128
|
...options,
|
|
23107
|
-
|
|
23129
|
+
subMenu: {
|
|
23130
|
+
disableIcon: false,
|
|
23131
|
+
savePinned: true,
|
|
23132
|
+
...(options?.subMenu || {}),
|
|
23133
|
+
// Force disable on mobile
|
|
23134
|
+
enable: options?.subMenu?.enable !== false && !this.settings.mobile,
|
|
23135
|
+
}
|
|
23108
23136
|
};
|
|
23109
|
-
this._$
|
|
23137
|
+
this._$enableSubMenu = new BehaviorSubject(this._options.subMenu.enable);
|
|
23110
23138
|
this._debug = !environment.production;
|
|
23111
|
-
this._staticItems = (staticItems || []).map(source => this.fromObject(source, { computeId: true, fillParent: true }));
|
|
23112
23139
|
this._detachedSubItems = [];
|
|
23140
|
+
this._staticItems = (staticItems || []).map(source => {
|
|
23141
|
+
const target = this.fromObject({ static: true, ...source }, { computeId: true, fillParent: true, fillDefaultFromParent: true });
|
|
23142
|
+
const detachedItems = TreeItemEntityUtils.deleteRecursively(target, (item) => item.static !== true);
|
|
23143
|
+
if (detachedItems?.length) {
|
|
23144
|
+
console.debug(this._logPrefix + 'Detached init items', detachedItems);
|
|
23145
|
+
detachedItems.forEach(item => this._detachToParent(item));
|
|
23146
|
+
this._detachedSubItems.push(...detachedItems);
|
|
23147
|
+
}
|
|
23148
|
+
return target;
|
|
23149
|
+
});
|
|
23113
23150
|
}
|
|
23114
23151
|
get opened() {
|
|
23115
23152
|
return this._$opened.asObservable();
|
|
@@ -23121,10 +23158,7 @@ class MenuService extends StartableObservableService {
|
|
|
23121
23158
|
return this._$enabled.asObservable();
|
|
23122
23159
|
}
|
|
23123
23160
|
get subMenuEnabled() {
|
|
23124
|
-
return this._$
|
|
23125
|
-
}
|
|
23126
|
-
get subMenuIconEnabled() {
|
|
23127
|
-
return this._options.enableSubMenuIcon;
|
|
23161
|
+
return this._$enableSubMenu.value;
|
|
23128
23162
|
}
|
|
23129
23163
|
get subItems() {
|
|
23130
23164
|
return (this.data || []).reduce((res, rootElement) => res.concat(rootElement.children), []);
|
|
@@ -23136,7 +23170,7 @@ class MenuService extends StartableObservableService {
|
|
|
23136
23170
|
this._$enabled.next(value);
|
|
23137
23171
|
}
|
|
23138
23172
|
enableSubMenu(value) {
|
|
23139
|
-
this._$
|
|
23173
|
+
this._$enableSubMenu.next(value);
|
|
23140
23174
|
}
|
|
23141
23175
|
setSplitPaneShowWhen(value) {
|
|
23142
23176
|
if (this._$splitPaneWhen.value !== value) {
|
|
@@ -23156,8 +23190,8 @@ class MenuService extends StartableObservableService {
|
|
|
23156
23190
|
// Compute id if need
|
|
23157
23191
|
if (opts?.computeId && isNil(target.id))
|
|
23158
23192
|
target.id = this._computeNewId();
|
|
23159
|
-
// Remove icon if
|
|
23160
|
-
if (
|
|
23193
|
+
// Remove icon if disabled
|
|
23194
|
+
if (this._options.subMenu.disableIcon) {
|
|
23161
23195
|
Object.assign(target, { icon: undefined, matIcon: undefined, matSvgIcon: undefined });
|
|
23162
23196
|
}
|
|
23163
23197
|
// Recursive
|
|
@@ -23165,6 +23199,21 @@ class MenuService extends StartableObservableService {
|
|
|
23165
23199
|
// Fill parent (once, when the full tree is ready)
|
|
23166
23200
|
if (opts?.fillParent) {
|
|
23167
23201
|
TreeItemEntityUtils.treeFillParent(target);
|
|
23202
|
+
// Fill defaults from the parent (once filled)
|
|
23203
|
+
if (opts?.fillDefaultFromParent) {
|
|
23204
|
+
TreeItemEntityUtils.visit(target, (item) => {
|
|
23205
|
+
if (!item.parent)
|
|
23206
|
+
return; // Skip if no parent
|
|
23207
|
+
item.parentPath = item.parentPath || item.parent.path;
|
|
23208
|
+
item.parentPathParams = item.parentPathParams || item.parent.pathParams;
|
|
23209
|
+
item.static = toBoolean(item.static, item.parent.static);
|
|
23210
|
+
// Compute path, from parent path + action
|
|
23211
|
+
if (!item.path && !!item.action) {
|
|
23212
|
+
item.path = item.parent.path;
|
|
23213
|
+
item.pathParams = (typeof item.action === 'string') ? { action: item.action } : { actionId: item.id.toString(), actionTitle: item.title };
|
|
23214
|
+
}
|
|
23215
|
+
});
|
|
23216
|
+
}
|
|
23168
23217
|
}
|
|
23169
23218
|
return target;
|
|
23170
23219
|
}
|
|
@@ -23215,6 +23264,9 @@ class MenuService extends StartableObservableService {
|
|
|
23215
23264
|
console.warn(this._logPrefix + `Sub menu {${source.path}} cannot be found - unable to toggle pinned!`);
|
|
23216
23265
|
return;
|
|
23217
23266
|
}
|
|
23267
|
+
// Skip if static
|
|
23268
|
+
if (item.static)
|
|
23269
|
+
return;
|
|
23218
23270
|
// Unpinned
|
|
23219
23271
|
if (item.pinned) {
|
|
23220
23272
|
item.pinned = false;
|
|
@@ -23231,6 +23283,93 @@ class MenuService extends StartableObservableService {
|
|
|
23231
23283
|
}
|
|
23232
23284
|
this.onPinned.emit(item);
|
|
23233
23285
|
}
|
|
23286
|
+
async executeAction(event, item) {
|
|
23287
|
+
const action = item?.action;
|
|
23288
|
+
if (!action)
|
|
23289
|
+
return; // skip
|
|
23290
|
+
if (typeof action === 'string') {
|
|
23291
|
+
switch (action) {
|
|
23292
|
+
case 'logout':
|
|
23293
|
+
await this.logout();
|
|
23294
|
+
break;
|
|
23295
|
+
case 'about':
|
|
23296
|
+
await this.openAboutModal();
|
|
23297
|
+
break;
|
|
23298
|
+
case 'expand':
|
|
23299
|
+
await this.toggleExpandableItem(item);
|
|
23300
|
+
if (item.path) {
|
|
23301
|
+
await this.navController.navigateRoot(item.path, {
|
|
23302
|
+
queryParams: item.pathParams
|
|
23303
|
+
});
|
|
23304
|
+
}
|
|
23305
|
+
break;
|
|
23306
|
+
default: {
|
|
23307
|
+
if (item.path) {
|
|
23308
|
+
await this.navController.navigateRoot(item.path, {
|
|
23309
|
+
queryParams: item.pathParams
|
|
23310
|
+
});
|
|
23311
|
+
}
|
|
23312
|
+
else {
|
|
23313
|
+
throw new Error('Unknown action: ' + action);
|
|
23314
|
+
}
|
|
23315
|
+
}
|
|
23316
|
+
}
|
|
23317
|
+
}
|
|
23318
|
+
else if (typeof action === 'function') {
|
|
23319
|
+
action(event);
|
|
23320
|
+
}
|
|
23321
|
+
}
|
|
23322
|
+
async logout() {
|
|
23323
|
+
const translations = await this.translate.instant([
|
|
23324
|
+
'AUTH.LOGOUT.CONFIRM_TITLE',
|
|
23325
|
+
'AUTH.LOGOUT.CONFIRM_MESSAGE',
|
|
23326
|
+
'COMMON.BTN_CANCEL',
|
|
23327
|
+
'AUTH.LOGOUT.BTN_CONFIRM',
|
|
23328
|
+
]);
|
|
23329
|
+
const alert = await this.alertController.create({
|
|
23330
|
+
header: translations['AUTH.LOGOUT.CONFIRM_TITLE'],
|
|
23331
|
+
message: translations['AUTH.LOGOUT.CONFIRM_MESSAGE'],
|
|
23332
|
+
buttons: [
|
|
23333
|
+
{
|
|
23334
|
+
text: translations['COMMON.BTN_CANCEL'],
|
|
23335
|
+
role: 'cancel',
|
|
23336
|
+
cssClass: 'secondary',
|
|
23337
|
+
},
|
|
23338
|
+
{
|
|
23339
|
+
text: translations['AUTH.LOGOUT.BTN_CONFIRM'],
|
|
23340
|
+
cssClass: 'ion-color-primary',
|
|
23341
|
+
handler: () => {
|
|
23342
|
+
this.accountService.logout();
|
|
23343
|
+
// Back to home
|
|
23344
|
+
setTimeout(() => this.navController.navigateRoot('/'), 100);
|
|
23345
|
+
},
|
|
23346
|
+
},
|
|
23347
|
+
],
|
|
23348
|
+
});
|
|
23349
|
+
await alert.present();
|
|
23350
|
+
}
|
|
23351
|
+
async openAboutModal() {
|
|
23352
|
+
const modal = await this.modalCtrl.create({ component: AboutModal });
|
|
23353
|
+
return modal.present();
|
|
23354
|
+
}
|
|
23355
|
+
async toggleExpandableItem(item) {
|
|
23356
|
+
if (!item.expanded) {
|
|
23357
|
+
if (this._debug)
|
|
23358
|
+
console.debug(this._logPrefix + 'Expand item', item);
|
|
23359
|
+
item.matIcon = 'expand_less';
|
|
23360
|
+
// Try to attach some item
|
|
23361
|
+
this._detachedSubItems
|
|
23362
|
+
.filter(childItem => !!this._findParent(childItem, [item]))
|
|
23363
|
+
.forEach(childItem => this._attachMenuToParent(item, childItem));
|
|
23364
|
+
}
|
|
23365
|
+
else {
|
|
23366
|
+
item.matIcon = 'expand_more';
|
|
23367
|
+
this._detachedSubItems = [
|
|
23368
|
+
...this._detachedSubItems,
|
|
23369
|
+
...this._detachSubMenuItems({ path: '/', params: {} }, item.children)
|
|
23370
|
+
];
|
|
23371
|
+
}
|
|
23372
|
+
}
|
|
23234
23373
|
_markAsOpened() {
|
|
23235
23374
|
this._$opened.next(true);
|
|
23236
23375
|
}
|
|
@@ -23262,7 +23401,7 @@ class MenuService extends StartableObservableService {
|
|
|
23262
23401
|
// Emit account changes event
|
|
23263
23402
|
this.accountChanges.next(account);
|
|
23264
23403
|
}));
|
|
23265
|
-
this.registerSubscription(merge(this.accountChanges.pipe(map(() => MenuItems.parsePathWithQuery(this.router.routerState.snapshot.url))), this._$listenRoute.pipe(filter(listen => listen === true), mergeMap$1(_ => this.router.events), filter(event => event instanceof NavigationEnd), map((event) => MenuItems.parsePathWithQuery(event.url)))).pipe(throttleTime(250)
|
|
23404
|
+
this.registerSubscription(merge(this.accountChanges.pipe(map(() => MenuItems.parsePathWithQuery(this.router.routerState.snapshot.url))), this._$listenRoute.pipe(filter(listen => listen === true && this.started), mergeMap$1(_ => this.router.events), filter(event => event instanceof NavigationEnd), map((event) => MenuItems.parsePathWithQuery(event.url)))).pipe(throttleTime(250))
|
|
23266
23405
|
.subscribe(pathParam => {
|
|
23267
23406
|
const detachedSubItems = this._detachSubMenuItems(pathParam);
|
|
23268
23407
|
if (detachedSubItems?.length) {
|
|
@@ -23290,7 +23429,7 @@ class MenuService extends StartableObservableService {
|
|
|
23290
23429
|
if (this._debug)
|
|
23291
23430
|
console.debug(`${this._logPrefix}Loading menu items...`);
|
|
23292
23431
|
// Save previous children of root items
|
|
23293
|
-
const detachedSubItems = (this.subItems || [])
|
|
23432
|
+
const detachedSubItems = (this.subItems || []).concat(this._staticSubItems || [])
|
|
23294
23433
|
.reduce((res, rootItem) => {
|
|
23295
23434
|
const children = rootItem.children;
|
|
23296
23435
|
if (isEmptyArray(children))
|
|
@@ -23370,21 +23509,22 @@ class MenuService extends StartableObservableService {
|
|
|
23370
23509
|
return items;
|
|
23371
23510
|
}
|
|
23372
23511
|
_addSubMenuItems(sources, opts) {
|
|
23373
|
-
return sources.map(source => this._addSubMenuItem(
|
|
23512
|
+
return sources.map(source => this._addSubMenuItem(source, opts));
|
|
23374
23513
|
}
|
|
23375
23514
|
_addSubMenuItem(newItem, opts) {
|
|
23376
23515
|
opts = {
|
|
23377
23516
|
skipIfExists: true,
|
|
23378
23517
|
...opts,
|
|
23379
23518
|
};
|
|
23519
|
+
const pathParam = MenuItems.parsePathWithQuery(this.router.routerState.snapshot.url);
|
|
23380
23520
|
// Find if item already exists
|
|
23381
23521
|
const existingItem = this._findExistingItem(newItem, opts?.availableParents);
|
|
23382
23522
|
if (existingItem) {
|
|
23383
23523
|
// No changes
|
|
23384
|
-
if (opts.skipIfExists && MenuItems.isSame(existingItem, newItem) &&
|
|
23524
|
+
if (opts.skipIfExists && MenuItems.isSame(existingItem, newItem) && existingItem.visible) {
|
|
23385
23525
|
// DEBUG
|
|
23386
23526
|
if (this._debug)
|
|
23387
|
-
console.debug(`${this._logPrefix}Skipping sub item (same item already exist)`, newItem);
|
|
23527
|
+
console.debug(`${this._logPrefix}Skipping sub item (same visible item already exist)`, newItem);
|
|
23388
23528
|
return existingItem;
|
|
23389
23529
|
}
|
|
23390
23530
|
if (this._debug)
|
|
@@ -23394,52 +23534,69 @@ class MenuService extends StartableObservableService {
|
|
|
23394
23534
|
newItem.id = existingItem.id;
|
|
23395
23535
|
newItem.$children = existingItem.$children;
|
|
23396
23536
|
newItem.pinned = existingItem.pinned;
|
|
23397
|
-
|
|
23537
|
+
newItem.static = existingItem.static;
|
|
23538
|
+
if (newItem.pinned || newItem.static || existingItem.expanded) {
|
|
23398
23539
|
// If loading, keep existing title if pinned (avoid to show skeleton)
|
|
23399
23540
|
newItem.title = newItem.title || existingItem.title;
|
|
23400
23541
|
}
|
|
23401
23542
|
else {
|
|
23402
23543
|
newItem.title = isNotNil(newItem.title) ? newItem.title : existingItem.title;
|
|
23403
23544
|
}
|
|
23545
|
+
// Auto set icon, for expand action
|
|
23546
|
+
if (existingItem.action === 'expand') {
|
|
23547
|
+
newItem.icon = null;
|
|
23548
|
+
newItem.matIcon = existingItem.expanded ? 'expand_less' : 'expand_more';
|
|
23549
|
+
}
|
|
23404
23550
|
}
|
|
23405
23551
|
}
|
|
23406
23552
|
// Generate item's id (if need)
|
|
23407
23553
|
else if (isNil(newItem.id)) {
|
|
23408
23554
|
newItem.id = this._computeNewId();
|
|
23409
23555
|
}
|
|
23410
|
-
//
|
|
23556
|
+
// Default icon for expand action
|
|
23557
|
+
if (newItem.action === 'expand' && !newItem.matIcon) {
|
|
23558
|
+
newItem.matIcon = 'expand_more';
|
|
23559
|
+
}
|
|
23560
|
+
// If visible, get the parent where to attach the item
|
|
23411
23561
|
const parent = this._findParent(newItem, opts?.availableParents);
|
|
23412
|
-
if (parent) {
|
|
23562
|
+
if (parent && parent.expanded) {
|
|
23413
23563
|
// Attach item to parent
|
|
23414
23564
|
this._attachMenuToParent(parent, newItem);
|
|
23415
|
-
const pathParam = MenuItems.parsePathWithQuery(this.router.routerState.snapshot.url);
|
|
23416
23565
|
// Update detached items :
|
|
23417
23566
|
// - excluded new item
|
|
23418
23567
|
// - attach and exclude those than can be attached to the new item
|
|
23419
23568
|
// Search in detached items one have newItem as parent
|
|
23420
|
-
|
|
23421
|
-
|
|
23422
|
-
.
|
|
23423
|
-
|
|
23424
|
-
|
|
23425
|
-
|
|
23426
|
-
|
|
23427
|
-
|
|
23428
|
-
|
|
23429
|
-
|
|
23430
|
-
|
|
23431
|
-
|
|
23432
|
-
|
|
23433
|
-
|
|
23434
|
-
|
|
23435
|
-
|
|
23569
|
+
if (newItem.expanded) {
|
|
23570
|
+
const ancestor = newItem.ancestor;
|
|
23571
|
+
this._detachedSubItems = this._detachedSubItems.concat(...newItem.children)
|
|
23572
|
+
.reduce((res, item) => {
|
|
23573
|
+
// Excluded newly add item
|
|
23574
|
+
if (item.id === newItem.id)
|
|
23575
|
+
return res;
|
|
23576
|
+
// If some detached can be attached to the new item: do it
|
|
23577
|
+
if (MenuItems.checkIfSubMenuVisible(item, pathParam)) {
|
|
23578
|
+
const parent = this._findParent(item, [ancestor]);
|
|
23579
|
+
if (parent) {
|
|
23580
|
+
// Update item's children
|
|
23581
|
+
const detachedChildren = this._detachSubMenuItems(pathParam, item.children || []);
|
|
23582
|
+
// Attach item
|
|
23583
|
+
this._attachMenuToParent(parent, item);
|
|
23584
|
+
// Remember detached children
|
|
23585
|
+
return res.concat(...detachedChildren);
|
|
23586
|
+
}
|
|
23436
23587
|
}
|
|
23437
|
-
|
|
23438
|
-
|
|
23439
|
-
|
|
23440
|
-
|
|
23441
|
-
|
|
23442
|
-
}
|
|
23588
|
+
// Detach (if need)
|
|
23589
|
+
this._detachToParent(item);
|
|
23590
|
+
// Add to detached items
|
|
23591
|
+
return res.concat(item);
|
|
23592
|
+
}, []);
|
|
23593
|
+
}
|
|
23594
|
+
else {
|
|
23595
|
+
// Remove from detached elements
|
|
23596
|
+
this._detachedSubItems = this._detachedSubItems.filter(item => item.id !== newItem.id);
|
|
23597
|
+
// Detach children
|
|
23598
|
+
newItem.children.forEach(item => this._detachToParent(item));
|
|
23599
|
+
}
|
|
23443
23600
|
}
|
|
23444
23601
|
else {
|
|
23445
23602
|
// Add or update detached item
|
|
@@ -23553,14 +23710,14 @@ class MenuService extends StartableObservableService {
|
|
|
23553
23710
|
}
|
|
23554
23711
|
}
|
|
23555
23712
|
}
|
|
23556
|
-
MenuService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: MenuService, deps: [{ token: LocalSettingsService }, { token: ConfigService }, { token: AccountService }, { token: i1$5.Router }, { token: ENVIRONMENT }, { token: APP_MENU_OPTIONS, optional: true }, { token: APP_MENU_ITEMS, optional: true }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
23713
|
+
MenuService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: MenuService, deps: [{ token: LocalSettingsService }, { token: ConfigService }, { token: AccountService }, { token: i1$5.Router }, { token: i2.ModalController }, { token: i2.AlertController }, { token: i2.NavController }, { token: i1$1.TranslateService }, { token: ENVIRONMENT }, { token: APP_MENU_OPTIONS, optional: true }, { token: APP_MENU_ITEMS, optional: true }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
23557
23714
|
MenuService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: MenuService, providedIn: 'root' });
|
|
23558
23715
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: MenuService, decorators: [{
|
|
23559
23716
|
type: Injectable,
|
|
23560
23717
|
args: [{
|
|
23561
23718
|
providedIn: 'root', deps: [ENVIRONMENT]
|
|
23562
23719
|
}]
|
|
23563
|
-
}], ctorParameters: function () { return [{ type: LocalSettingsService }, { type: ConfigService }, { type: AccountService }, { type: i1$5.Router }, { type: Environment, decorators: [{
|
|
23720
|
+
}], ctorParameters: function () { return [{ type: LocalSettingsService }, { type: ConfigService }, { type: AccountService }, { type: i1$5.Router }, { type: i2.ModalController }, { type: i2.AlertController }, { type: i2.NavController }, { type: i1$1.TranslateService }, { type: Environment, decorators: [{
|
|
23564
23721
|
type: Inject,
|
|
23565
23722
|
args: [ENVIRONMENT]
|
|
23566
23723
|
}] }, { type: MenuOptions, decorators: [{
|
|
@@ -23654,35 +23811,6 @@ class MenuComponent {
|
|
|
23654
23811
|
this.markAsLoaded({ emitEvent: false });
|
|
23655
23812
|
this.markForCheck();
|
|
23656
23813
|
}
|
|
23657
|
-
async logout() {
|
|
23658
|
-
const translations = await this.translate.instant([
|
|
23659
|
-
'AUTH.LOGOUT.CONFIRM_TITLE',
|
|
23660
|
-
'AUTH.LOGOUT.CONFIRM_MESSAGE',
|
|
23661
|
-
'COMMON.BTN_CANCEL',
|
|
23662
|
-
'AUTH.LOGOUT.BTN_CONFIRM',
|
|
23663
|
-
]);
|
|
23664
|
-
const alert = await this.alertController.create({
|
|
23665
|
-
header: translations['AUTH.LOGOUT.CONFIRM_TITLE'],
|
|
23666
|
-
message: translations['AUTH.LOGOUT.CONFIRM_MESSAGE'],
|
|
23667
|
-
buttons: [
|
|
23668
|
-
{
|
|
23669
|
-
text: translations['COMMON.BTN_CANCEL'],
|
|
23670
|
-
role: 'cancel',
|
|
23671
|
-
cssClass: 'secondary',
|
|
23672
|
-
},
|
|
23673
|
-
{
|
|
23674
|
-
text: translations['AUTH.LOGOUT.BTN_CONFIRM'],
|
|
23675
|
-
cssClass: 'ion-color-primary',
|
|
23676
|
-
handler: () => {
|
|
23677
|
-
this.accountService.logout();
|
|
23678
|
-
// Back to home
|
|
23679
|
-
setTimeout(() => this.navController.navigateRoot('/'), 100);
|
|
23680
|
-
},
|
|
23681
|
-
},
|
|
23682
|
-
],
|
|
23683
|
-
});
|
|
23684
|
-
await alert.present();
|
|
23685
|
-
}
|
|
23686
23814
|
trackByFn(index, item) {
|
|
23687
23815
|
return item.id.toString();
|
|
23688
23816
|
}
|
|
@@ -23711,15 +23839,11 @@ class MenuComponent {
|
|
|
23711
23839
|
if (opened) {
|
|
23712
23840
|
console.debug('[menu] Closing menu');
|
|
23713
23841
|
await this.menu.close(this.menuId);
|
|
23714
|
-
//
|
|
23842
|
+
// Propagate to service
|
|
23715
23843
|
this.menuService._markAsClosed();
|
|
23716
23844
|
}
|
|
23717
23845
|
return true;
|
|
23718
23846
|
}
|
|
23719
|
-
async openAboutModal(event) {
|
|
23720
|
-
const modal = await this.modalCtrl.create({ component: AboutModal });
|
|
23721
|
-
return modal.present();
|
|
23722
|
-
}
|
|
23723
23847
|
async setSplitPaneWhen(value) {
|
|
23724
23848
|
console.debug('[menu] Checking splitPane when...');
|
|
23725
23849
|
if (this.splitPane.when !== value) {
|
|
@@ -23742,24 +23866,10 @@ class MenuComponent {
|
|
|
23742
23866
|
return this.setSplitPaneWhen(false);
|
|
23743
23867
|
}
|
|
23744
23868
|
}
|
|
23745
|
-
|
|
23869
|
+
executeAction(event, item) {
|
|
23746
23870
|
this.close();
|
|
23747
|
-
|
|
23748
|
-
|
|
23749
|
-
switch (action) {
|
|
23750
|
-
case 'logout':
|
|
23751
|
-
await this.logout();
|
|
23752
|
-
break;
|
|
23753
|
-
case 'about':
|
|
23754
|
-
await this.openAboutModal(event);
|
|
23755
|
-
break;
|
|
23756
|
-
default:
|
|
23757
|
-
throw new Error('Unknown action: ' + action);
|
|
23758
|
-
}
|
|
23759
|
-
}
|
|
23760
|
-
else if (typeof action === 'function') {
|
|
23761
|
-
action(event);
|
|
23762
|
-
}
|
|
23871
|
+
// Delegate execution to service
|
|
23872
|
+
return this.menuService.executeAction(event, item);
|
|
23763
23873
|
}
|
|
23764
23874
|
onSwipeRight(event) {
|
|
23765
23875
|
// Skip, if not a valid swipe event
|
|
@@ -23808,10 +23918,10 @@ class MenuComponent {
|
|
|
23808
23918
|
}
|
|
23809
23919
|
}
|
|
23810
23920
|
MenuComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: MenuComponent, deps: [{ token: PlatformService }, { token: AccountService }, { token: i2.NavController }, { token: i2.MenuController }, { token: i2.ModalController }, { token: i2.AlertController }, { token: i1$1.TranslateService }, { token: i0.ChangeDetectorRef }, { token: MenuService }, { token: i1$5.Router }, { token: ENVIRONMENT }, { token: i1$5.ActivatedRoute, optional: true }], target: i0.ɵɵFactoryTarget.Component });
|
|
23811
|
-
MenuComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: MenuComponent, selector: "app-menu", inputs: { id: "id", menuId: "menuId", side: "side", contentId: "contentId", logo: "logo", appName: "appName", appVersion: "appVersion", rxStrategy: "rxStrategy" }, viewQueries: [{ propertyName: "splitPane", first: true, predicate: ["splitPane"], descendants: true, static: true }], ngImport: i0, template: "<ion-split-pane #splitPane [contentId]=\"contentId\" (swiperight)=\"onSwipeRight($event)\">\n\n <ion-menu [id]=\"id\" [menuId]=\"menuId\" [contentId]=\"contentId\">\n <ion-header>\n\n <ion-toolbar *ngIf=\"!loading && isLogin; else notLogin\"\n @fadeInSlowAnimation\n class=\"user-toolbar\">\n <ion-grid>\n <ion-row>\n <ion-col size=\"4\">\n <button type=\"button\" mat-flat-button\n class=\"user-avatar\" [class.primary]=\"!accountAvatar\"\n [style.background-image]=\"'url('+(accountAvatar||'./assets/img/person.png')+')'\"\n [routerLink]=\"['/account']\"\n routerDirection=\"root\"\n routerLinkActive=\"ion-color-primary\"\n (click)=\"close()\"\n [title]=\"'MENU.BTN_MY_ACCOUNT'|translate\">\n </button>\n </ion-col>\n <ion-col size=\"8\" class=\"user-logo\">\n <img *ngIf=\"logo; else noLogo\" src=\"{{logo}}\" [title]=\"'APP_NAME'|translate: {appName: appName}\" width=\"108px\"/>\n <ng-template #noLogo>\n <span style=\"width: 108px;\">{{appName}}</span>\n </ng-template>\n </ion-col>\n </ion-row>\n <ion-row class=\"ion-no-padding\">\n <ion-col>\n <button mat-button type=\"button\"\n [routerLink]=\"['/account']\"\n routerDirection=\"root\"\n routerLinkActive=\"ion-color-primary\"\n (click)=\"close()\"\n [title]=\"'MENU.BTN_MY_ACCOUNT'|translate\">\n <ion-label color=\"primary\" class=\"ion-text-wrap ion-text-start\">\n <h3 class=\"no-margin username\">\n <b>{{accountName}}</b>\n </h3>\n <h4>{{accountEmail}}</h4>\n </ion-label>\n </button>\n </ion-col>\n\n <!-- Insertion headerBottomRight -->\n <ion-col size=\"auto\">\n <ng-container *ngTemplateOutlet=\"headerBottomRight\"></ng-container>\n </ion-col>\n </ion-row>\n </ion-grid>\n\n </ion-toolbar>\n\n <!-- User not logged -->\n <ng-template #notLogin>\n <mat-toolbar class=\"ion-padding\"\n *ngIf=\"!loading\"\n style=\"height: unset; display: block; margin: auto; text-align: center;\">\n <img *ngIf=\"logo\" src=\"{{logo}}\" [title]=\"'APP_NAME'|translate: {appName: appName}\" width=\"150px;\" alt=\"logo\">\n <span *ngIf=\"!logo\" style=\"width: 150px\">{{appName}}</span>\n </mat-toolbar>\n </ng-template>\n </ion-header>\n\n <ion-content [class.has-user-header]=\"isLogin\">\n <!-- will close the menu, after a click, in mobile -->\n <ion-menu-toggle auto-hide=\"false\">\n <ion-list lines=\"none\" *ngIf=\"!loading\">\n <ng-container *rxFor=\"let item of menuService.dataSubject; strategy: rxStrategy; trackBy: trackByFn\">\n <ng-container *ngTemplateOutlet=\"menuItem; context: {$implicit: item, level: 0}\"></ng-container>\n </ng-container>\n </ion-list>\n </ion-menu-toggle>\n </ion-content>\n\n <ion-footer class=\"hidden-xs hidden-sm\">\n <ion-toolbar>\n\n <ion-buttons slot=\"start\">\n <ion-button mat-icon-button color=\"accent\" (click)=\"openAboutModal($event)\">\n <mat-icon slot=\"icon-only\">help_outline</mat-icon>\n </ion-button>\n </ion-buttons>\n\n <ion-title (click)=\"openAboutModal($event)\" color=\"medium\">\n {{'MENU.FOOTER_VERSION_ABOUT'| translate: {version: appVersion} }}\n </ion-title>\n\n <ion-buttons slot=\"end\">\n <button mat-icon-button color=\"accent\" (click)=\"toggleSplitPaneShow($event)\"\n class=\"hidden-xs hidden-sm hidden-md\"\n [title]=\"(splitPane.when ? 'COMMON.BTN_HIDE_MENU' : 'COMMON.BTN_SHOW_MENU') |translate\">\n <mat-icon><span>{{splitPane.when ? '«' : '»'}}</span></mat-icon>\n </button>\n </ion-buttons>\n </ion-toolbar>\n </ion-footer>\n\n </ion-menu>\n\n <ng-content></ng-content>\n\n</ion-split-pane>\n\n<ng-template #headerBottomRight>\n <ng-content select=\"[headerBottomRight]\"></ng-content>\n</ng-template>\n\n<ng-template #menuItem let-item let-level=\"level\">\n <!-- link -->\n <ion-item *ngIf=\"item.path && !item.action\"\n @fadeInSlowAnimation\n class=\"{{item.cssClass}} {{item.color}}\"\n [class.menu-item-sub]=\"level!==0\"\n tappable\n [routerLink]=\"item.path\"\n [queryParams]=\"item.pathParams\"\n routerDirection=\"root\"\n routerLinkActive=\"selected\"\n [routerLinkActiveOptions]=\"{exact: (item.path === '/' || level !== 0)}\">\n <ion-icon slot=\"start\" *ngIf=\"item.icon\" [name]=\"item.icon\"></ion-icon>\n <mat-icon slot=\"start\" *ngIf=\"item.matIcon\">{{item.matIcon}}</mat-icon>\n <ion-label *rxLet=\"item.$title; let title\">\n <span *ngIf=\"title; else skeletonText\" [innerHTML]=\"title|translate\"></span>\n <!--<span *ngIf=\"_debug\"> {{item.id}}</span>-->\n </ion-label>\n\n <!-- pin button -->\n <ng-container *ngTemplateOutlet=\"pinButton; context: {$implicit: item, level: level}\"></ng-container>\n\n </ion-item>\n\n <!-- action -->\n <ion-item *ngIf=\"item.action\"\n @fadeInSlowAnimation\n class=\"{{item.cssClass}} {{item.color}} text-1x\"\n [class.menu-item-sub]=\"level!==0\"\n tappable\n (click)=\"doAction(item.action, $event)\">\n <ion-icon slot=\"start\" *ngIf=\"item.icon\" [name]=\"item.icon\"></ion-icon>\n <mat-icon slot=\"start\" *ngIf=\"item.matIcon\">{{item.matIcon}}</mat-icon>\n <ion-label>\n <span *rxIf=\"item.$title; let title; else skeletonText\" [innerHTML]=\"title|translate\"></span>\n <!--<span *ngIf=\"_debug\"> {{item.id}}</span>-->\n </ion-label>\n\n <!-- pin button -->\n <ng-container *ngTemplateOutlet=\"pinButton; context: {$implicit: item, level: level}\"></ng-container>\n </ion-item>\n\n <!-- divider -->\n <ion-item-divider @fadeInSlowAnimation\n class=\"{{item.cssClass}} {{item.color}}\"\n *ngIf=\"!item.path && !item.action\">\n <ion-label>\n <span *rxIf=\"item.$title; let title; else skeletonText\" [innerHTML]=\"title|translate\"></span>\n </ion-label>\n </ion-item-divider>\n\n <!-- children -->\n <div *ngIf=\"item?.$children\" class=\"sub-menu-container\">\n <ng-container *rxFor=\"let child of item.$children ; strategy: rxStrategy; trackBy: trackByFn\">\n <ng-container *ngTemplateOutlet=\"menuItem; context: {$implicit: child, level: level+1}\"></ng-container>\n </ng-container>\n </div>\n</ng-template>\n\n<ng-template #pinButton let-item let-level=\"level\">\n <!-- pin button -->\n <ion-button *ngIf=\"level > 0\"\n slot=\"end\"\n shape=\"round\" fill=\"clear\" size=\"small\"\n [class.visible-hover]=\"!item.pinned\"\n (click)=\"togglePinned($event, item)\">\n <ion-icon slot=\"icon-only\" [name]=\"item.pinned ? 'pin' : 'pin-outline'\"></ion-icon>\n </ion-button>\n</ng-template>\n\n<ng-template #skeletonText let-width let-animated>\n <ion-skeleton-text [animated]=\"animated\" [style.width.%]=\"width || 60\"></ion-skeleton-text>\n</ng-template>\n", styles: ["@keyframes fadeinout{0%{opacity:0;display:none}75%{opacity:0;display:none}to{opacity:1;display:flex}}ion-menu{--menu-item-margin: 0;--ion-item-background: transparent;--ion-item-divider-background: transparent;--ion-item-icon-color: var(--ion-color-primary-tint);--ion-item-text-color: var(--ion-color-primary-tint);--ion-item-background-selected: var(--ion-color-secondary100);--ion-item-text-color-selected: var(--ion-color-primary);--ion-item-icon-color-selected: var(--ion-color-primary);--ion-item-text-color-disable: var(--ion-color-medium);--ion-item-icon-color-disable: var(--ion-color-medium);--menu-item-background-selected-sub: var(--ion-color-secondary50);--menu-item-border-width-sub: 0 0 1px 0;--menu-item-margin-start-sub: 16px}ion-menu ion-header ion-text{color:var(--ion-color-primary)}ion-menu ion-header ion-toolbar.user-toolbar{--ion-toolbar-height: 128px}ion-menu ion-header .user-avatar{background-size:cover;background-repeat:no-repeat;background-position:center;background-color:var(--ion-color-secondary);border:solid 1px rgba(var(--ion-color-secondary-rgb),.5);overflow:hidden!important;font-size:var(--avatar-size, 60px)!important;line-height:var(--avatar-size, 60px);height:var(--avatar-size, 60px)!important;width:var(--avatar-size, 60px)!important;border-radius:50%;display:inline-block}ion-menu ion-header .user-avatar:hover{background-color:var(--ion-color-secondary-shade);border:solid 2px var(--ion-color-secondary-shade)}ion-menu ion-header .user-logo{text-align:right}ion-menu ion-header .user-logo img{max-width:120px;max-height:var(--avatar-size, 60px);width:auto}ion-menu ion-header .username{padding-top:0;margin-top:0;margin-bottom:0;width:100%;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}ion-menu ion-header button[mat-button]{padding:0;text-align:start!important;width:100%}ion-menu ion-content ion-list{min-height:100%;display:flex;flex-direction:column;justify-content:flex-start}ion-menu ion-content ion-list ion-menu-toggle.flex-spacer{flex:1 1 auto;display:flex;flex-direction:column;justify-content:flex-end}ion-menu ion-content ion-list ion-item.primary{--ion-item-icon-color: var(--ion-color-primary-tint);--ion-item-text-color: var(--ion-color-primary-tint)}ion-menu ion-content ion-list ion-item.secondary{--ion-item-icon-color: var(--ion-color-secondary-tint);--ion-item-text-color: var(--ion-color-secondary-tint)}ion-menu ion-content ion-list ion-item.tertiary{--ion-item-icon-color: var(--ion-color-tertiary-tint);--ion-item-text-color: var(--ion-color-tertiary-tint)}ion-menu ion-content ion-list ion-item.danger{--ion-item-icon-color: var(--ion-color-danger-tint);--ion-item-text-color: var(--ion-color-danger-tint)}ion-menu ion-content ion-list ion-item.medium{--ion-item-icon-color: var(--ion-color-medium-shade);--ion-item-text-color: var(--ion-color-medium-shade)}ion-menu ion-content ion-list ion-item.dark{--ion-item-icon-color: var(--ion-color-dark-tint);--ion-item-text-color: var(--ion-color-dark-tint)}ion-menu ion-content ion-list ion-item mat-icon,ion-menu ion-content ion-list ion-item ion-icon{color:var(--ion-item-icon-color)!important;fill:currentColor;stroke:currentColor}ion-menu ion-content ion-list ion-item ion-text,ion-menu ion-content ion-list ion-item ion-label{color:var(--ion-item-text-color)!important}ion-menu ion-content ion-list ion-item span{margin-left:var(--menu-item-margin)}ion-menu ion-content ion-list ion-item.selected{background-color:var(--ion-item-background-selected)!important;--color-hover: var(--ion-item-background-selected) !important}ion-menu ion-content ion-list ion-item.selected mat-icon,ion-menu ion-content ion-list ion-item.selected ion-icon{color:var(--ion-item-icon-color-selected)!important;fill:currentColor;stroke:currentColor}ion-menu ion-content ion-list ion-item.selected ion-text,ion-menu ion-content ion-list ion-item.selected ion-label{color:var(--ion-item-text-color-selected)!important}ion-menu ion-content ion-list ion-item.selected:hover{--color-hover: var(--ion-item-background-selected) !important;--ion-item-icon-color-selected: var(--ion-item-icon-color) !important;--ion-item-text-color-selected: var(--ion-item-text-color) !important}ion-menu ion-content ion-list ion-item.selected.menu-item-sub{background-color:var(--menu-item-background-selected-sub)!important}ion-menu ion-content ion-list ion-item.menu-item-sub{--min-height: 34px;--padding-vertical: 8px;--padding-start: 8px;--padding-horizontal: 8px;--inner-border-width: var(--menu-item-border-width-sub);font-size:.8em;overflow:unset}ion-menu ion-content ion-list ion-item.menu-item-sub ion-icon[slot],ion-menu ion-content ion-list ion-item.menu-item-sub mat-icon[slot]{font-size:calc(var(--min-height) / 2 - 1px);height:calc(var(--min-height) / 2 - 1px);margin-top:calc(var(--padding-vertical) + 2px);margin-inline-end:calc(var(--padding-horizontal) + 2px);margin-bottom:calc(var(--padding-vertical) + 2px)}ion-menu ion-content ion-list ion-item.menu-item-sub ion-label{margin-top:var(--padding-vertical);margin-bottom:var(--padding-vertical)}ion-menu ion-content ion-list ion-item.menu-item-sub .item-inner{border-width:var(--inner-border-width);border-style:var(--border-style);border-color:var(--border-color);box-shadow:var(--inner-box-shadow)}ion-menu ion-content ion-list ion-item.menu-item-sub ion-button[slot=end] ion-icon[slot=icon-only]{margin:0}ion-menu ion-content ion-list ion-item.menu-item-sub ion-button[slot=end].visible-hover{opacity:0;display:none;animation:fadeinout 1s linear 1 backwards}ion-menu ion-content ion-list ion-item.menu-item-sub:hover ion-button.visible-hover{opacity:1;display:flex}ion-menu ion-content ion-list .sub-menu-container{margin-inline-start:var(--menu-item-margin-start-sub, 16px)}ion-menu ion-footer{display:block!important}ion-menu ion-footer ion-toolbar ion-title{cursor:pointer;font-size:12pt;font-weight:400;text-align:center;padding:0 8px}ion-menu ion-footer ion-toolbar ion-button{--width: 40px}@media screen and (max-width: 767px){ion-menu ion-footer{display:none!important;visibility:hidden!important}}@media screen and (min-width: 768px){ion-menu ion-scroll{overflow-y:auto!important}ion-menu .user-avatar{font-size:var(--avatar-size, 80px)!important;line-height:var(--avatar-size, 80px);height:var(--avatar-size, 80px)!important;width:var(--avatar-size, 80px)!important}ion-menu .user-logo img{max-height:var(--avatar-size, 80px)}}\n"], dependencies: [{ kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i3.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: i2.IonButton, selector: "ion-button", inputs: ["buttonType", "color", "disabled", "download", "expand", "fill", "form", "href", "mode", "rel", "routerAnimation", "routerDirection", "shape", "size", "strong", "target", "type"] }, { kind: "component", type: i2.IonButtons, selector: "ion-buttons", inputs: ["collapse"] }, { kind: "component", type: i2.IonCol, selector: "ion-col", inputs: ["offset", "offsetLg", "offsetMd", "offsetSm", "offsetXl", "offsetXs", "pull", "pullLg", "pullMd", "pullSm", "pullXl", "pullXs", "push", "pushLg", "pushMd", "pushSm", "pushXl", "pushXs", "size", "sizeLg", "sizeMd", "sizeSm", "sizeXl", "sizeXs"] }, { kind: "component", type: i2.IonContent, selector: "ion-content", inputs: ["color", "forceOverscroll", "fullscreen", "scrollEvents", "scrollX", "scrollY"] }, { kind: "component", type: i2.IonFooter, selector: "ion-footer", inputs: ["collapse", "mode", "translucent"] }, { kind: "component", type: i2.IonGrid, selector: "ion-grid", inputs: ["fixed"] }, { kind: "component", type: i2.IonHeader, selector: "ion-header", inputs: ["collapse", "mode", "translucent"] }, { kind: "component", type: i2.IonIcon, selector: "ion-icon", inputs: ["color", "flipRtl", "icon", "ios", "lazy", "md", "mode", "name", "sanitize", "size", "src"] }, { kind: "component", type: i2.IonItem, selector: "ion-item", inputs: ["button", "color", "counter", "counterFormatter", "detail", "detailIcon", "disabled", "download", "fill", "href", "lines", "mode", "rel", "routerAnimation", "routerDirection", "shape", "target", "type"] }, { kind: "component", type: i2.IonItemDivider, selector: "ion-item-divider", inputs: ["color", "mode", "sticky"] }, { kind: "component", type: i2.IonLabel, selector: "ion-label", inputs: ["color", "mode", "position"] }, { kind: "component", type: i2.IonList, selector: "ion-list", inputs: ["inset", "lines", "mode"] }, { kind: "component", type: i2.IonMenu, selector: "ion-menu", inputs: ["contentId", "disabled", "maxEdgeStart", "menuId", "side", "swipeGesture", "type"] }, { kind: "component", type: i2.IonMenuToggle, selector: "ion-menu-toggle", inputs: ["autoHide", "menu"] }, { kind: "component", type: i2.IonRow, selector: "ion-row" }, { kind: "component", type: i2.IonSkeletonText, selector: "ion-skeleton-text", inputs: ["animated"] }, { kind: "component", type: i2.IonSplitPane, selector: "ion-split-pane", inputs: ["contentId", "disabled", "when"] }, { kind: "component", type: i2.IonTitle, selector: "ion-title", inputs: ["color", "size"] }, { kind: "component", type: i2.IonToolbar, selector: "ion-toolbar", inputs: ["color", "mode"] }, { kind: "directive", type: i2.RouterLinkDelegate, selector: ":not(a):not(area)[routerLink]", inputs: ["routerDirection", "routerAnimation"] }, { kind: "component", type: i8$1.MatToolbar, selector: "mat-toolbar", inputs: ["color"], exportAs: ["matToolbar"] }, { kind: "component", type: i8.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i9.MatButton, selector: "button[mat-button], button[mat-raised-button], button[mat-icon-button], button[mat-fab], button[mat-mini-fab], button[mat-stroked-button], button[mat-flat-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { kind: "directive", type: i1$5.RouterLink, selector: ":not(a):not(area)[routerLink]", inputs: ["queryParams", "fragment", "queryParamsHandling", "state", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "directive", type: i1$5.RouterLinkActive, selector: "[routerLinkActive]", inputs: ["routerLinkActiveOptions", "ariaCurrentWhenActive", "routerLinkActive"], outputs: ["isActiveChange"], exportAs: ["routerLinkActive"] }, { kind: "directive", type: i5$2.RxFor, selector: "[rxFor][rxForOf]", inputs: ["rxForOf", "rxForTemplate", "rxForStrategy", "rxForParent", "rxForPatchZone", "rxForTrackBy", "rxForRenderCallback"] }, { kind: "directive", type: i12$3.RxIf, selector: "[rxIf]", inputs: ["rxIf", "rxIfStrategy", "rxIfElse", "rxIfThen", "rxIfSuspense", "rxIfComplete", "rxIfError", "rxIfContextTrigger", "rxIfNextTrigger", "rxIfSuspenseTrigger", "rxIfErrorTrigger", "rxIfCompleteTrigger", "rxIfParent", "rxIfPatchZone", "rxIfRenderCallback"] }, { kind: "directive", type: i13.LetDirective, selector: "[rxLet]", inputs: ["rxLet", "rxLetStrategy", "rxLetComplete", "rxLetError", "rxLetSuspense", "rxLetContextTrigger", "rxLetCompleteTrigger", "rxLetErrorTrigger", "rxLetSuspenseTrigger", "rxLetNextTrigger", "rxLetRenderCallback", "rxLetParent", "rxLetPatchZone"], outputs: ["rendered"] }, { kind: "pipe", type: i1$1.TranslatePipe, name: "translate" }], animations: [fadeInSlowAnimation], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
23921
|
+
MenuComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: MenuComponent, selector: "app-menu", inputs: { id: "id", menuId: "menuId", side: "side", contentId: "contentId", logo: "logo", appName: "appName", appVersion: "appVersion", rxStrategy: "rxStrategy" }, viewQueries: [{ propertyName: "splitPane", first: true, predicate: ["splitPane"], descendants: true, static: true }], ngImport: i0, template: "<ion-split-pane #splitPane [contentId]=\"contentId\" (swiperight)=\"onSwipeRight($event)\">\n\n <ion-menu [id]=\"id\" [menuId]=\"menuId\" [contentId]=\"contentId\">\n <ion-header>\n\n <ion-toolbar *ngIf=\"!loading && isLogin; else notLogin\"\n @fadeInSlowAnimation\n class=\"user-toolbar\">\n <ion-grid>\n <ion-row>\n <ion-col size=\"4\">\n <button type=\"button\" mat-flat-button\n class=\"user-avatar\" [class.primary]=\"!accountAvatar\"\n [style.background-image]=\"'url('+(accountAvatar||'./assets/img/person.png')+')'\"\n [routerLink]=\"['/account']\"\n routerDirection=\"root\"\n routerLinkActive=\"ion-color-primary\"\n (click)=\"close()\"\n [title]=\"'MENU.BTN_MY_ACCOUNT'|translate\">\n </button>\n </ion-col>\n <ion-col size=\"8\" class=\"user-logo\">\n <img *ngIf=\"logo; else noLogo\" src=\"{{logo}}\" [title]=\"'APP_NAME'|translate: {appName: appName}\" width=\"108px\"/>\n <ng-template #noLogo>\n <span style=\"width: 108px;\">{{appName}}</span>\n </ng-template>\n </ion-col>\n </ion-row>\n <ion-row class=\"ion-no-padding\">\n <ion-col>\n <button mat-button type=\"button\"\n [routerLink]=\"['/account']\"\n routerDirection=\"root\"\n routerLinkActive=\"ion-color-primary\"\n (click)=\"close()\"\n [title]=\"'MENU.BTN_MY_ACCOUNT'|translate\">\n <ion-label color=\"primary\" class=\"ion-text-wrap ion-text-start\">\n <h3 class=\"no-margin username\">\n <b>{{accountName}}</b>\n </h3>\n <h4>{{accountEmail}}</h4>\n </ion-label>\n </button>\n </ion-col>\n\n <!-- Insertion headerBottomRight -->\n <ion-col size=\"auto\">\n <ng-container *ngTemplateOutlet=\"headerBottomRight\"></ng-container>\n </ion-col>\n </ion-row>\n </ion-grid>\n\n </ion-toolbar>\n\n <!-- User not logged -->\n <ng-template #notLogin>\n <mat-toolbar class=\"ion-padding\"\n *ngIf=\"!loading\"\n style=\"height: unset; display: block; margin: auto; text-align: center;\">\n <img *ngIf=\"logo\" src=\"{{logo}}\" [title]=\"'APP_NAME'|translate: {appName: appName}\" width=\"150px;\" alt=\"logo\">\n <span *ngIf=\"!logo\" style=\"width: 150px\">{{appName}}</span>\n </mat-toolbar>\n </ng-template>\n </ion-header>\n\n <ion-content [class.has-user-header]=\"isLogin\">\n <!-- will close the menu, after a click, in mobile -->\n <ion-menu-toggle auto-hide=\"false\">\n <ion-list lines=\"none\" *ngIf=\"!loading\">\n <ng-container *rxFor=\"let item of menuService.dataSubject; strategy: rxStrategy; trackBy: trackByFn\">\n <ng-container *ngTemplateOutlet=\"menuItem; context: {$implicit: item, level: 0}\"></ng-container>\n </ng-container>\n </ion-list>\n </ion-menu-toggle>\n </ion-content>\n\n <ion-footer class=\"hidden-xs hidden-sm\">\n <ion-toolbar>\n\n <ion-buttons slot=\"start\">\n <ion-button mat-icon-button color=\"accent\" (click)=\"menuService.openAboutModal()\">\n <mat-icon slot=\"icon-only\">help_outline</mat-icon>\n </ion-button>\n </ion-buttons>\n\n <ion-title (click)=\"menuService.openAboutModal()\" color=\"medium\">\n {{'MENU.FOOTER_VERSION_ABOUT'| translate: {version: appVersion} }}\n </ion-title>\n\n <ion-buttons slot=\"end\">\n <button mat-icon-button color=\"accent\" (click)=\"toggleSplitPaneShow($event)\"\n class=\"hidden-xs hidden-sm hidden-md\"\n [title]=\"(splitPane.when ? 'COMMON.BTN_HIDE_MENU' : 'COMMON.BTN_SHOW_MENU') |translate\">\n <mat-icon><span>{{splitPane.when ? '«' : '»'}}</span></mat-icon>\n </button>\n </ion-buttons>\n </ion-toolbar>\n </ion-footer>\n\n </ion-menu>\n\n <ng-content></ng-content>\n\n</ion-split-pane>\n\n<ng-template #headerBottomRight>\n <ng-content select=\"[headerBottomRight]\"></ng-content>\n</ng-template>\n\n<ng-template #menuItem let-item let-level=\"level\">\n\n <!-- divider -->\n <ion-item-divider *ngIf=\"item.divider; else tappable\"\n class=\"{{item.cssClass}} {{item.color}}\"\n @fadeInSlowAnimation>\n <ion-icon slot=\"start\" *ngIf=\"item.icon\" [name]=\"item.icon\"></ion-icon>\n <mat-icon slot=\"start\" *ngIf=\"item.matIcon\">{{item.matIcon}}</mat-icon>\n <ion-label>\n <span *rxIf=\"item.$title; let title; else skeletonText\" [innerHTML]=\"title|translate\"></span>\n </ion-label>\n </ion-item-divider>\n\n <ng-template #tappable>\n\n <!-- link -->\n <ion-item *ngIf=\"item.path && !item.action\"\n @fadeInSlowAnimation\n class=\"{{item.cssClass}} {{item.color}}\"\n [class.menu-item-sub]=\"level!==0\"\n tappable\n [routerLink]=\"item.path\"\n [queryParams]=\"item.pathParams\"\n routerDirection=\"root\"\n routerLinkActive=\"selected\"\n [routerLinkActiveOptions]=\"{exact: (item.path === '/' || level !== 0)}\">\n <ion-icon slot=\"start\" *ngIf=\"item.icon\" [name]=\"item.icon\"></ion-icon>\n <mat-icon slot=\"start\" *ngIf=\"item.matIcon\">{{item.matIcon}}</mat-icon>\n <ion-label *rxLet=\"item.$title; let title\">\n <span *ngIf=\"title; else skeletonText\" [innerHTML]=\"title|translate\"></span>\n <!--<span *ngIf=\"_debug\"> {{item.id}}</span>-->\n </ion-label>\n\n <!-- pin button -->\n <ng-container *ngTemplateOutlet=\"pinButton; context: {$implicit: item, level: level}\"></ng-container>\n\n </ion-item>\n\n <!-- action -->\n <ion-item *ngIf=\"item.action\"\n @fadeInSlowAnimation\n class=\"{{item.cssClass}} {{item.color}} text-1x\"\n [class.menu-item-sub]=\"level!==0\"\n tappable\n (click)=\"executeAction($event, item)\">\n <ion-icon slot=\"start\" *ngIf=\"item.icon\" [name]=\"item.icon\"></ion-icon>\n <mat-icon slot=\"start\" *ngIf=\"item.matIcon\">{{item.matIcon}}</mat-icon>\n <ion-label>\n <span *rxIf=\"item.$title; let title; else skeletonText\" [innerHTML]=\"title|translate\"></span>\n <!--<span *ngIf=\"_debug\"> {{item.id}}</span>-->\n </ion-label>\n\n <!-- pin button -->\n <ng-container *ngTemplateOutlet=\"pinButton; context: {$implicit: item, level: level}\"></ng-container>\n </ion-item>\n </ng-template>\n\n\n\n <!-- children -->\n <div *ngIf=\"item?.$children\" class=\"sub-menu-container\">\n <ng-container *rxFor=\"let child of item.$children ; strategy: rxStrategy; trackBy: trackByFn\">\n <ng-container *ngTemplateOutlet=\"menuItem; context: {$implicit: child, level: level+1}\"></ng-container>\n </ng-container>\n </div>\n</ng-template>\n\n<ng-template #pinButton let-item>\n <!-- pin button -->\n <ion-button *ngIf=\"item.pinnable\"\n slot=\"end\"\n shape=\"round\" fill=\"clear\" size=\"small\"\n [class.visible-hover]=\"!item.pinned\"\n (click)=\"togglePinned($event, item)\">\n <ion-icon slot=\"icon-only\" [name]=\"item.pinned ? 'pin' : 'pin-outline'\"></ion-icon>\n </ion-button>\n</ng-template>\n\n<ng-template #skeletonText let-width let-animated>\n <ion-skeleton-text [animated]=\"animated\" [style.width.%]=\"width || 60\"></ion-skeleton-text>\n</ng-template>\n", styles: ["@keyframes fadeinout{0%{opacity:0;display:none}75%{opacity:0;display:none}to{opacity:1;display:flex}}ion-menu{--menu-item-margin: 0;--ion-item-background: transparent;--ion-item-divider-background: transparent;--ion-item-icon-color: var(--ion-color-primary-tint);--ion-item-text-color: var(--ion-color-primary-tint);--ion-item-background-selected: var(--ion-color-secondary100);--ion-item-text-color-selected: var(--ion-color-primary);--ion-item-icon-color-selected: var(--ion-color-primary);--ion-item-text-color-disable: var(--ion-color-medium);--ion-item-icon-color-disable: var(--ion-color-medium);--menu-item-background-selected-sub: var(--ion-color-secondary50);--menu-item-border-width-sub: 0 0 1px 0;--menu-item-margin-start-sub: 16px}ion-menu ion-header ion-text{color:var(--ion-color-primary)}ion-menu ion-header ion-toolbar.user-toolbar{--ion-toolbar-height: 128px}ion-menu ion-header .user-avatar{background-size:cover;background-repeat:no-repeat;background-position:center;background-color:var(--ion-color-secondary);border:solid 1px rgba(var(--ion-color-secondary-rgb),.5);overflow:hidden!important;font-size:var(--avatar-size, 60px)!important;line-height:var(--avatar-size, 60px);height:var(--avatar-size, 60px)!important;width:var(--avatar-size, 60px)!important;border-radius:50%;display:inline-block}ion-menu ion-header .user-avatar:hover{background-color:var(--ion-color-secondary-shade);border:solid 2px var(--ion-color-secondary-shade)}ion-menu ion-header .user-logo{text-align:right}ion-menu ion-header .user-logo img{max-width:120px;max-height:var(--avatar-size, 60px);width:auto}ion-menu ion-header .username{padding-top:0;margin-top:0;margin-bottom:0;width:100%;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}ion-menu ion-header button[mat-button]{padding:0;text-align:start!important;width:100%}ion-menu ion-content ion-list{min-height:100%;display:flex;flex-direction:column;justify-content:flex-start}ion-menu ion-content ion-list ion-menu-toggle.flex-spacer{flex:1 1 auto;display:flex;flex-direction:column;justify-content:flex-end}ion-menu ion-content ion-list ion-item.primary{--ion-item-icon-color: var(--ion-color-primary-tint);--ion-item-text-color: var(--ion-color-primary-tint)}ion-menu ion-content ion-list ion-item.secondary{--ion-item-icon-color: var(--ion-color-secondary-tint);--ion-item-text-color: var(--ion-color-secondary-tint)}ion-menu ion-content ion-list ion-item.tertiary{--ion-item-icon-color: var(--ion-color-tertiary-tint);--ion-item-text-color: var(--ion-color-tertiary-tint)}ion-menu ion-content ion-list ion-item.danger{--ion-item-icon-color: var(--ion-color-danger-tint);--ion-item-text-color: var(--ion-color-danger-tint)}ion-menu ion-content ion-list ion-item.medium{--ion-item-icon-color: var(--ion-color-medium-shade);--ion-item-text-color: var(--ion-color-medium-shade)}ion-menu ion-content ion-list ion-item.dark{--ion-item-icon-color: var(--ion-color-dark-tint);--ion-item-text-color: var(--ion-color-dark-tint)}ion-menu ion-content ion-list ion-item mat-icon,ion-menu ion-content ion-list ion-item ion-icon{color:var(--ion-item-icon-color)!important;fill:currentColor;stroke:currentColor}ion-menu ion-content ion-list ion-item ion-text,ion-menu ion-content ion-list ion-item ion-label{color:var(--ion-item-text-color)!important}ion-menu ion-content ion-list ion-item span{margin-left:var(--menu-item-margin)}ion-menu ion-content ion-list ion-item.selected{background-color:var(--ion-item-background-selected)!important;--color-hover: var(--ion-item-background-selected) !important}ion-menu ion-content ion-list ion-item.selected mat-icon,ion-menu ion-content ion-list ion-item.selected ion-icon{color:var(--ion-item-icon-color-selected)!important;fill:currentColor;stroke:currentColor}ion-menu ion-content ion-list ion-item.selected ion-text,ion-menu ion-content ion-list ion-item.selected ion-label{color:var(--ion-item-text-color-selected)!important}ion-menu ion-content ion-list ion-item.selected:hover{--color-hover: var(--ion-item-background-selected) !important;--ion-item-icon-color-selected: var(--ion-item-icon-color) !important;--ion-item-text-color-selected: var(--ion-item-text-color) !important}ion-menu ion-content ion-list ion-item.selected.menu-item-sub{background-color:var(--menu-item-background-selected-sub)!important}ion-menu ion-content ion-list ion-item.menu-item-sub{--min-height: 34px;--padding-vertical: 8px;--padding-start: 8px;--padding-horizontal: 8px;--inner-border-width: var(--menu-item-border-width-sub);font-size:.8em;overflow:unset}ion-menu ion-content ion-list ion-item.menu-item-sub ion-icon[slot],ion-menu ion-content ion-list ion-item.menu-item-sub mat-icon[slot]{font-size:calc(var(--min-height) / 2 - 1px);height:calc(var(--min-height) / 2 - 1px);margin-top:calc(var(--padding-vertical) + 2px);margin-inline-end:calc(var(--padding-horizontal) + 2px);margin-bottom:calc(var(--padding-vertical) + 2px)}ion-menu ion-content ion-list ion-item.menu-item-sub ion-label{margin-top:var(--padding-vertical);margin-bottom:var(--padding-vertical)}ion-menu ion-content ion-list ion-item.menu-item-sub .item-inner{border-width:var(--inner-border-width);border-style:var(--border-style);border-color:var(--border-color);box-shadow:var(--inner-box-shadow)}ion-menu ion-content ion-list ion-item.menu-item-sub ion-button[slot=end] ion-icon[slot=icon-only]{margin:0}ion-menu ion-content ion-list ion-item.menu-item-sub ion-button[slot=end].visible-hover{opacity:0;display:none;animation:fadeinout 1s linear 1 backwards}ion-menu ion-content ion-list ion-item.menu-item-sub:hover ion-button.visible-hover{opacity:1;display:flex}ion-menu ion-content ion-list .sub-menu-container{margin-inline-start:var(--menu-item-margin-start-sub, 16px)}ion-menu ion-footer{display:block!important}ion-menu ion-footer ion-toolbar ion-title{cursor:pointer;font-size:12pt;font-weight:400;text-align:center;padding:0 8px}ion-menu ion-footer ion-toolbar ion-button{--width: 40px}@media screen and (max-width: 767px){ion-menu ion-footer{display:none!important;visibility:hidden!important}}@media screen and (min-width: 768px){ion-menu ion-scroll{overflow-y:auto!important}ion-menu .user-avatar{font-size:var(--avatar-size, 80px)!important;line-height:var(--avatar-size, 80px);height:var(--avatar-size, 80px)!important;width:var(--avatar-size, 80px)!important}ion-menu .user-logo img{max-height:var(--avatar-size, 80px)}}\n"], dependencies: [{ kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i3.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: i2.IonButton, selector: "ion-button", inputs: ["buttonType", "color", "disabled", "download", "expand", "fill", "form", "href", "mode", "rel", "routerAnimation", "routerDirection", "shape", "size", "strong", "target", "type"] }, { kind: "component", type: i2.IonButtons, selector: "ion-buttons", inputs: ["collapse"] }, { kind: "component", type: i2.IonCol, selector: "ion-col", inputs: ["offset", "offsetLg", "offsetMd", "offsetSm", "offsetXl", "offsetXs", "pull", "pullLg", "pullMd", "pullSm", "pullXl", "pullXs", "push", "pushLg", "pushMd", "pushSm", "pushXl", "pushXs", "size", "sizeLg", "sizeMd", "sizeSm", "sizeXl", "sizeXs"] }, { kind: "component", type: i2.IonContent, selector: "ion-content", inputs: ["color", "forceOverscroll", "fullscreen", "scrollEvents", "scrollX", "scrollY"] }, { kind: "component", type: i2.IonFooter, selector: "ion-footer", inputs: ["collapse", "mode", "translucent"] }, { kind: "component", type: i2.IonGrid, selector: "ion-grid", inputs: ["fixed"] }, { kind: "component", type: i2.IonHeader, selector: "ion-header", inputs: ["collapse", "mode", "translucent"] }, { kind: "component", type: i2.IonIcon, selector: "ion-icon", inputs: ["color", "flipRtl", "icon", "ios", "lazy", "md", "mode", "name", "sanitize", "size", "src"] }, { kind: "component", type: i2.IonItem, selector: "ion-item", inputs: ["button", "color", "counter", "counterFormatter", "detail", "detailIcon", "disabled", "download", "fill", "href", "lines", "mode", "rel", "routerAnimation", "routerDirection", "shape", "target", "type"] }, { kind: "component", type: i2.IonItemDivider, selector: "ion-item-divider", inputs: ["color", "mode", "sticky"] }, { kind: "component", type: i2.IonLabel, selector: "ion-label", inputs: ["color", "mode", "position"] }, { kind: "component", type: i2.IonList, selector: "ion-list", inputs: ["inset", "lines", "mode"] }, { kind: "component", type: i2.IonMenu, selector: "ion-menu", inputs: ["contentId", "disabled", "maxEdgeStart", "menuId", "side", "swipeGesture", "type"] }, { kind: "component", type: i2.IonMenuToggle, selector: "ion-menu-toggle", inputs: ["autoHide", "menu"] }, { kind: "component", type: i2.IonRow, selector: "ion-row" }, { kind: "component", type: i2.IonSkeletonText, selector: "ion-skeleton-text", inputs: ["animated"] }, { kind: "component", type: i2.IonSplitPane, selector: "ion-split-pane", inputs: ["contentId", "disabled", "when"] }, { kind: "component", type: i2.IonTitle, selector: "ion-title", inputs: ["color", "size"] }, { kind: "component", type: i2.IonToolbar, selector: "ion-toolbar", inputs: ["color", "mode"] }, { kind: "directive", type: i2.RouterLinkDelegate, selector: ":not(a):not(area)[routerLink]", inputs: ["routerDirection", "routerAnimation"] }, { kind: "component", type: i8$1.MatToolbar, selector: "mat-toolbar", inputs: ["color"], exportAs: ["matToolbar"] }, { kind: "component", type: i8.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i9.MatButton, selector: "button[mat-button], button[mat-raised-button], button[mat-icon-button], button[mat-fab], button[mat-mini-fab], button[mat-stroked-button], button[mat-flat-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { kind: "directive", type: i1$5.RouterLink, selector: ":not(a):not(area)[routerLink]", inputs: ["queryParams", "fragment", "queryParamsHandling", "state", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "directive", type: i1$5.RouterLinkActive, selector: "[routerLinkActive]", inputs: ["routerLinkActiveOptions", "ariaCurrentWhenActive", "routerLinkActive"], outputs: ["isActiveChange"], exportAs: ["routerLinkActive"] }, { kind: "directive", type: i5$2.RxFor, selector: "[rxFor][rxForOf]", inputs: ["rxForOf", "rxForTemplate", "rxForStrategy", "rxForParent", "rxForPatchZone", "rxForTrackBy", "rxForRenderCallback"] }, { kind: "directive", type: i12$3.RxIf, selector: "[rxIf]", inputs: ["rxIf", "rxIfStrategy", "rxIfElse", "rxIfThen", "rxIfSuspense", "rxIfComplete", "rxIfError", "rxIfContextTrigger", "rxIfNextTrigger", "rxIfSuspenseTrigger", "rxIfErrorTrigger", "rxIfCompleteTrigger", "rxIfParent", "rxIfPatchZone", "rxIfRenderCallback"] }, { kind: "directive", type: i13.LetDirective, selector: "[rxLet]", inputs: ["rxLet", "rxLetStrategy", "rxLetComplete", "rxLetError", "rxLetSuspense", "rxLetContextTrigger", "rxLetCompleteTrigger", "rxLetErrorTrigger", "rxLetSuspenseTrigger", "rxLetNextTrigger", "rxLetRenderCallback", "rxLetParent", "rxLetPatchZone"], outputs: ["rendered"] }, { kind: "pipe", type: i1$1.TranslatePipe, name: "translate" }], animations: [fadeInSlowAnimation], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
23812
23922
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: MenuComponent, decorators: [{
|
|
23813
23923
|
type: Component,
|
|
23814
|
-
args: [{ selector: 'app-menu', animations: [fadeInSlowAnimation], changeDetection: ChangeDetectionStrategy.OnPush, template: "<ion-split-pane #splitPane [contentId]=\"contentId\" (swiperight)=\"onSwipeRight($event)\">\n\n <ion-menu [id]=\"id\" [menuId]=\"menuId\" [contentId]=\"contentId\">\n <ion-header>\n\n <ion-toolbar *ngIf=\"!loading && isLogin; else notLogin\"\n @fadeInSlowAnimation\n class=\"user-toolbar\">\n <ion-grid>\n <ion-row>\n <ion-col size=\"4\">\n <button type=\"button\" mat-flat-button\n class=\"user-avatar\" [class.primary]=\"!accountAvatar\"\n [style.background-image]=\"'url('+(accountAvatar||'./assets/img/person.png')+')'\"\n [routerLink]=\"['/account']\"\n routerDirection=\"root\"\n routerLinkActive=\"ion-color-primary\"\n (click)=\"close()\"\n [title]=\"'MENU.BTN_MY_ACCOUNT'|translate\">\n </button>\n </ion-col>\n <ion-col size=\"8\" class=\"user-logo\">\n <img *ngIf=\"logo; else noLogo\" src=\"{{logo}}\" [title]=\"'APP_NAME'|translate: {appName: appName}\" width=\"108px\"/>\n <ng-template #noLogo>\n <span style=\"width: 108px;\">{{appName}}</span>\n </ng-template>\n </ion-col>\n </ion-row>\n <ion-row class=\"ion-no-padding\">\n <ion-col>\n <button mat-button type=\"button\"\n [routerLink]=\"['/account']\"\n routerDirection=\"root\"\n routerLinkActive=\"ion-color-primary\"\n (click)=\"close()\"\n [title]=\"'MENU.BTN_MY_ACCOUNT'|translate\">\n <ion-label color=\"primary\" class=\"ion-text-wrap ion-text-start\">\n <h3 class=\"no-margin username\">\n <b>{{accountName}}</b>\n </h3>\n <h4>{{accountEmail}}</h4>\n </ion-label>\n </button>\n </ion-col>\n\n <!-- Insertion headerBottomRight -->\n <ion-col size=\"auto\">\n <ng-container *ngTemplateOutlet=\"headerBottomRight\"></ng-container>\n </ion-col>\n </ion-row>\n </ion-grid>\n\n </ion-toolbar>\n\n <!-- User not logged -->\n <ng-template #notLogin>\n <mat-toolbar class=\"ion-padding\"\n *ngIf=\"!loading\"\n style=\"height: unset; display: block; margin: auto; text-align: center;\">\n <img *ngIf=\"logo\" src=\"{{logo}}\" [title]=\"'APP_NAME'|translate: {appName: appName}\" width=\"150px;\" alt=\"logo\">\n <span *ngIf=\"!logo\" style=\"width: 150px\">{{appName}}</span>\n </mat-toolbar>\n </ng-template>\n </ion-header>\n\n <ion-content [class.has-user-header]=\"isLogin\">\n <!-- will close the menu, after a click, in mobile -->\n <ion-menu-toggle auto-hide=\"false\">\n <ion-list lines=\"none\" *ngIf=\"!loading\">\n <ng-container *rxFor=\"let item of menuService.dataSubject; strategy: rxStrategy; trackBy: trackByFn\">\n <ng-container *ngTemplateOutlet=\"menuItem; context: {$implicit: item, level: 0}\"></ng-container>\n </ng-container>\n </ion-list>\n </ion-menu-toggle>\n </ion-content>\n\n <ion-footer class=\"hidden-xs hidden-sm\">\n <ion-toolbar>\n\n <ion-buttons slot=\"start\">\n <ion-button mat-icon-button color=\"accent\" (click)=\"openAboutModal($event)\">\n <mat-icon slot=\"icon-only\">help_outline</mat-icon>\n </ion-button>\n </ion-buttons>\n\n <ion-title (click)=\"openAboutModal($event)\" color=\"medium\">\n {{'MENU.FOOTER_VERSION_ABOUT'| translate: {version: appVersion} }}\n </ion-title>\n\n <ion-buttons slot=\"end\">\n <button mat-icon-button color=\"accent\" (click)=\"toggleSplitPaneShow($event)\"\n class=\"hidden-xs hidden-sm hidden-md\"\n [title]=\"(splitPane.when ? 'COMMON.BTN_HIDE_MENU' : 'COMMON.BTN_SHOW_MENU') |translate\">\n <mat-icon><span>{{splitPane.when ? '«' : '»'}}</span></mat-icon>\n </button>\n </ion-buttons>\n </ion-toolbar>\n </ion-footer>\n\n </ion-menu>\n\n <ng-content></ng-content>\n\n</ion-split-pane>\n\n<ng-template #headerBottomRight>\n <ng-content select=\"[headerBottomRight]\"></ng-content>\n</ng-template>\n\n<ng-template #menuItem let-item let-level=\"level\">\n <!-- link -->\n <ion-item *ngIf=\"item.path && !item.action\"\n @fadeInSlowAnimation\n class=\"{{item.cssClass}} {{item.color}}\"\n [class.menu-item-sub]=\"level!==0\"\n tappable\n [routerLink]=\"item.path\"\n [queryParams]=\"item.pathParams\"\n routerDirection=\"root\"\n routerLinkActive=\"selected\"\n [routerLinkActiveOptions]=\"{exact: (item.path === '/' || level !== 0)}\">\n <ion-icon slot=\"start\" *ngIf=\"item.icon\" [name]=\"item.icon\"></ion-icon>\n <mat-icon slot=\"start\" *ngIf=\"item.matIcon\">{{item.matIcon}}</mat-icon>\n <ion-label *rxLet=\"item.$title; let title\">\n <span *ngIf=\"title; else skeletonText\" [innerHTML]=\"title|translate\"></span>\n <!--<span *ngIf=\"_debug\"> {{item.id}}</span>-->\n </ion-label>\n\n <!-- pin button -->\n <ng-container *ngTemplateOutlet=\"pinButton; context: {$implicit: item, level: level}\"></ng-container>\n\n </ion-item>\n\n <!-- action -->\n <ion-item *ngIf=\"item.action\"\n @fadeInSlowAnimation\n class=\"{{item.cssClass}} {{item.color}} text-1x\"\n [class.menu-item-sub]=\"level!==0\"\n tappable\n (click)=\"doAction(item.action, $event)\">\n <ion-icon slot=\"start\" *ngIf=\"item.icon\" [name]=\"item.icon\"></ion-icon>\n <mat-icon slot=\"start\" *ngIf=\"item.matIcon\">{{item.matIcon}}</mat-icon>\n <ion-label>\n <span *rxIf=\"item.$title; let title; else skeletonText\" [innerHTML]=\"title|translate\"></span>\n <!--<span *ngIf=\"_debug\"> {{item.id}}</span>-->\n </ion-label>\n\n <!-- pin button -->\n <ng-container *ngTemplateOutlet=\"pinButton; context: {$implicit: item, level: level}\"></ng-container>\n </ion-item>\n\n <!-- divider -->\n <ion-item-divider @fadeInSlowAnimation\n class=\"{{item.cssClass}} {{item.color}}\"\n *ngIf=\"!item.path && !item.action\">\n <ion-label>\n <span *rxIf=\"item.$title; let title; else skeletonText\" [innerHTML]=\"title|translate\"></span>\n </ion-label>\n </ion-item-divider>\n\n <!-- children -->\n <div *ngIf=\"item?.$children\" class=\"sub-menu-container\">\n <ng-container *rxFor=\"let child of item.$children ; strategy: rxStrategy; trackBy: trackByFn\">\n <ng-container *ngTemplateOutlet=\"menuItem; context: {$implicit: child, level: level+1}\"></ng-container>\n </ng-container>\n </div>\n</ng-template>\n\n<ng-template #pinButton let-item let-level=\"level\">\n <!-- pin button -->\n <ion-button *ngIf=\"level > 0\"\n slot=\"end\"\n shape=\"round\" fill=\"clear\" size=\"small\"\n [class.visible-hover]=\"!item.pinned\"\n (click)=\"togglePinned($event, item)\">\n <ion-icon slot=\"icon-only\" [name]=\"item.pinned ? 'pin' : 'pin-outline'\"></ion-icon>\n </ion-button>\n</ng-template>\n\n<ng-template #skeletonText let-width let-animated>\n <ion-skeleton-text [animated]=\"animated\" [style.width.%]=\"width || 60\"></ion-skeleton-text>\n</ng-template>\n", styles: ["@keyframes fadeinout{0%{opacity:0;display:none}75%{opacity:0;display:none}to{opacity:1;display:flex}}ion-menu{--menu-item-margin: 0;--ion-item-background: transparent;--ion-item-divider-background: transparent;--ion-item-icon-color: var(--ion-color-primary-tint);--ion-item-text-color: var(--ion-color-primary-tint);--ion-item-background-selected: var(--ion-color-secondary100);--ion-item-text-color-selected: var(--ion-color-primary);--ion-item-icon-color-selected: var(--ion-color-primary);--ion-item-text-color-disable: var(--ion-color-medium);--ion-item-icon-color-disable: var(--ion-color-medium);--menu-item-background-selected-sub: var(--ion-color-secondary50);--menu-item-border-width-sub: 0 0 1px 0;--menu-item-margin-start-sub: 16px}ion-menu ion-header ion-text{color:var(--ion-color-primary)}ion-menu ion-header ion-toolbar.user-toolbar{--ion-toolbar-height: 128px}ion-menu ion-header .user-avatar{background-size:cover;background-repeat:no-repeat;background-position:center;background-color:var(--ion-color-secondary);border:solid 1px rgba(var(--ion-color-secondary-rgb),.5);overflow:hidden!important;font-size:var(--avatar-size, 60px)!important;line-height:var(--avatar-size, 60px);height:var(--avatar-size, 60px)!important;width:var(--avatar-size, 60px)!important;border-radius:50%;display:inline-block}ion-menu ion-header .user-avatar:hover{background-color:var(--ion-color-secondary-shade);border:solid 2px var(--ion-color-secondary-shade)}ion-menu ion-header .user-logo{text-align:right}ion-menu ion-header .user-logo img{max-width:120px;max-height:var(--avatar-size, 60px);width:auto}ion-menu ion-header .username{padding-top:0;margin-top:0;margin-bottom:0;width:100%;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}ion-menu ion-header button[mat-button]{padding:0;text-align:start!important;width:100%}ion-menu ion-content ion-list{min-height:100%;display:flex;flex-direction:column;justify-content:flex-start}ion-menu ion-content ion-list ion-menu-toggle.flex-spacer{flex:1 1 auto;display:flex;flex-direction:column;justify-content:flex-end}ion-menu ion-content ion-list ion-item.primary{--ion-item-icon-color: var(--ion-color-primary-tint);--ion-item-text-color: var(--ion-color-primary-tint)}ion-menu ion-content ion-list ion-item.secondary{--ion-item-icon-color: var(--ion-color-secondary-tint);--ion-item-text-color: var(--ion-color-secondary-tint)}ion-menu ion-content ion-list ion-item.tertiary{--ion-item-icon-color: var(--ion-color-tertiary-tint);--ion-item-text-color: var(--ion-color-tertiary-tint)}ion-menu ion-content ion-list ion-item.danger{--ion-item-icon-color: var(--ion-color-danger-tint);--ion-item-text-color: var(--ion-color-danger-tint)}ion-menu ion-content ion-list ion-item.medium{--ion-item-icon-color: var(--ion-color-medium-shade);--ion-item-text-color: var(--ion-color-medium-shade)}ion-menu ion-content ion-list ion-item.dark{--ion-item-icon-color: var(--ion-color-dark-tint);--ion-item-text-color: var(--ion-color-dark-tint)}ion-menu ion-content ion-list ion-item mat-icon,ion-menu ion-content ion-list ion-item ion-icon{color:var(--ion-item-icon-color)!important;fill:currentColor;stroke:currentColor}ion-menu ion-content ion-list ion-item ion-text,ion-menu ion-content ion-list ion-item ion-label{color:var(--ion-item-text-color)!important}ion-menu ion-content ion-list ion-item span{margin-left:var(--menu-item-margin)}ion-menu ion-content ion-list ion-item.selected{background-color:var(--ion-item-background-selected)!important;--color-hover: var(--ion-item-background-selected) !important}ion-menu ion-content ion-list ion-item.selected mat-icon,ion-menu ion-content ion-list ion-item.selected ion-icon{color:var(--ion-item-icon-color-selected)!important;fill:currentColor;stroke:currentColor}ion-menu ion-content ion-list ion-item.selected ion-text,ion-menu ion-content ion-list ion-item.selected ion-label{color:var(--ion-item-text-color-selected)!important}ion-menu ion-content ion-list ion-item.selected:hover{--color-hover: var(--ion-item-background-selected) !important;--ion-item-icon-color-selected: var(--ion-item-icon-color) !important;--ion-item-text-color-selected: var(--ion-item-text-color) !important}ion-menu ion-content ion-list ion-item.selected.menu-item-sub{background-color:var(--menu-item-background-selected-sub)!important}ion-menu ion-content ion-list ion-item.menu-item-sub{--min-height: 34px;--padding-vertical: 8px;--padding-start: 8px;--padding-horizontal: 8px;--inner-border-width: var(--menu-item-border-width-sub);font-size:.8em;overflow:unset}ion-menu ion-content ion-list ion-item.menu-item-sub ion-icon[slot],ion-menu ion-content ion-list ion-item.menu-item-sub mat-icon[slot]{font-size:calc(var(--min-height) / 2 - 1px);height:calc(var(--min-height) / 2 - 1px);margin-top:calc(var(--padding-vertical) + 2px);margin-inline-end:calc(var(--padding-horizontal) + 2px);margin-bottom:calc(var(--padding-vertical) + 2px)}ion-menu ion-content ion-list ion-item.menu-item-sub ion-label{margin-top:var(--padding-vertical);margin-bottom:var(--padding-vertical)}ion-menu ion-content ion-list ion-item.menu-item-sub .item-inner{border-width:var(--inner-border-width);border-style:var(--border-style);border-color:var(--border-color);box-shadow:var(--inner-box-shadow)}ion-menu ion-content ion-list ion-item.menu-item-sub ion-button[slot=end] ion-icon[slot=icon-only]{margin:0}ion-menu ion-content ion-list ion-item.menu-item-sub ion-button[slot=end].visible-hover{opacity:0;display:none;animation:fadeinout 1s linear 1 backwards}ion-menu ion-content ion-list ion-item.menu-item-sub:hover ion-button.visible-hover{opacity:1;display:flex}ion-menu ion-content ion-list .sub-menu-container{margin-inline-start:var(--menu-item-margin-start-sub, 16px)}ion-menu ion-footer{display:block!important}ion-menu ion-footer ion-toolbar ion-title{cursor:pointer;font-size:12pt;font-weight:400;text-align:center;padding:0 8px}ion-menu ion-footer ion-toolbar ion-button{--width: 40px}@media screen and (max-width: 767px){ion-menu ion-footer{display:none!important;visibility:hidden!important}}@media screen and (min-width: 768px){ion-menu ion-scroll{overflow-y:auto!important}ion-menu .user-avatar{font-size:var(--avatar-size, 80px)!important;line-height:var(--avatar-size, 80px);height:var(--avatar-size, 80px)!important;width:var(--avatar-size, 80px)!important}ion-menu .user-logo img{max-height:var(--avatar-size, 80px)}}\n"] }]
|
|
23924
|
+
args: [{ selector: 'app-menu', animations: [fadeInSlowAnimation], changeDetection: ChangeDetectionStrategy.OnPush, template: "<ion-split-pane #splitPane [contentId]=\"contentId\" (swiperight)=\"onSwipeRight($event)\">\n\n <ion-menu [id]=\"id\" [menuId]=\"menuId\" [contentId]=\"contentId\">\n <ion-header>\n\n <ion-toolbar *ngIf=\"!loading && isLogin; else notLogin\"\n @fadeInSlowAnimation\n class=\"user-toolbar\">\n <ion-grid>\n <ion-row>\n <ion-col size=\"4\">\n <button type=\"button\" mat-flat-button\n class=\"user-avatar\" [class.primary]=\"!accountAvatar\"\n [style.background-image]=\"'url('+(accountAvatar||'./assets/img/person.png')+')'\"\n [routerLink]=\"['/account']\"\n routerDirection=\"root\"\n routerLinkActive=\"ion-color-primary\"\n (click)=\"close()\"\n [title]=\"'MENU.BTN_MY_ACCOUNT'|translate\">\n </button>\n </ion-col>\n <ion-col size=\"8\" class=\"user-logo\">\n <img *ngIf=\"logo; else noLogo\" src=\"{{logo}}\" [title]=\"'APP_NAME'|translate: {appName: appName}\" width=\"108px\"/>\n <ng-template #noLogo>\n <span style=\"width: 108px;\">{{appName}}</span>\n </ng-template>\n </ion-col>\n </ion-row>\n <ion-row class=\"ion-no-padding\">\n <ion-col>\n <button mat-button type=\"button\"\n [routerLink]=\"['/account']\"\n routerDirection=\"root\"\n routerLinkActive=\"ion-color-primary\"\n (click)=\"close()\"\n [title]=\"'MENU.BTN_MY_ACCOUNT'|translate\">\n <ion-label color=\"primary\" class=\"ion-text-wrap ion-text-start\">\n <h3 class=\"no-margin username\">\n <b>{{accountName}}</b>\n </h3>\n <h4>{{accountEmail}}</h4>\n </ion-label>\n </button>\n </ion-col>\n\n <!-- Insertion headerBottomRight -->\n <ion-col size=\"auto\">\n <ng-container *ngTemplateOutlet=\"headerBottomRight\"></ng-container>\n </ion-col>\n </ion-row>\n </ion-grid>\n\n </ion-toolbar>\n\n <!-- User not logged -->\n <ng-template #notLogin>\n <mat-toolbar class=\"ion-padding\"\n *ngIf=\"!loading\"\n style=\"height: unset; display: block; margin: auto; text-align: center;\">\n <img *ngIf=\"logo\" src=\"{{logo}}\" [title]=\"'APP_NAME'|translate: {appName: appName}\" width=\"150px;\" alt=\"logo\">\n <span *ngIf=\"!logo\" style=\"width: 150px\">{{appName}}</span>\n </mat-toolbar>\n </ng-template>\n </ion-header>\n\n <ion-content [class.has-user-header]=\"isLogin\">\n <!-- will close the menu, after a click, in mobile -->\n <ion-menu-toggle auto-hide=\"false\">\n <ion-list lines=\"none\" *ngIf=\"!loading\">\n <ng-container *rxFor=\"let item of menuService.dataSubject; strategy: rxStrategy; trackBy: trackByFn\">\n <ng-container *ngTemplateOutlet=\"menuItem; context: {$implicit: item, level: 0}\"></ng-container>\n </ng-container>\n </ion-list>\n </ion-menu-toggle>\n </ion-content>\n\n <ion-footer class=\"hidden-xs hidden-sm\">\n <ion-toolbar>\n\n <ion-buttons slot=\"start\">\n <ion-button mat-icon-button color=\"accent\" (click)=\"menuService.openAboutModal()\">\n <mat-icon slot=\"icon-only\">help_outline</mat-icon>\n </ion-button>\n </ion-buttons>\n\n <ion-title (click)=\"menuService.openAboutModal()\" color=\"medium\">\n {{'MENU.FOOTER_VERSION_ABOUT'| translate: {version: appVersion} }}\n </ion-title>\n\n <ion-buttons slot=\"end\">\n <button mat-icon-button color=\"accent\" (click)=\"toggleSplitPaneShow($event)\"\n class=\"hidden-xs hidden-sm hidden-md\"\n [title]=\"(splitPane.when ? 'COMMON.BTN_HIDE_MENU' : 'COMMON.BTN_SHOW_MENU') |translate\">\n <mat-icon><span>{{splitPane.when ? '«' : '»'}}</span></mat-icon>\n </button>\n </ion-buttons>\n </ion-toolbar>\n </ion-footer>\n\n </ion-menu>\n\n <ng-content></ng-content>\n\n</ion-split-pane>\n\n<ng-template #headerBottomRight>\n <ng-content select=\"[headerBottomRight]\"></ng-content>\n</ng-template>\n\n<ng-template #menuItem let-item let-level=\"level\">\n\n <!-- divider -->\n <ion-item-divider *ngIf=\"item.divider; else tappable\"\n class=\"{{item.cssClass}} {{item.color}}\"\n @fadeInSlowAnimation>\n <ion-icon slot=\"start\" *ngIf=\"item.icon\" [name]=\"item.icon\"></ion-icon>\n <mat-icon slot=\"start\" *ngIf=\"item.matIcon\">{{item.matIcon}}</mat-icon>\n <ion-label>\n <span *rxIf=\"item.$title; let title; else skeletonText\" [innerHTML]=\"title|translate\"></span>\n </ion-label>\n </ion-item-divider>\n\n <ng-template #tappable>\n\n <!-- link -->\n <ion-item *ngIf=\"item.path && !item.action\"\n @fadeInSlowAnimation\n class=\"{{item.cssClass}} {{item.color}}\"\n [class.menu-item-sub]=\"level!==0\"\n tappable\n [routerLink]=\"item.path\"\n [queryParams]=\"item.pathParams\"\n routerDirection=\"root\"\n routerLinkActive=\"selected\"\n [routerLinkActiveOptions]=\"{exact: (item.path === '/' || level !== 0)}\">\n <ion-icon slot=\"start\" *ngIf=\"item.icon\" [name]=\"item.icon\"></ion-icon>\n <mat-icon slot=\"start\" *ngIf=\"item.matIcon\">{{item.matIcon}}</mat-icon>\n <ion-label *rxLet=\"item.$title; let title\">\n <span *ngIf=\"title; else skeletonText\" [innerHTML]=\"title|translate\"></span>\n <!--<span *ngIf=\"_debug\"> {{item.id}}</span>-->\n </ion-label>\n\n <!-- pin button -->\n <ng-container *ngTemplateOutlet=\"pinButton; context: {$implicit: item, level: level}\"></ng-container>\n\n </ion-item>\n\n <!-- action -->\n <ion-item *ngIf=\"item.action\"\n @fadeInSlowAnimation\n class=\"{{item.cssClass}} {{item.color}} text-1x\"\n [class.menu-item-sub]=\"level!==0\"\n tappable\n (click)=\"executeAction($event, item)\">\n <ion-icon slot=\"start\" *ngIf=\"item.icon\" [name]=\"item.icon\"></ion-icon>\n <mat-icon slot=\"start\" *ngIf=\"item.matIcon\">{{item.matIcon}}</mat-icon>\n <ion-label>\n <span *rxIf=\"item.$title; let title; else skeletonText\" [innerHTML]=\"title|translate\"></span>\n <!--<span *ngIf=\"_debug\"> {{item.id}}</span>-->\n </ion-label>\n\n <!-- pin button -->\n <ng-container *ngTemplateOutlet=\"pinButton; context: {$implicit: item, level: level}\"></ng-container>\n </ion-item>\n </ng-template>\n\n\n\n <!-- children -->\n <div *ngIf=\"item?.$children\" class=\"sub-menu-container\">\n <ng-container *rxFor=\"let child of item.$children ; strategy: rxStrategy; trackBy: trackByFn\">\n <ng-container *ngTemplateOutlet=\"menuItem; context: {$implicit: child, level: level+1}\"></ng-container>\n </ng-container>\n </div>\n</ng-template>\n\n<ng-template #pinButton let-item>\n <!-- pin button -->\n <ion-button *ngIf=\"item.pinnable\"\n slot=\"end\"\n shape=\"round\" fill=\"clear\" size=\"small\"\n [class.visible-hover]=\"!item.pinned\"\n (click)=\"togglePinned($event, item)\">\n <ion-icon slot=\"icon-only\" [name]=\"item.pinned ? 'pin' : 'pin-outline'\"></ion-icon>\n </ion-button>\n</ng-template>\n\n<ng-template #skeletonText let-width let-animated>\n <ion-skeleton-text [animated]=\"animated\" [style.width.%]=\"width || 60\"></ion-skeleton-text>\n</ng-template>\n", styles: ["@keyframes fadeinout{0%{opacity:0;display:none}75%{opacity:0;display:none}to{opacity:1;display:flex}}ion-menu{--menu-item-margin: 0;--ion-item-background: transparent;--ion-item-divider-background: transparent;--ion-item-icon-color: var(--ion-color-primary-tint);--ion-item-text-color: var(--ion-color-primary-tint);--ion-item-background-selected: var(--ion-color-secondary100);--ion-item-text-color-selected: var(--ion-color-primary);--ion-item-icon-color-selected: var(--ion-color-primary);--ion-item-text-color-disable: var(--ion-color-medium);--ion-item-icon-color-disable: var(--ion-color-medium);--menu-item-background-selected-sub: var(--ion-color-secondary50);--menu-item-border-width-sub: 0 0 1px 0;--menu-item-margin-start-sub: 16px}ion-menu ion-header ion-text{color:var(--ion-color-primary)}ion-menu ion-header ion-toolbar.user-toolbar{--ion-toolbar-height: 128px}ion-menu ion-header .user-avatar{background-size:cover;background-repeat:no-repeat;background-position:center;background-color:var(--ion-color-secondary);border:solid 1px rgba(var(--ion-color-secondary-rgb),.5);overflow:hidden!important;font-size:var(--avatar-size, 60px)!important;line-height:var(--avatar-size, 60px);height:var(--avatar-size, 60px)!important;width:var(--avatar-size, 60px)!important;border-radius:50%;display:inline-block}ion-menu ion-header .user-avatar:hover{background-color:var(--ion-color-secondary-shade);border:solid 2px var(--ion-color-secondary-shade)}ion-menu ion-header .user-logo{text-align:right}ion-menu ion-header .user-logo img{max-width:120px;max-height:var(--avatar-size, 60px);width:auto}ion-menu ion-header .username{padding-top:0;margin-top:0;margin-bottom:0;width:100%;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}ion-menu ion-header button[mat-button]{padding:0;text-align:start!important;width:100%}ion-menu ion-content ion-list{min-height:100%;display:flex;flex-direction:column;justify-content:flex-start}ion-menu ion-content ion-list ion-menu-toggle.flex-spacer{flex:1 1 auto;display:flex;flex-direction:column;justify-content:flex-end}ion-menu ion-content ion-list ion-item.primary{--ion-item-icon-color: var(--ion-color-primary-tint);--ion-item-text-color: var(--ion-color-primary-tint)}ion-menu ion-content ion-list ion-item.secondary{--ion-item-icon-color: var(--ion-color-secondary-tint);--ion-item-text-color: var(--ion-color-secondary-tint)}ion-menu ion-content ion-list ion-item.tertiary{--ion-item-icon-color: var(--ion-color-tertiary-tint);--ion-item-text-color: var(--ion-color-tertiary-tint)}ion-menu ion-content ion-list ion-item.danger{--ion-item-icon-color: var(--ion-color-danger-tint);--ion-item-text-color: var(--ion-color-danger-tint)}ion-menu ion-content ion-list ion-item.medium{--ion-item-icon-color: var(--ion-color-medium-shade);--ion-item-text-color: var(--ion-color-medium-shade)}ion-menu ion-content ion-list ion-item.dark{--ion-item-icon-color: var(--ion-color-dark-tint);--ion-item-text-color: var(--ion-color-dark-tint)}ion-menu ion-content ion-list ion-item mat-icon,ion-menu ion-content ion-list ion-item ion-icon{color:var(--ion-item-icon-color)!important;fill:currentColor;stroke:currentColor}ion-menu ion-content ion-list ion-item ion-text,ion-menu ion-content ion-list ion-item ion-label{color:var(--ion-item-text-color)!important}ion-menu ion-content ion-list ion-item span{margin-left:var(--menu-item-margin)}ion-menu ion-content ion-list ion-item.selected{background-color:var(--ion-item-background-selected)!important;--color-hover: var(--ion-item-background-selected) !important}ion-menu ion-content ion-list ion-item.selected mat-icon,ion-menu ion-content ion-list ion-item.selected ion-icon{color:var(--ion-item-icon-color-selected)!important;fill:currentColor;stroke:currentColor}ion-menu ion-content ion-list ion-item.selected ion-text,ion-menu ion-content ion-list ion-item.selected ion-label{color:var(--ion-item-text-color-selected)!important}ion-menu ion-content ion-list ion-item.selected:hover{--color-hover: var(--ion-item-background-selected) !important;--ion-item-icon-color-selected: var(--ion-item-icon-color) !important;--ion-item-text-color-selected: var(--ion-item-text-color) !important}ion-menu ion-content ion-list ion-item.selected.menu-item-sub{background-color:var(--menu-item-background-selected-sub)!important}ion-menu ion-content ion-list ion-item.menu-item-sub{--min-height: 34px;--padding-vertical: 8px;--padding-start: 8px;--padding-horizontal: 8px;--inner-border-width: var(--menu-item-border-width-sub);font-size:.8em;overflow:unset}ion-menu ion-content ion-list ion-item.menu-item-sub ion-icon[slot],ion-menu ion-content ion-list ion-item.menu-item-sub mat-icon[slot]{font-size:calc(var(--min-height) / 2 - 1px);height:calc(var(--min-height) / 2 - 1px);margin-top:calc(var(--padding-vertical) + 2px);margin-inline-end:calc(var(--padding-horizontal) + 2px);margin-bottom:calc(var(--padding-vertical) + 2px)}ion-menu ion-content ion-list ion-item.menu-item-sub ion-label{margin-top:var(--padding-vertical);margin-bottom:var(--padding-vertical)}ion-menu ion-content ion-list ion-item.menu-item-sub .item-inner{border-width:var(--inner-border-width);border-style:var(--border-style);border-color:var(--border-color);box-shadow:var(--inner-box-shadow)}ion-menu ion-content ion-list ion-item.menu-item-sub ion-button[slot=end] ion-icon[slot=icon-only]{margin:0}ion-menu ion-content ion-list ion-item.menu-item-sub ion-button[slot=end].visible-hover{opacity:0;display:none;animation:fadeinout 1s linear 1 backwards}ion-menu ion-content ion-list ion-item.menu-item-sub:hover ion-button.visible-hover{opacity:1;display:flex}ion-menu ion-content ion-list .sub-menu-container{margin-inline-start:var(--menu-item-margin-start-sub, 16px)}ion-menu ion-footer{display:block!important}ion-menu ion-footer ion-toolbar ion-title{cursor:pointer;font-size:12pt;font-weight:400;text-align:center;padding:0 8px}ion-menu ion-footer ion-toolbar ion-button{--width: 40px}@media screen and (max-width: 767px){ion-menu ion-footer{display:none!important;visibility:hidden!important}}@media screen and (min-width: 768px){ion-menu ion-scroll{overflow-y:auto!important}ion-menu .user-avatar{font-size:var(--avatar-size, 80px)!important;line-height:var(--avatar-size, 80px);height:var(--avatar-size, 80px)!important;width:var(--avatar-size, 80px)!important}ion-menu .user-logo img{max-height:var(--avatar-size, 80px)}}\n"] }]
|
|
23815
23925
|
}], ctorParameters: function () { return [{ type: PlatformService }, { type: AccountService }, { type: i2.NavController }, { type: i2.MenuController }, { type: i2.ModalController }, { type: i2.AlertController }, { type: i1$1.TranslateService }, { type: i0.ChangeDetectorRef }, { type: MenuService }, { type: i1$5.Router }, { type: undefined, decorators: [{
|
|
23816
23926
|
type: Inject,
|
|
23817
23927
|
args: [ENVIRONMENT]
|
|
@@ -35179,33 +35289,23 @@ class UsersPage extends AppTable {
|
|
|
35179
35289
|
debounceTime(500), tap((json) => this.settings.savePageSetting(this.settingsId, json, SETTINGS_FILTER)))
|
|
35180
35290
|
.subscribe());
|
|
35181
35291
|
if (this.canSendMessage && this.debug) {
|
|
35182
|
-
|
|
35183
|
-
|
|
35184
|
-
|
|
35185
|
-
|
|
35186
|
-
|
|
35187
|
-
|
|
35188
|
-
|
|
35189
|
-
|
|
35190
|
-
action: async () => {
|
|
35191
|
-
if (actionIcon.matIcon === 'expand_more') {
|
|
35192
|
-
actionIcon.matIcon = 'expand_less';
|
|
35193
|
-
subActionsItems = await this.menuService.addSubMenuItems([
|
|
35194
|
-
{
|
|
35195
|
-
parentPath: '/admin/users?action=actions',
|
|
35196
|
-
path: '/admin/users?action=send',
|
|
35197
|
-
icon: 'mail',
|
|
35198
|
-
title: 'USER.LIST.BTN_SEND_MESSAGE',
|
|
35199
|
-
action: () => this.openComposeMessageModal(),
|
|
35200
|
-
},
|
|
35201
|
-
]);
|
|
35202
|
-
}
|
|
35203
|
-
else {
|
|
35204
|
-
actionIcon.matIcon = 'expand_more';
|
|
35205
|
-
await this.menuService.removeSubMenuItems(subActionsItems);
|
|
35206
|
-
}
|
|
35292
|
+
await this.menuService.addSubMenuItems([
|
|
35293
|
+
{
|
|
35294
|
+
parentPath: '/admin/users',
|
|
35295
|
+
path: '/admin/users',
|
|
35296
|
+
pathParams: { action: 'expand' },
|
|
35297
|
+
matIcon: 'expand_more',
|
|
35298
|
+
title: 'USER.LIST.BTN_ACTIONS',
|
|
35299
|
+
action: 'expand',
|
|
35207
35300
|
},
|
|
35208
|
-
|
|
35301
|
+
{
|
|
35302
|
+
parentPath: '/admin/users?action=expand',
|
|
35303
|
+
path: '/admin/users?action=send',
|
|
35304
|
+
icon: 'mail',
|
|
35305
|
+
title: 'USER.LIST.BTN_SEND_MESSAGE',
|
|
35306
|
+
action: () => this.openComposeMessageModal(),
|
|
35307
|
+
},
|
|
35308
|
+
], { skipIfExists: false });
|
|
35209
35309
|
}
|
|
35210
35310
|
// Restore filter from settings, or load all
|
|
35211
35311
|
this.restoreFilterOrLoad();
|