@sumaris-net/ngx-components 18.0.7 → 18.0.9
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/doc/changelog.md +12 -1
- package/esm2022/src/app/core/about/about.modal.mjs +6 -4
- package/esm2022/src/app/core/about/about.module.mjs +5 -4
- package/esm2022/src/app/core/form/buttons/form-buttons-bar.component.mjs +3 -3
- package/esm2022/src/app/core/services/config/core.config.mjs +6 -1
- package/esm2022/src/app/shared/hotkeys/dialog/hotkeys-dialog.component.mjs +1 -1
- package/esm2022/src/app/shared/hotkeys/hotkeys.service.mjs +40 -11
- package/esm2022/src/app/shared/material/latlong/material.latlong.mjs +33 -10
- package/esm2022/src/app/shared/toolbar/modal-toolbar.mjs +2 -2
- package/fesm2022/sumaris-net.ngx-components.mjs +84 -26
- package/fesm2022/sumaris-net.ngx-components.mjs.map +1 -1
- package/package.json +6 -4
- package/src/app/core/about/about.modal.d.ts +1 -1
- package/src/app/core/about/about.module.d.ts +2 -1
- package/src/app/core/services/config/core.config.d.ts +1 -0
- package/src/app/shared/hotkeys/hotkeys.service.d.ts +5 -0
- package/src/app/shared/inputs.d.ts +1 -1
- package/src/app/shared/material/latlong/material.latlong.d.ts +3 -0
- package/src/assets/i18n/en-US.json +1 -0
- package/src/assets/i18n/en.json +1 -0
- package/src/assets/i18n/fr.json +1 -0
- package/src/assets/manifest.json +1 -1
|
@@ -8674,14 +8674,7 @@ class MatLatLongField {
|
|
|
8674
8674
|
else {
|
|
8675
8675
|
this.formControl.setValidators(this.type === 'latitude' ? SharedValidators.latitude : SharedValidators.longitude);
|
|
8676
8676
|
}
|
|
8677
|
-
this._subscription.add(this.signFormControl.valueChanges.subscribe(() =>
|
|
8678
|
-
const strValue = this.textFormControl.value;
|
|
8679
|
-
const parsedValue = this.parseValue(strValue);
|
|
8680
|
-
// TODO Need to check this or delegate the work on validator
|
|
8681
|
-
// if (this.formControl.valid) {
|
|
8682
|
-
// }
|
|
8683
|
-
this.formControl.patchValue(parsedValue, { emitEvent: false });
|
|
8684
|
-
}));
|
|
8677
|
+
this._subscription.add(merge(this.textFormControl.valueChanges, this.signFormControl.valueChanges).subscribe(() => this.onFormChange()));
|
|
8685
8678
|
// Listen status changes (when done outside the component - e.g. when setErrors() is calling on the formControl)
|
|
8686
8679
|
this._subscription.add(this.formControl.statusChanges
|
|
8687
8680
|
.pipe(filter(() => !this.readonly && !this._writing && !this._disabling) // Skip
|
|
@@ -8773,7 +8766,37 @@ class MatLatLongField {
|
|
|
8773
8766
|
_format(value, opts = {}) {
|
|
8774
8767
|
return formatLatLong(value, this.type, { ...this._formatOptions, ...opts }) ?? this.maskitoPlaceholder;
|
|
8775
8768
|
}
|
|
8769
|
+
_checkIfTouched() {
|
|
8770
|
+
if (this.textFormControl.touched) {
|
|
8771
|
+
this._onTouchedCallback();
|
|
8772
|
+
this.markForCheck();
|
|
8773
|
+
}
|
|
8774
|
+
}
|
|
8776
8775
|
/* -- private method -- */
|
|
8776
|
+
onFormChange() {
|
|
8777
|
+
if (this._writing)
|
|
8778
|
+
return; // Skip if call by self
|
|
8779
|
+
this._writing = true;
|
|
8780
|
+
let strValue = this.textFormControl.value;
|
|
8781
|
+
// Reset mask if value is empty
|
|
8782
|
+
if (!/\d/.test(strValue)) {
|
|
8783
|
+
strValue = null;
|
|
8784
|
+
}
|
|
8785
|
+
const parsedValue = this.parseValue(strValue);
|
|
8786
|
+
this.emitChange(parsedValue);
|
|
8787
|
+
this._writing = false;
|
|
8788
|
+
this.markForCheck();
|
|
8789
|
+
}
|
|
8790
|
+
emitChange(value) {
|
|
8791
|
+
const formControlValue = this.formControl.value;
|
|
8792
|
+
if (formControlValue !== value) {
|
|
8793
|
+
if (this.textFormControl.valid) {
|
|
8794
|
+
this.formControl.setValue(value, { emitEvent: false });
|
|
8795
|
+
this._onChangeCallback(value);
|
|
8796
|
+
this._checkIfTouched();
|
|
8797
|
+
}
|
|
8798
|
+
}
|
|
8799
|
+
}
|
|
8777
8800
|
updateTranslations(translation) {
|
|
8778
8801
|
// No change
|
|
8779
8802
|
if (this.maskitoPlaceholder === translation)
|
|
@@ -14194,6 +14217,7 @@ class Hotkeys {
|
|
|
14194
14217
|
modalController;
|
|
14195
14218
|
popoverController;
|
|
14196
14219
|
_debug = false;
|
|
14220
|
+
_id = 0;
|
|
14197
14221
|
_hotkeys = new Map();
|
|
14198
14222
|
_document = inject(DOCUMENT);
|
|
14199
14223
|
_defaults = {
|
|
@@ -14201,9 +14225,13 @@ class Hotkeys {
|
|
|
14201
14225
|
preventDefault: true,
|
|
14202
14226
|
};
|
|
14203
14227
|
_dialogRef;
|
|
14228
|
+
_dialogIsOpened = false;
|
|
14204
14229
|
_config;
|
|
14205
14230
|
defaultControlKey;
|
|
14206
14231
|
defaultControlKeyName;
|
|
14232
|
+
get isHelpModalOpened() {
|
|
14233
|
+
return !!this._dialogRef;
|
|
14234
|
+
}
|
|
14207
14235
|
constructor(platform, eventManager, dialog, modalController, popoverController, config) {
|
|
14208
14236
|
this.eventManager = eventManager;
|
|
14209
14237
|
this.dialog = dialog;
|
|
@@ -14216,9 +14244,9 @@ class Hotkeys {
|
|
|
14216
14244
|
};
|
|
14217
14245
|
// Add shortcut to open help modal
|
|
14218
14246
|
if (this._config.enableHelpModal) {
|
|
14219
|
-
this.addShortcut({ keys: this._config.openHelpModalShortcut }).subscribe(() => this.openHelpModal());
|
|
14220
14247
|
if (this._debug)
|
|
14221
14248
|
console.debug(`[hotkeys] Starting hotkeys service... Press ${this._config.openHelpModalShortcut} to get help modal.`);
|
|
14249
|
+
this.addShortcut({ keys: this._config.openHelpModalShortcut }).subscribe(() => this.toggleHelpModal());
|
|
14222
14250
|
}
|
|
14223
14251
|
const isIOS = platform.is('ios');
|
|
14224
14252
|
this.defaultControlKey = isIOS ? 'meta' : 'control';
|
|
@@ -14228,11 +14256,14 @@ class Hotkeys {
|
|
|
14228
14256
|
}
|
|
14229
14257
|
addShortcut(options) {
|
|
14230
14258
|
const merged = { ...this._defaults, ...options };
|
|
14259
|
+
if (!merged.keys)
|
|
14260
|
+
throw new Error("Missing 'keys' or 'description' attribute");
|
|
14231
14261
|
const event = `keydown.${merged.keys}`;
|
|
14262
|
+
const id = this._id++;
|
|
14263
|
+
this._hotkeys.set(id, merged);
|
|
14232
14264
|
if (isNotNilOrBlank(merged.description)) {
|
|
14233
14265
|
if (this._debug)
|
|
14234
14266
|
console.debug(`[hotkeys] Add shortcut {${options.keys}}: ${merged.description}`);
|
|
14235
|
-
this._hotkeys.set(merged.keys, merged.description);
|
|
14236
14267
|
}
|
|
14237
14268
|
else {
|
|
14238
14269
|
if (this._debug)
|
|
@@ -14258,27 +14289,48 @@ class Hotkeys {
|
|
|
14258
14289
|
const dispose = this.eventManager.addEventListener(merged.element, event, handler);
|
|
14259
14290
|
return () => {
|
|
14260
14291
|
dispose();
|
|
14261
|
-
this._hotkeys.delete(
|
|
14292
|
+
this._hotkeys.delete(id);
|
|
14262
14293
|
};
|
|
14263
14294
|
});
|
|
14264
14295
|
}
|
|
14265
|
-
|
|
14266
|
-
if (this.
|
|
14267
|
-
this.
|
|
14268
|
-
return;
|
|
14296
|
+
toggleHelpModal() {
|
|
14297
|
+
if (this.isHelpModalOpened) {
|
|
14298
|
+
this.closeHelpModal();
|
|
14269
14299
|
}
|
|
14300
|
+
else {
|
|
14301
|
+
this.openHelpModal();
|
|
14302
|
+
}
|
|
14303
|
+
}
|
|
14304
|
+
openHelpModal() {
|
|
14305
|
+
if (this.isHelpModalOpened)
|
|
14306
|
+
return; // Skip if already opened
|
|
14307
|
+
// Get keys with a not blank description
|
|
14308
|
+
const hotkeys = Array.from(this._hotkeys.values()).reduce((map, item) => {
|
|
14309
|
+
if (isNotNilOrBlank(item?.description)) {
|
|
14310
|
+
map.set(item.keys, item.description);
|
|
14311
|
+
}
|
|
14312
|
+
return map;
|
|
14313
|
+
}, new Map());
|
|
14314
|
+
if (hotkeys.size === 0)
|
|
14315
|
+
return; // Nothing to display
|
|
14270
14316
|
this._dialogRef = this.dialog.open(HotkeysDialogComponent, {
|
|
14271
14317
|
width: '500px',
|
|
14272
|
-
data:
|
|
14318
|
+
data: hotkeys,
|
|
14273
14319
|
});
|
|
14274
14320
|
this._dialogRef
|
|
14275
14321
|
.afterClosed()
|
|
14276
|
-
.pipe(first()
|
|
14322
|
+
.pipe(first(),
|
|
14323
|
+
// Avoid too many call (e.g. in Safari)
|
|
14324
|
+
delay(250))
|
|
14277
14325
|
.subscribe(() => {
|
|
14278
14326
|
// Forget the dialog ref
|
|
14279
14327
|
this._dialogRef = null;
|
|
14328
|
+
console.debug('[hotkeys] Closing help modal');
|
|
14280
14329
|
});
|
|
14281
14330
|
}
|
|
14331
|
+
closeHelpModal() {
|
|
14332
|
+
this._dialogRef?.close(true);
|
|
14333
|
+
}
|
|
14282
14334
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.8", ngImport: i0, type: Hotkeys, deps: [{ token: i2$1.Platform }, { token: i1$2.EventManager }, { token: i3$1.MatDialog }, { token: i2$1.ModalController }, { token: i2$1.PopoverController }, { token: APP_HOTKEYS_CONFIG, optional: true }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
14283
14335
|
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.8", ngImport: i0, type: Hotkeys, providedIn: 'root' });
|
|
14284
14336
|
}
|
|
@@ -14928,6 +14980,11 @@ const CORE_CONFIG_OPTIONS = Object.freeze({
|
|
|
14928
14980
|
label: 'CONFIGURATION.OPTIONS.FORUM_URL',
|
|
14929
14981
|
type: 'string',
|
|
14930
14982
|
},
|
|
14983
|
+
REPORT_ISSUE_URL: {
|
|
14984
|
+
key: 'sumaris.reportIssue.url',
|
|
14985
|
+
label: 'CONFIGURATION.OPTIONS.REPORT_ISSUE_URL',
|
|
14986
|
+
type: 'string',
|
|
14987
|
+
},
|
|
14931
14988
|
LOGO_LARGE: {
|
|
14932
14989
|
key: 'sumaris.logo.large',
|
|
14933
14990
|
label: 'CONFIGURATION.OPTIONS.HOME.LOGO_LARGE',
|
|
@@ -22237,7 +22294,7 @@ class ModalToolbarComponent {
|
|
|
22237
22294
|
this.canValidate = toBoolean(this.canValidate, this.validate.observed);
|
|
22238
22295
|
// Ctrl+S
|
|
22239
22296
|
this._subscription.add(this.hotkeys
|
|
22240
|
-
.addShortcut({ keys:
|
|
22297
|
+
.addShortcut({ keys: `${this.hotkeys.defaultControlKey}.s`, description: 'COMMON.BTN_VALIDATE', elementName: this.modalName })
|
|
22241
22298
|
.pipe(filter(() => this.canValidate))
|
|
22242
22299
|
.subscribe((event) => this.validate.emit(event)));
|
|
22243
22300
|
// Escape
|
|
@@ -26428,8 +26485,8 @@ class AboutModal {
|
|
|
26428
26485
|
name;
|
|
26429
26486
|
version;
|
|
26430
26487
|
sourceUrl;
|
|
26431
|
-
reportIssueUrl;
|
|
26432
26488
|
config$;
|
|
26489
|
+
reportIssueUrl;
|
|
26433
26490
|
forumUrl;
|
|
26434
26491
|
helpUrl;
|
|
26435
26492
|
_subscription = new Subscription();
|
|
@@ -26463,13 +26520,14 @@ class AboutModal {
|
|
|
26463
26520
|
setConfig(config) {
|
|
26464
26521
|
this.forumUrl = config?.getProperty(CORE_CONFIG_OPTIONS.FORUM_URL) || this.environment.forumUrl;
|
|
26465
26522
|
this.helpUrl = config?.getProperty(CORE_CONFIG_OPTIONS.HELP_URL) || this.environment.helpUrl;
|
|
26523
|
+
this.reportIssueUrl = config?.getProperty(CORE_CONFIG_OPTIONS.REPORT_ISSUE_URL) || this.environment.reportIssueUrl;
|
|
26466
26524
|
}
|
|
26467
26525
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.8", ngImport: i0, type: AboutModal, deps: [{ token: i1$1.TranslateService }, { token: i2$1.ModalController }, { token: ConfigService }, { token: ENVIRONMENT, optional: true }, { token: APP_ABOUT_DEVELOPERS, optional: true }, { token: APP_ABOUT_PARTNERS, optional: true }], target: i0.ɵɵFactoryTarget.Component });
|
|
26468
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "
|
|
26526
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.8", type: AboutModal, selector: "app-about-modal", ngImport: i0, template: "<ion-header>\n <ion-toolbar color=\"light\">\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 <ion-list lines=\"none\">\n <!-- Peer info -->\n @if (config$ | async; as config) {\n <ion-item>\n <span slot=\"start\"> </span>\n <ion-label class=\"ion-text-wrap\">\n <h2>\n <b>{{ config.label | capitalize }}</b>\n @if (config.name) {\n -\n <span [innerHTML]=\"config.name\"></span>\n }\n </h2>\n\n @if (config.description) {\n <p>\n <markdown [data]=\"config.description\" emoji></markdown>\n </p>\n }\n </ion-label>\n </ion-item>\n }\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>\n {{ 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 <!-- 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\" class=\"ion-no-padding\">\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-img slot=\"end\" [src]=\"item.logo\" />\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 *ngIf=\"item.logo; else partnerName\" [src]=\"item.logo\" [alt]=\"item.label\" />\n <ng-template #partnerName>\n <ion-text>{{ item.label }}</ion-text>\n </ng-template>\n </a>\n </p>\n </ion-text>\n </ion-item>\n </ion-list>\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!important}\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$1.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$1.IonButtons, selector: "ion-buttons", inputs: ["collapse"] }, { kind: "component", type: i2$1.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$1.IonContent, selector: "ion-content", inputs: ["color", "fixedSlotPlacement", "forceOverscroll", "fullscreen", "scrollEvents", "scrollX", "scrollY"] }, { kind: "component", type: i2$1.IonFooter, selector: "ion-footer", inputs: ["collapse", "mode", "translucent"] }, { kind: "component", type: i2$1.IonHeader, selector: "ion-header", inputs: ["collapse", "mode", "translucent"] }, { kind: "component", type: i2$1.IonIcon, selector: "ion-icon", inputs: ["color", "flipRtl", "icon", "ios", "lazy", "md", "mode", "name", "sanitize", "size", "src"] }, { kind: "component", type: i2$1.IonImg, selector: "ion-img", inputs: ["alt", "src"] }, { kind: "component", type: i2$1.IonItem, selector: "ion-item", inputs: ["button", "color", "detail", "detailIcon", "disabled", "download", "href", "lines", "mode", "rel", "routerAnimation", "routerDirection", "target", "type"] }, { kind: "component", type: i2$1.IonLabel, selector: "ion-label", inputs: ["color", "mode", "position"] }, { kind: "component", type: i2$1.IonList, selector: "ion-list", inputs: ["inset", "lines", "mode"] }, { kind: "component", type: i2$1.IonRow, selector: "ion-row" }, { kind: "component", type: i2$1.IonText, selector: "ion-text", inputs: ["color", "mode"] }, { kind: "component", type: i2$1.IonTitle, selector: "ion-title", inputs: ["color", "size"] }, { kind: "component", type: i2$1.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", "disableSanitizer", "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" }, { kind: "pipe", type: CapitalizePipe, name: "capitalize" }] });
|
|
26469
26527
|
}
|
|
26470
26528
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.8", ngImport: i0, type: AboutModal, decorators: [{
|
|
26471
26529
|
type: Component,
|
|
26472
|
-
args: [{ selector: 'app-about-modal', template: "<ion-header>\n <ion-toolbar color=\"light\">\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 <ion-list lines=\"none\">\n <!-- Peer info -->\n
|
|
26530
|
+
args: [{ selector: 'app-about-modal', template: "<ion-header>\n <ion-toolbar color=\"light\">\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 <ion-list lines=\"none\">\n <!-- Peer info -->\n @if (config$ | async; as config) {\n <ion-item>\n <span slot=\"start\"> </span>\n <ion-label class=\"ion-text-wrap\">\n <h2>\n <b>{{ config.label | capitalize }}</b>\n @if (config.name) {\n -\n <span [innerHTML]=\"config.name\"></span>\n }\n </h2>\n\n @if (config.description) {\n <p>\n <markdown [data]=\"config.description\" emoji></markdown>\n </p>\n }\n </ion-label>\n </ion-item>\n }\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>\n {{ 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 <!-- 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\" class=\"ion-no-padding\">\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-img slot=\"end\" [src]=\"item.logo\" />\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 *ngIf=\"item.logo; else partnerName\" [src]=\"item.logo\" [alt]=\"item.label\" />\n <ng-template #partnerName>\n <ion-text>{{ item.label }}</ion-text>\n </ng-template>\n </a>\n </p>\n </ion-text>\n </ion-item>\n </ion-list>\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!important}\n"] }]
|
|
26473
26531
|
}], ctorParameters: () => [{ type: i1$1.TranslateService }, { type: i2$1.ModalController }, { type: ConfigService }, { type: undefined, decorators: [{
|
|
26474
26532
|
type: Optional
|
|
26475
26533
|
}, {
|
|
@@ -29109,13 +29167,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.8", ngImpor
|
|
|
29109
29167
|
|
|
29110
29168
|
class AppAboutModalModule {
|
|
29111
29169
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.8", ngImport: i0, type: AppAboutModalModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
|
|
29112
|
-
static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "18.2.8", ngImport: i0, type: AppAboutModalModule, declarations: [AboutModal], imports: [SharedModule, IonicModule, i1$1.TranslateModule], exports: [TranslateModule, AboutModal] });
|
|
29113
|
-
static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "18.2.8", ngImport: i0, type: AppAboutModalModule, imports: [SharedModule, IonicModule, TranslateModule.forChild(), TranslateModule] });
|
|
29170
|
+
static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "18.2.8", ngImport: i0, type: AppAboutModalModule, declarations: [AboutModal], imports: [SharedModule, IonicModule, i1$1.TranslateModule, MarkdownModule], exports: [TranslateModule, AboutModal] });
|
|
29171
|
+
static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "18.2.8", ngImport: i0, type: AppAboutModalModule, imports: [SharedModule, IonicModule, TranslateModule.forChild(), MarkdownModule, TranslateModule] });
|
|
29114
29172
|
}
|
|
29115
29173
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.8", ngImport: i0, type: AppAboutModalModule, decorators: [{
|
|
29116
29174
|
type: NgModule,
|
|
29117
29175
|
args: [{
|
|
29118
|
-
imports: [SharedModule, IonicModule, TranslateModule.forChild()],
|
|
29176
|
+
imports: [SharedModule, IonicModule, TranslateModule.forChild(), MarkdownModule],
|
|
29119
29177
|
declarations: [AboutModal],
|
|
29120
29178
|
exports: [TranslateModule, AboutModal],
|
|
29121
29179
|
}]
|
|
@@ -29262,12 +29320,12 @@ class FormButtonsBarComponent {
|
|
|
29262
29320
|
this.menu = menu;
|
|
29263
29321
|
// Ctrl+S
|
|
29264
29322
|
this._subscription.add(hotkeys
|
|
29265
|
-
.addShortcut({ keys:
|
|
29323
|
+
.addShortcut({ keys: `${hotkeys.defaultControlKey}.s`, description: 'COMMON.BTN_SAVE' })
|
|
29266
29324
|
.pipe(filter((_) => !this.disabled))
|
|
29267
29325
|
.subscribe((event) => this.onSave.emit(event)));
|
|
29268
29326
|
// Ctrl+Z
|
|
29269
29327
|
this._subscription.add(hotkeys
|
|
29270
|
-
.addShortcut({ keys:
|
|
29328
|
+
.addShortcut({ keys: `${hotkeys.defaultControlKey}.z`, description: 'COMMON.BTN_RESET' })
|
|
29271
29329
|
.pipe(filter((_) => !this.disabled && !this.disabledCancel))
|
|
29272
29330
|
.subscribe((event) => this.onCancel.emit(event)));
|
|
29273
29331
|
// Escape
|