@sumaris-net/ngx-components 2.4.142 → 2.4.143
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 +30 -13
- package/esm2020/src/app/core/menu/menu.service.mjs +183 -49
- 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 +302 -211
- package/fesm2015/sumaris-net.ngx-components.mjs.map +1 -1
- package/fesm2020/sumaris-net.ngx-components.mjs +290 -200
- 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 +20 -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,18 @@ 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
|
+
}
|
|
22957
22904
|
isPinned() {
|
|
22958
22905
|
if (this.pinned)
|
|
22959
22906
|
return true;
|
|
22960
22907
|
return (this.children || []).some(child => child.isPinned());
|
|
22961
22908
|
}
|
|
22962
|
-
}
|
|
22909
|
+
};
|
|
22910
|
+
MenuItem = MenuItem_1 = __decorate([
|
|
22911
|
+
EntityClass({ typename: 'MenuItemVO' })
|
|
22912
|
+
], MenuItem);
|
|
22963
22913
|
class MenuItems {
|
|
22964
22914
|
/**
|
|
22965
22915
|
* Compare, without checking the children
|
|
@@ -23041,11 +22991,16 @@ class MenuItems {
|
|
|
23041
22991
|
static checkIfSubMenuVisible(item, currentPathParam) {
|
|
23042
22992
|
if (!item.parentPath)
|
|
23043
22993
|
return false; // Should have a parent
|
|
22994
|
+
if (item.static)
|
|
22995
|
+
return true; // Always keep static items
|
|
23044
22996
|
if (item.isPinned())
|
|
23045
22997
|
return true; // Always keep pinned items
|
|
23046
22998
|
// Keep each menu items in the scope of the current url path
|
|
23047
22999
|
if (currentPathParam?.path.startsWith(item.path))
|
|
23048
23000
|
return true;
|
|
23001
|
+
// Keep if parent is an expanded item
|
|
23002
|
+
if (item.parent?.action === 'expand' && item.parent.expanded)
|
|
23003
|
+
return true;
|
|
23049
23004
|
// Not visible
|
|
23050
23005
|
return false;
|
|
23051
23006
|
}
|
|
@@ -23078,19 +23033,84 @@ class MenuItems {
|
|
|
23078
23033
|
}
|
|
23079
23034
|
_a = MenuItems;
|
|
23080
23035
|
MenuItems.sortByTabOrId = _a.sortByParamOrIdComparator('tab');
|
|
23036
|
+
/**
|
|
23037
|
+
* Options to configure specific behavior on projects
|
|
23038
|
+
*/
|
|
23081
23039
|
class MenuOptions {
|
|
23082
23040
|
}
|
|
23083
23041
|
|
|
23042
|
+
const APP_ABOUT_DEVELOPERS = new InjectionToken('aboutDevelopers');
|
|
23043
|
+
const APP_ABOUT_PARTNERS = new InjectionToken('aboutPartners');
|
|
23044
|
+
class AboutModal {
|
|
23045
|
+
constructor(translate, modalController, configService, environment, developers, partners) {
|
|
23046
|
+
this.translate = translate;
|
|
23047
|
+
this.modalController = modalController;
|
|
23048
|
+
this.configService = configService;
|
|
23049
|
+
this.environment = environment;
|
|
23050
|
+
this.developers = developers;
|
|
23051
|
+
this.partners = partners;
|
|
23052
|
+
this._subscription = new Subscription();
|
|
23053
|
+
this.name = translate.instant('APP_NAME');
|
|
23054
|
+
if (this.name === 'APP_NAME') {
|
|
23055
|
+
// Not translated: use name from the environnement
|
|
23056
|
+
this.name = environment && environment.name && capitalizeFirstLetter(environment.name) || undefined;
|
|
23057
|
+
}
|
|
23058
|
+
this.version = environment && environment.version;
|
|
23059
|
+
this.sourceUrl = environment && environment.sourceUrl;
|
|
23060
|
+
this.reportIssueUrl = environment && environment.reportIssueUrl;
|
|
23061
|
+
this.forumUrl = environment && environment.forumUrl;
|
|
23062
|
+
this.helpUrl = environment && environment.helpUrl;
|
|
23063
|
+
this.config$ = configService.config;
|
|
23064
|
+
this._subscription.add(this.config$.subscribe(config => this.setConfig(config)));
|
|
23065
|
+
}
|
|
23066
|
+
ngOnDestroy() {
|
|
23067
|
+
this._subscription.unsubscribe();
|
|
23068
|
+
}
|
|
23069
|
+
async close() {
|
|
23070
|
+
await this.modalController.dismiss();
|
|
23071
|
+
}
|
|
23072
|
+
/* -- protected functions -- */
|
|
23073
|
+
setConfig(config) {
|
|
23074
|
+
this.forumUrl = config?.getProperty(CORE_CONFIG_OPTIONS.FORUM_URL) || this.environment.forumUrl;
|
|
23075
|
+
this.helpUrl = config?.getProperty(CORE_CONFIG_OPTIONS.HELP_URL) || this.environment.helpUrl;
|
|
23076
|
+
}
|
|
23077
|
+
}
|
|
23078
|
+
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 });
|
|
23079
|
+
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" }] });
|
|
23080
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: AboutModal, decorators: [{
|
|
23081
|
+
type: Component,
|
|
23082
|
+
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"] }]
|
|
23083
|
+
}], ctorParameters: function () { return [{ type: i1$1.TranslateService }, { type: i2.ModalController }, { type: ConfigService }, { type: undefined, decorators: [{
|
|
23084
|
+
type: Optional
|
|
23085
|
+
}, {
|
|
23086
|
+
type: Inject,
|
|
23087
|
+
args: [ENVIRONMENT]
|
|
23088
|
+
}] }, { type: undefined, decorators: [{
|
|
23089
|
+
type: Optional
|
|
23090
|
+
}, {
|
|
23091
|
+
type: Inject,
|
|
23092
|
+
args: [APP_ABOUT_DEVELOPERS]
|
|
23093
|
+
}] }, { type: undefined, decorators: [{
|
|
23094
|
+
type: Optional
|
|
23095
|
+
}, {
|
|
23096
|
+
type: Inject,
|
|
23097
|
+
args: [APP_ABOUT_PARTNERS]
|
|
23098
|
+
}] }]; } });
|
|
23099
|
+
|
|
23084
23100
|
const DEFAULT_MENU_SHOW_WHEN = 'lg';
|
|
23085
23101
|
const APP_MENU_ITEMS = new InjectionToken('menuItems');
|
|
23086
23102
|
const APP_MENU_OPTIONS = new InjectionToken('menuOptions');
|
|
23087
23103
|
class MenuService extends StartableObservableService {
|
|
23088
|
-
constructor(settings, configService, accountService, router, environment, options, staticItems) {
|
|
23104
|
+
constructor(settings, configService, accountService, router, modalCtrl, alertController, navController, translate, environment, options, staticItems) {
|
|
23089
23105
|
super(settings);
|
|
23090
23106
|
this.settings = settings;
|
|
23091
23107
|
this.configService = configService;
|
|
23092
23108
|
this.accountService = accountService;
|
|
23093
23109
|
this.router = router;
|
|
23110
|
+
this.modalCtrl = modalCtrl;
|
|
23111
|
+
this.alertController = alertController;
|
|
23112
|
+
this.navController = navController;
|
|
23113
|
+
this.translate = translate;
|
|
23094
23114
|
this.environment = environment;
|
|
23095
23115
|
this.accountChanges = new BehaviorSubject(undefined);
|
|
23096
23116
|
this.onPinned = new EventEmitter(true);
|
|
@@ -23102,14 +23122,28 @@ class MenuService extends StartableObservableService {
|
|
|
23102
23122
|
this._$enabled = new BehaviorSubject(true);
|
|
23103
23123
|
this._$listenRoute = new BehaviorSubject(false);
|
|
23104
23124
|
this._options = {
|
|
23105
|
-
enableSubMenuIcon: true,
|
|
23106
23125
|
...options,
|
|
23107
|
-
|
|
23126
|
+
subMenu: {
|
|
23127
|
+
disableIcon: false,
|
|
23128
|
+
savePinned: true,
|
|
23129
|
+
...(options?.subMenu || {}),
|
|
23130
|
+
// Force disable on mobile
|
|
23131
|
+
enable: options?.subMenu?.enable !== false && !this.settings.mobile,
|
|
23132
|
+
}
|
|
23108
23133
|
};
|
|
23109
|
-
this._$
|
|
23134
|
+
this._$enableSubMenu = new BehaviorSubject(this._options.subMenu.enable);
|
|
23110
23135
|
this._debug = !environment.production;
|
|
23111
|
-
this._staticItems = (staticItems || []).map(source => this.fromObject(source, { computeId: true, fillParent: true }));
|
|
23112
23136
|
this._detachedSubItems = [];
|
|
23137
|
+
this._staticItems = (staticItems || []).map(source => {
|
|
23138
|
+
const target = this.fromObject({ static: true, ...source }, { computeId: true, fillParent: true, fillDefaultFromParent: true });
|
|
23139
|
+
const detachedItems = TreeItemEntityUtils.deleteRecursively(target, (item) => item.static !== true);
|
|
23140
|
+
if (detachedItems?.length) {
|
|
23141
|
+
console.debug(this._logPrefix + 'Detached init items', detachedItems);
|
|
23142
|
+
detachedItems.forEach(item => this._detachToParent(item));
|
|
23143
|
+
this._detachedSubItems.push(...detachedItems);
|
|
23144
|
+
}
|
|
23145
|
+
return target;
|
|
23146
|
+
});
|
|
23113
23147
|
}
|
|
23114
23148
|
get opened() {
|
|
23115
23149
|
return this._$opened.asObservable();
|
|
@@ -23121,10 +23155,7 @@ class MenuService extends StartableObservableService {
|
|
|
23121
23155
|
return this._$enabled.asObservable();
|
|
23122
23156
|
}
|
|
23123
23157
|
get subMenuEnabled() {
|
|
23124
|
-
return this._$
|
|
23125
|
-
}
|
|
23126
|
-
get subMenuIconEnabled() {
|
|
23127
|
-
return this._options.enableSubMenuIcon;
|
|
23158
|
+
return this._$enableSubMenu.value;
|
|
23128
23159
|
}
|
|
23129
23160
|
get subItems() {
|
|
23130
23161
|
return (this.data || []).reduce((res, rootElement) => res.concat(rootElement.children), []);
|
|
@@ -23136,7 +23167,7 @@ class MenuService extends StartableObservableService {
|
|
|
23136
23167
|
this._$enabled.next(value);
|
|
23137
23168
|
}
|
|
23138
23169
|
enableSubMenu(value) {
|
|
23139
|
-
this._$
|
|
23170
|
+
this._$enableSubMenu.next(value);
|
|
23140
23171
|
}
|
|
23141
23172
|
setSplitPaneShowWhen(value) {
|
|
23142
23173
|
if (this._$splitPaneWhen.value !== value) {
|
|
@@ -23156,8 +23187,8 @@ class MenuService extends StartableObservableService {
|
|
|
23156
23187
|
// Compute id if need
|
|
23157
23188
|
if (opts?.computeId && isNil(target.id))
|
|
23158
23189
|
target.id = this._computeNewId();
|
|
23159
|
-
// Remove icon if
|
|
23160
|
-
if (
|
|
23190
|
+
// Remove icon if disabled
|
|
23191
|
+
if (this._options.subMenu.disableIcon) {
|
|
23161
23192
|
Object.assign(target, { icon: undefined, matIcon: undefined, matSvgIcon: undefined });
|
|
23162
23193
|
}
|
|
23163
23194
|
// Recursive
|
|
@@ -23165,6 +23196,21 @@ class MenuService extends StartableObservableService {
|
|
|
23165
23196
|
// Fill parent (once, when the full tree is ready)
|
|
23166
23197
|
if (opts?.fillParent) {
|
|
23167
23198
|
TreeItemEntityUtils.treeFillParent(target);
|
|
23199
|
+
// Fill defaults from the parent (once filled)
|
|
23200
|
+
if (opts?.fillDefaultFromParent) {
|
|
23201
|
+
TreeItemEntityUtils.visit(target, (item) => {
|
|
23202
|
+
if (!item.parent)
|
|
23203
|
+
return; // Skip if no parent
|
|
23204
|
+
item.parentPath = item.parentPath || item.parent.path;
|
|
23205
|
+
item.parentPathParams = item.parentPathParams || item.parent.pathParams;
|
|
23206
|
+
item.static = toBoolean(item.static, item.parent.static);
|
|
23207
|
+
// Compute path, from parent path + action
|
|
23208
|
+
if (!item.path && !!item.action) {
|
|
23209
|
+
item.path = item.parent.path;
|
|
23210
|
+
item.pathParams = (typeof item.action === 'string') ? { action: item.action } : { actionId: item.id.toString(), actionTitle: item.title };
|
|
23211
|
+
}
|
|
23212
|
+
});
|
|
23213
|
+
}
|
|
23168
23214
|
}
|
|
23169
23215
|
return target;
|
|
23170
23216
|
}
|
|
@@ -23215,6 +23261,9 @@ class MenuService extends StartableObservableService {
|
|
|
23215
23261
|
console.warn(this._logPrefix + `Sub menu {${source.path}} cannot be found - unable to toggle pinned!`);
|
|
23216
23262
|
return;
|
|
23217
23263
|
}
|
|
23264
|
+
// Skip if static
|
|
23265
|
+
if (item.static)
|
|
23266
|
+
return;
|
|
23218
23267
|
// Unpinned
|
|
23219
23268
|
if (item.pinned) {
|
|
23220
23269
|
item.pinned = false;
|
|
@@ -23231,6 +23280,88 @@ class MenuService extends StartableObservableService {
|
|
|
23231
23280
|
}
|
|
23232
23281
|
this.onPinned.emit(item);
|
|
23233
23282
|
}
|
|
23283
|
+
async executeAction(event, item) {
|
|
23284
|
+
const action = item?.action;
|
|
23285
|
+
if (!action)
|
|
23286
|
+
return; // skip
|
|
23287
|
+
if (typeof action === 'string') {
|
|
23288
|
+
switch (action) {
|
|
23289
|
+
case 'logout':
|
|
23290
|
+
await this.logout();
|
|
23291
|
+
break;
|
|
23292
|
+
case 'about':
|
|
23293
|
+
await this.openAboutModal();
|
|
23294
|
+
break;
|
|
23295
|
+
case 'expand':
|
|
23296
|
+
await this.toggleExpandableItem(item);
|
|
23297
|
+
break;
|
|
23298
|
+
default: {
|
|
23299
|
+
if (item.path) {
|
|
23300
|
+
await this.navController.navigateForward(item.path, {
|
|
23301
|
+
queryParams: item.pathParams
|
|
23302
|
+
});
|
|
23303
|
+
}
|
|
23304
|
+
else {
|
|
23305
|
+
throw new Error('Unknown action: ' + action);
|
|
23306
|
+
}
|
|
23307
|
+
}
|
|
23308
|
+
}
|
|
23309
|
+
}
|
|
23310
|
+
else if (typeof action === 'function') {
|
|
23311
|
+
action(event);
|
|
23312
|
+
}
|
|
23313
|
+
}
|
|
23314
|
+
async logout() {
|
|
23315
|
+
const translations = await this.translate.instant([
|
|
23316
|
+
'AUTH.LOGOUT.CONFIRM_TITLE',
|
|
23317
|
+
'AUTH.LOGOUT.CONFIRM_MESSAGE',
|
|
23318
|
+
'COMMON.BTN_CANCEL',
|
|
23319
|
+
'AUTH.LOGOUT.BTN_CONFIRM',
|
|
23320
|
+
]);
|
|
23321
|
+
const alert = await this.alertController.create({
|
|
23322
|
+
header: translations['AUTH.LOGOUT.CONFIRM_TITLE'],
|
|
23323
|
+
message: translations['AUTH.LOGOUT.CONFIRM_MESSAGE'],
|
|
23324
|
+
buttons: [
|
|
23325
|
+
{
|
|
23326
|
+
text: translations['COMMON.BTN_CANCEL'],
|
|
23327
|
+
role: 'cancel',
|
|
23328
|
+
cssClass: 'secondary',
|
|
23329
|
+
},
|
|
23330
|
+
{
|
|
23331
|
+
text: translations['AUTH.LOGOUT.BTN_CONFIRM'],
|
|
23332
|
+
cssClass: 'ion-color-primary',
|
|
23333
|
+
handler: () => {
|
|
23334
|
+
this.accountService.logout();
|
|
23335
|
+
// Back to home
|
|
23336
|
+
setTimeout(() => this.navController.navigateRoot('/'), 100);
|
|
23337
|
+
},
|
|
23338
|
+
},
|
|
23339
|
+
],
|
|
23340
|
+
});
|
|
23341
|
+
await alert.present();
|
|
23342
|
+
}
|
|
23343
|
+
async openAboutModal() {
|
|
23344
|
+
const modal = await this.modalCtrl.create({ component: AboutModal });
|
|
23345
|
+
return modal.present();
|
|
23346
|
+
}
|
|
23347
|
+
async toggleExpandableItem(item) {
|
|
23348
|
+
if (!item.expanded) {
|
|
23349
|
+
if (this._debug)
|
|
23350
|
+
console.debug(this._logPrefix + 'Expand item', item);
|
|
23351
|
+
item.matIcon = 'expand_less';
|
|
23352
|
+
// Try to attach some item
|
|
23353
|
+
this._detachedSubItems
|
|
23354
|
+
.filter(childItem => !!this._findParent(childItem, [item]))
|
|
23355
|
+
.forEach(childItem => this._attachMenuToParent(item, childItem));
|
|
23356
|
+
}
|
|
23357
|
+
else {
|
|
23358
|
+
item.matIcon = 'expand_more';
|
|
23359
|
+
this._detachedSubItems = [
|
|
23360
|
+
...this._detachedSubItems,
|
|
23361
|
+
...this._detachSubMenuItems({ path: '/', params: {} }, item.children)
|
|
23362
|
+
];
|
|
23363
|
+
}
|
|
23364
|
+
}
|
|
23234
23365
|
_markAsOpened() {
|
|
23235
23366
|
this._$opened.next(true);
|
|
23236
23367
|
}
|
|
@@ -23262,7 +23393,7 @@ class MenuService extends StartableObservableService {
|
|
|
23262
23393
|
// Emit account changes event
|
|
23263
23394
|
this.accountChanges.next(account);
|
|
23264
23395
|
}));
|
|
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)
|
|
23396
|
+
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
23397
|
.subscribe(pathParam => {
|
|
23267
23398
|
const detachedSubItems = this._detachSubMenuItems(pathParam);
|
|
23268
23399
|
if (detachedSubItems?.length) {
|
|
@@ -23290,7 +23421,7 @@ class MenuService extends StartableObservableService {
|
|
|
23290
23421
|
if (this._debug)
|
|
23291
23422
|
console.debug(`${this._logPrefix}Loading menu items...`);
|
|
23292
23423
|
// Save previous children of root items
|
|
23293
|
-
const detachedSubItems = (this.subItems || [])
|
|
23424
|
+
const detachedSubItems = (this.subItems || []).concat(this._staticSubItems || [])
|
|
23294
23425
|
.reduce((res, rootItem) => {
|
|
23295
23426
|
const children = rootItem.children;
|
|
23296
23427
|
if (isEmptyArray(children))
|
|
@@ -23370,21 +23501,22 @@ class MenuService extends StartableObservableService {
|
|
|
23370
23501
|
return items;
|
|
23371
23502
|
}
|
|
23372
23503
|
_addSubMenuItems(sources, opts) {
|
|
23373
|
-
return sources.map(source => this._addSubMenuItem(
|
|
23504
|
+
return sources.map(source => this._addSubMenuItem(source, opts));
|
|
23374
23505
|
}
|
|
23375
23506
|
_addSubMenuItem(newItem, opts) {
|
|
23376
23507
|
opts = {
|
|
23377
23508
|
skipIfExists: true,
|
|
23378
23509
|
...opts,
|
|
23379
23510
|
};
|
|
23511
|
+
const pathParam = MenuItems.parsePathWithQuery(this.router.routerState.snapshot.url);
|
|
23380
23512
|
// Find if item already exists
|
|
23381
23513
|
const existingItem = this._findExistingItem(newItem, opts?.availableParents);
|
|
23382
23514
|
if (existingItem) {
|
|
23383
23515
|
// No changes
|
|
23384
|
-
if (opts.skipIfExists && MenuItems.isSame(existingItem, newItem) &&
|
|
23516
|
+
if (opts.skipIfExists && MenuItems.isSame(existingItem, newItem) && existingItem.visible) {
|
|
23385
23517
|
// DEBUG
|
|
23386
23518
|
if (this._debug)
|
|
23387
|
-
console.debug(`${this._logPrefix}Skipping sub item (same item already exist)`, newItem);
|
|
23519
|
+
console.debug(`${this._logPrefix}Skipping sub item (same visible item already exist)`, newItem);
|
|
23388
23520
|
return existingItem;
|
|
23389
23521
|
}
|
|
23390
23522
|
if (this._debug)
|
|
@@ -23394,52 +23526,67 @@ class MenuService extends StartableObservableService {
|
|
|
23394
23526
|
newItem.id = existingItem.id;
|
|
23395
23527
|
newItem.$children = existingItem.$children;
|
|
23396
23528
|
newItem.pinned = existingItem.pinned;
|
|
23397
|
-
|
|
23529
|
+
newItem.static = existingItem.static;
|
|
23530
|
+
if (newItem.pinned || newItem.static || existingItem.expanded) {
|
|
23398
23531
|
// If loading, keep existing title if pinned (avoid to show skeleton)
|
|
23399
23532
|
newItem.title = newItem.title || existingItem.title;
|
|
23400
23533
|
}
|
|
23401
23534
|
else {
|
|
23402
23535
|
newItem.title = isNotNil(newItem.title) ? newItem.title : existingItem.title;
|
|
23403
23536
|
}
|
|
23537
|
+
// Auto set icon, for expand action
|
|
23538
|
+
if (existingItem.action === 'expand') {
|
|
23539
|
+
newItem.icon = null;
|
|
23540
|
+
newItem.matIcon = existingItem.expanded ? 'expand_less' : 'expand_more';
|
|
23541
|
+
}
|
|
23404
23542
|
}
|
|
23405
23543
|
}
|
|
23406
23544
|
// Generate item's id (if need)
|
|
23407
23545
|
else if (isNil(newItem.id)) {
|
|
23408
23546
|
newItem.id = this._computeNewId();
|
|
23409
23547
|
}
|
|
23410
|
-
//
|
|
23548
|
+
// Default icon for expand action
|
|
23549
|
+
if (newItem.action === 'expand' && !newItem.matIcon) {
|
|
23550
|
+
newItem.matIcon = 'expand_more';
|
|
23551
|
+
}
|
|
23552
|
+
// If visible, get the parent where to attach the item
|
|
23411
23553
|
const parent = this._findParent(newItem, opts?.availableParents);
|
|
23412
|
-
if (parent) {
|
|
23554
|
+
if (parent && parent.expanded) {
|
|
23413
23555
|
// Attach item to parent
|
|
23414
23556
|
this._attachMenuToParent(parent, newItem);
|
|
23415
|
-
const pathParam = MenuItems.parsePathWithQuery(this.router.routerState.snapshot.url);
|
|
23416
23557
|
// Update detached items :
|
|
23417
23558
|
// - excluded new item
|
|
23418
23559
|
// - attach and exclude those than can be attached to the new item
|
|
23419
23560
|
// 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
|
-
|
|
23561
|
+
if (newItem.expanded) {
|
|
23562
|
+
const ancestor = newItem.ancestor;
|
|
23563
|
+
this._detachedSubItems = this._detachedSubItems.concat(...newItem.children)
|
|
23564
|
+
.reduce((res, item) => {
|
|
23565
|
+
// Excluded newly add item
|
|
23566
|
+
if (item.id === newItem.id)
|
|
23567
|
+
return res;
|
|
23568
|
+
// If some detached can be attached to the new item: do it
|
|
23569
|
+
if (MenuItems.checkIfSubMenuVisible(item, pathParam)) {
|
|
23570
|
+
const parent = this._findParent(item, [ancestor]);
|
|
23571
|
+
if (parent) {
|
|
23572
|
+
// Update item's children
|
|
23573
|
+
const detachedChildren = this._detachSubMenuItems(pathParam, item.children || []);
|
|
23574
|
+
// Attach item
|
|
23575
|
+
this._attachMenuToParent(parent, item);
|
|
23576
|
+
// Remember detached children
|
|
23577
|
+
return res.concat(...detachedChildren);
|
|
23578
|
+
}
|
|
23436
23579
|
}
|
|
23437
|
-
|
|
23580
|
+
// Detach (if need)
|
|
23581
|
+
this._detachToParent(item);
|
|
23582
|
+
// Add to detached items
|
|
23583
|
+
return res.concat(item);
|
|
23584
|
+
}, []);
|
|
23585
|
+
}
|
|
23586
|
+
else {
|
|
23438
23587
|
// Detach (if need)
|
|
23439
|
-
this._detachToParent(item);
|
|
23440
|
-
|
|
23441
|
-
return res.concat(item);
|
|
23442
|
-
}, []);
|
|
23588
|
+
newItem.children.forEach(item => this._detachToParent(item));
|
|
23589
|
+
}
|
|
23443
23590
|
}
|
|
23444
23591
|
else {
|
|
23445
23592
|
// Add or update detached item
|
|
@@ -23553,14 +23700,14 @@ class MenuService extends StartableObservableService {
|
|
|
23553
23700
|
}
|
|
23554
23701
|
}
|
|
23555
23702
|
}
|
|
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 });
|
|
23703
|
+
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
23704
|
MenuService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: MenuService, providedIn: 'root' });
|
|
23558
23705
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: MenuService, decorators: [{
|
|
23559
23706
|
type: Injectable,
|
|
23560
23707
|
args: [{
|
|
23561
23708
|
providedIn: 'root', deps: [ENVIRONMENT]
|
|
23562
23709
|
}]
|
|
23563
|
-
}], ctorParameters: function () { return [{ type: LocalSettingsService }, { type: ConfigService }, { type: AccountService }, { type: i1$5.Router }, { type: Environment, decorators: [{
|
|
23710
|
+
}], 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
23711
|
type: Inject,
|
|
23565
23712
|
args: [ENVIRONMENT]
|
|
23566
23713
|
}] }, { type: MenuOptions, decorators: [{
|
|
@@ -23654,35 +23801,6 @@ class MenuComponent {
|
|
|
23654
23801
|
this.markAsLoaded({ emitEvent: false });
|
|
23655
23802
|
this.markForCheck();
|
|
23656
23803
|
}
|
|
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
23804
|
trackByFn(index, item) {
|
|
23687
23805
|
return item.id.toString();
|
|
23688
23806
|
}
|
|
@@ -23711,15 +23829,11 @@ class MenuComponent {
|
|
|
23711
23829
|
if (opened) {
|
|
23712
23830
|
console.debug('[menu] Closing menu');
|
|
23713
23831
|
await this.menu.close(this.menuId);
|
|
23714
|
-
//
|
|
23832
|
+
// Propagate to service
|
|
23715
23833
|
this.menuService._markAsClosed();
|
|
23716
23834
|
}
|
|
23717
23835
|
return true;
|
|
23718
23836
|
}
|
|
23719
|
-
async openAboutModal(event) {
|
|
23720
|
-
const modal = await this.modalCtrl.create({ component: AboutModal });
|
|
23721
|
-
return modal.present();
|
|
23722
|
-
}
|
|
23723
23837
|
async setSplitPaneWhen(value) {
|
|
23724
23838
|
console.debug('[menu] Checking splitPane when...');
|
|
23725
23839
|
if (this.splitPane.when !== value) {
|
|
@@ -23742,24 +23856,10 @@ class MenuComponent {
|
|
|
23742
23856
|
return this.setSplitPaneWhen(false);
|
|
23743
23857
|
}
|
|
23744
23858
|
}
|
|
23745
|
-
|
|
23859
|
+
executeAction(event, item) {
|
|
23746
23860
|
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
|
-
}
|
|
23861
|
+
// Delegate execution to service
|
|
23862
|
+
return this.menuService.executeAction(event, item);
|
|
23763
23863
|
}
|
|
23764
23864
|
onSwipeRight(event) {
|
|
23765
23865
|
// Skip, if not a valid swipe event
|
|
@@ -23808,10 +23908,10 @@ class MenuComponent {
|
|
|
23808
23908
|
}
|
|
23809
23909
|
}
|
|
23810
23910
|
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 });
|
|
23911
|
+
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.static\"\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
23912
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: MenuComponent, decorators: [{
|
|
23813
23913
|
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"] }]
|
|
23914
|
+
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.static\"\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
23915
|
}], 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
23916
|
type: Inject,
|
|
23817
23917
|
args: [ENVIRONMENT]
|
|
@@ -35179,33 +35279,23 @@ class UsersPage extends AppTable {
|
|
|
35179
35279
|
debounceTime(500), tap((json) => this.settings.savePageSetting(this.settingsId, json, SETTINGS_FILTER)))
|
|
35180
35280
|
.subscribe());
|
|
35181
35281
|
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
|
-
}
|
|
35282
|
+
await this.menuService.addSubMenuItems([
|
|
35283
|
+
{
|
|
35284
|
+
parentPath: '/admin/users',
|
|
35285
|
+
path: '/admin/users',
|
|
35286
|
+
pathParams: { action: 'expand' },
|
|
35287
|
+
matIcon: 'expand_more',
|
|
35288
|
+
title: 'USER.LIST.BTN_ACTIONS',
|
|
35289
|
+
action: 'expand',
|
|
35207
35290
|
},
|
|
35208
|
-
|
|
35291
|
+
{
|
|
35292
|
+
parentPath: '/admin/users?action=expand',
|
|
35293
|
+
path: '/admin/users?action=send',
|
|
35294
|
+
icon: 'mail',
|
|
35295
|
+
title: 'USER.LIST.BTN_SEND_MESSAGE',
|
|
35296
|
+
action: () => this.openComposeMessageModal(),
|
|
35297
|
+
},
|
|
35298
|
+
], { skipIfExists: false });
|
|
35209
35299
|
}
|
|
35210
35300
|
// Restore filter from settings, or load all
|
|
35211
35301
|
this.restoreFilterOrLoad();
|