@sumaris-net/ngx-components 18.6.9 → 18.6.10-beta1
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 +3 -0
- package/esm2022/src/app/admin/services/validator/person.validator.mjs +1 -1
- package/esm2022/src/app/core/account/account.page.mjs +32 -20
- package/esm2022/src/app/core/form/properties/properties.table.mjs +28 -32
- package/esm2022/src/app/core/form/properties/properties.utils.mjs +14 -1
- package/esm2022/src/app/core/services/account.service.mjs +22 -7
- package/esm2022/src/app/core/services/local-settings.service.mjs +9 -2
- package/esm2022/src/app/core/services/model/account.model.mjs +32 -13
- package/esm2022/src/app/core/services/model/entity.model.mjs +1 -1
- package/esm2022/src/app/core/services/platform.service.mjs +4 -3
- package/esm2022/src/app/core/services/validator/base.validator.class.mjs +3 -3
- package/esm2022/src/app/core/table/entities-async-table-datasource.class.mjs +1 -1
- package/esm2022/src/app/core/table/entities-table-datasource.class.mjs +1 -1
- package/esm2022/src/app/shared/named-filter/named-filter-selector.component.mjs +1 -1
- package/esm2022/src/app/shared/named-filter/named-filter.model.mjs +1 -1
- package/esm2022/src/app/social/user-event/user-event.model.mjs +1 -1
- package/fesm2022/sumaris-net.ngx-components.mjs +130 -70
- package/fesm2022/sumaris-net.ngx-components.mjs.map +1 -1
- package/package.json +1 -1
- package/src/app/admin/services/validator/person.validator.d.ts +1 -1
- package/src/app/core/account/account.page.d.ts +2 -0
- package/src/app/core/form/properties/properties.table.d.ts +4 -10
- package/src/app/core/form/properties/properties.utils.d.ts +4 -0
- package/src/app/core/install/install-upgrade-card.component.d.ts +1 -1
- package/src/app/core/services/account.service.d.ts +2 -0
- package/src/app/core/services/local-settings.service.d.ts +1 -0
- package/src/app/core/services/model/account.model.d.ts +17 -2
- package/src/app/core/services/model/entity.model.d.ts +2 -2
- package/src/app/core/services/validator/base.validator.class.d.ts +5 -5
- package/src/app/core/table/entities-async-table-datasource.class.d.ts +2 -2
- package/src/app/core/table/entities-table-datasource.class.d.ts +2 -2
- package/src/app/shared/named-filter/named-filter-selector.component.d.ts +3 -1
- package/src/app/shared/named-filter/named-filter.model.d.ts +2 -2
- package/src/app/social/user-event/user-event.model.d.ts +2 -2
|
@@ -7170,6 +7170,19 @@ class AppPropertiesUtils {
|
|
|
7170
7170
|
}
|
|
7171
7171
|
return targets;
|
|
7172
7172
|
}
|
|
7173
|
+
static sanitize(source, opts) {
|
|
7174
|
+
if (!source)
|
|
7175
|
+
return source; // Skip if empty
|
|
7176
|
+
const includedKeys = opts?.includedKeys ?? opts?.definitions.map((def) => def.key);
|
|
7177
|
+
if (Array.isArray(source)) {
|
|
7178
|
+
return source.filter((property) => property && (!includedKeys || includedKeys.includes(property.key)) && isNotNil(property.value));
|
|
7179
|
+
}
|
|
7180
|
+
return (includedKeys || Object.keys(source)).reduce((res, key) => {
|
|
7181
|
+
if (isNotNil(source[key]))
|
|
7182
|
+
res[key] = source[key];
|
|
7183
|
+
return res;
|
|
7184
|
+
}, {});
|
|
7185
|
+
}
|
|
7173
7186
|
}
|
|
7174
7187
|
class AppPropertyUtils {
|
|
7175
7188
|
static key(key) {
|
|
@@ -12381,12 +12394,18 @@ class LocalSettingsService extends StartableService {
|
|
|
12381
12394
|
async apply(settings, opts) {
|
|
12382
12395
|
if (!this.started)
|
|
12383
12396
|
await this.ready();
|
|
12397
|
+
// Sanitize (keep properties that can be set by user
|
|
12398
|
+
if (opts?.sanitize) {
|
|
12399
|
+
settings.properties = AppPropertiesUtils.sanitize(settings.properties, { definitions: this.optionDefs });
|
|
12400
|
+
}
|
|
12384
12401
|
const data = {
|
|
12385
12402
|
...this._data,
|
|
12386
12403
|
...settings,
|
|
12387
12404
|
};
|
|
12388
12405
|
if (equals(data, this._data))
|
|
12389
12406
|
return; // Skip if no changes
|
|
12407
|
+
// DEBUG
|
|
12408
|
+
//console.debug('[platform] Applying local settings...', settings);
|
|
12390
12409
|
this._data = data;
|
|
12391
12410
|
// Save locally
|
|
12392
12411
|
if (opts && opts.persistImmediate) {
|
|
@@ -12521,7 +12540,7 @@ class LocalSettingsService extends StartableService {
|
|
|
12521
12540
|
const index = this._optionDefs.findIndex((f) => f.key === def.key);
|
|
12522
12541
|
if (index !== -1) {
|
|
12523
12542
|
if (opts?.replaceIfExists !== true) {
|
|
12524
|
-
throw new Error(`Additional
|
|
12543
|
+
throw new Error(`Additional property {${def.key}} already define.`);
|
|
12525
12544
|
}
|
|
12526
12545
|
// Replace existing
|
|
12527
12546
|
if (this._debug)
|
|
@@ -21313,11 +21332,19 @@ let UserSettings = class UserSettings extends Entity {
|
|
|
21313
21332
|
}
|
|
21314
21333
|
this.nonce = source.nonce;
|
|
21315
21334
|
}
|
|
21316
|
-
|
|
21335
|
+
/**
|
|
21336
|
+
* Merges the given source object into the current instance.
|
|
21337
|
+
*
|
|
21338
|
+
* @param {S} source - The source object containing properties to merge.
|
|
21339
|
+
* @param {Array<keyof S | string | number>} [includedProperties] - Optional array of property keys to be merged into the content map.
|
|
21340
|
+
* @param {boolean} [resetContent] - Optional flag to reset existing content. False by default
|
|
21341
|
+
* @return {boolean} - Returns true if any changes were made; otherwise, false.
|
|
21342
|
+
*/
|
|
21343
|
+
merge(source, includedProperties, resetContent) {
|
|
21317
21344
|
if (!source)
|
|
21318
21345
|
return; // Skip
|
|
21319
|
-
// Reset content
|
|
21320
|
-
this.content = {};
|
|
21346
|
+
// Reset or init content
|
|
21347
|
+
this.content = resetContent ? {} : this.content || {};
|
|
21321
21348
|
let hasChanges = false;
|
|
21322
21349
|
// For each property of source object
|
|
21323
21350
|
Object.keys(source).forEach((key) => {
|
|
@@ -21329,13 +21356,14 @@ let UserSettings = class UserSettings extends Entity {
|
|
|
21329
21356
|
}
|
|
21330
21357
|
}
|
|
21331
21358
|
// Else, store property into the 'content' map
|
|
21332
|
-
else if (
|
|
21333
|
-
|
|
21334
|
-
|
|
21335
|
-
|
|
21359
|
+
else if (includedProperties && includedProperties.includes(key)) {
|
|
21360
|
+
const sourceValue = source[key];
|
|
21361
|
+
if (!equals(this.content[key], sourceValue)) {
|
|
21362
|
+
if (typeof sourceValue === 'object' && sourceValue !== null) {
|
|
21363
|
+
this.content[key] = { ...this.content[key], ...sourceValue }; // Merge object
|
|
21336
21364
|
}
|
|
21337
21365
|
else {
|
|
21338
|
-
this.content[key] =
|
|
21366
|
+
this.content[key] = sourceValue;
|
|
21339
21367
|
}
|
|
21340
21368
|
hasChanges = true;
|
|
21341
21369
|
}
|
|
@@ -21343,7 +21371,11 @@ let UserSettings = class UserSettings extends Entity {
|
|
|
21343
21371
|
});
|
|
21344
21372
|
return hasChanges;
|
|
21345
21373
|
}
|
|
21346
|
-
|
|
21374
|
+
/**
|
|
21375
|
+
* Transform user settings into local settings
|
|
21376
|
+
* @param opts
|
|
21377
|
+
*/
|
|
21378
|
+
asLocalSettings(opts) {
|
|
21347
21379
|
const target = {};
|
|
21348
21380
|
UserSettings_1.SETTINGS_PROPERTIES.forEach((key) => {
|
|
21349
21381
|
target[key] = this[key];
|
|
@@ -21351,9 +21383,14 @@ let UserSettings = class UserSettings extends Entity {
|
|
|
21351
21383
|
Object.keys(this.content).forEach((key) => {
|
|
21352
21384
|
target[key] = this.content[key];
|
|
21353
21385
|
});
|
|
21386
|
+
// Sanitize properties
|
|
21387
|
+
const includedKeys = opts?.definitions?.map((def) => def.key) || [];
|
|
21388
|
+
if (isNotEmptyArray(includedKeys)) {
|
|
21389
|
+
target.properties = AppPropertiesUtils.sanitize(target.properties, { includedKeys });
|
|
21390
|
+
}
|
|
21354
21391
|
// Clear properties if empty, to avoid to reset the existing properties - See issue sumaris-app#897
|
|
21355
|
-
if (Object.keys(target
|
|
21356
|
-
delete target
|
|
21392
|
+
if (Object.keys(target.properties || {}).length === 0) {
|
|
21393
|
+
delete target.properties;
|
|
21357
21394
|
}
|
|
21358
21395
|
return target;
|
|
21359
21396
|
}
|
|
@@ -21664,6 +21701,7 @@ class AccountService extends BaseGraphqlService {
|
|
|
21664
21701
|
department: null,
|
|
21665
21702
|
};
|
|
21666
21703
|
_optionDefs;
|
|
21704
|
+
_remoteLocalSettingsKeys;
|
|
21667
21705
|
_$additionalFields = new BehaviorSubject([]);
|
|
21668
21706
|
_tokenType$ = new BehaviorSubject(undefined);
|
|
21669
21707
|
_apiTokenEnabled = true;
|
|
@@ -21718,6 +21756,7 @@ class AccountService extends BaseGraphqlService {
|
|
|
21718
21756
|
if (this._debug)
|
|
21719
21757
|
console.debug('[account-service] Creating service');
|
|
21720
21758
|
this._optionDefs = Object.values(options?.options || {});
|
|
21759
|
+
this._remoteLocalSettingsKeys = options?.remoteLocalSettingsKeys || [];
|
|
21721
21760
|
this.resetData();
|
|
21722
21761
|
// Send auth token to the graphql layer, when changed
|
|
21723
21762
|
this.onAuthTokenChange.subscribe((token) => this.graphql.setAuthToken(token));
|
|
@@ -21843,9 +21882,7 @@ class AccountService extends BaseGraphqlService {
|
|
|
21843
21882
|
data.account.pubkey = Base58.encode(keypair.publicKey);
|
|
21844
21883
|
// Default values
|
|
21845
21884
|
data.account.settings = data.account.settings || new UserSettings();
|
|
21846
|
-
data.account.settings.
|
|
21847
|
-
data.account.settings.latLongFormat = this.settings.latLongFormat;
|
|
21848
|
-
data.account.settings.content = data.account.settings.content || {};
|
|
21885
|
+
data.account.settings.merge(this.settings.settings, this._remoteLocalSettingsKeys, true);
|
|
21849
21886
|
data.account.department.id = data.account.department.id || this.environment.defaultDepartmentId;
|
|
21850
21887
|
this._cache.keypair = keypair;
|
|
21851
21888
|
const account = await this.saveRemotely(data.account, keypair);
|
|
@@ -22325,6 +22362,7 @@ class AccountService extends BaseGraphqlService {
|
|
|
22325
22362
|
if (!this._cache.pubkey)
|
|
22326
22363
|
throw new Error('User not logged');
|
|
22327
22364
|
this._cache.loaded = false;
|
|
22365
|
+
console.debug('[account-service] Loading account data...');
|
|
22328
22366
|
try {
|
|
22329
22367
|
const account = (await this.load(opts)) || new Account();
|
|
22330
22368
|
// Set defaults
|
|
@@ -22345,8 +22383,21 @@ class AccountService extends BaseGraphqlService {
|
|
|
22345
22383
|
this._cache.loaded = true;
|
|
22346
22384
|
// Apply settings, found in remote account
|
|
22347
22385
|
if (account.settings && this.settings.settings.accountInheritance) {
|
|
22386
|
+
console.debug('[account-service] Copying account settings into local settings...');
|
|
22387
|
+
const localSettings = this.settings.settings;
|
|
22348
22388
|
const accountSettings = account.settings.asLocalSettings();
|
|
22349
|
-
|
|
22389
|
+
const definitions = removeDuplicatesFromArray([...this.optionDefs, ...this.settings.optionDefs], 'key');
|
|
22390
|
+
const mergedProperties = AppPropertiesUtils.sanitize({
|
|
22391
|
+
...localSettings.properties,
|
|
22392
|
+
...accountSettings.properties,
|
|
22393
|
+
}, { definitions });
|
|
22394
|
+
// Merge local/account settings
|
|
22395
|
+
const settings = {
|
|
22396
|
+
...localSettings,
|
|
22397
|
+
...accountSettings,
|
|
22398
|
+
properties: mergedProperties,
|
|
22399
|
+
};
|
|
22400
|
+
await this.settings.apply(settings);
|
|
22350
22401
|
}
|
|
22351
22402
|
return this._data;
|
|
22352
22403
|
}
|
|
@@ -22506,7 +22557,7 @@ class AccountService extends BaseGraphqlService {
|
|
|
22506
22557
|
const account = this.account;
|
|
22507
22558
|
// Merge local settings into account's settings
|
|
22508
22559
|
const settings = UserSettings.fromObject(account.settings) || new UserSettings();
|
|
22509
|
-
const changed = settings.merge(source,
|
|
22560
|
+
const changed = settings.merge(source, this._remoteLocalSettingsKeys);
|
|
22510
22561
|
if (!changed)
|
|
22511
22562
|
return; // Skip if unchanged
|
|
22512
22563
|
// Save remotely
|
|
@@ -23618,10 +23669,11 @@ class PlatformService extends StartableService {
|
|
|
23618
23669
|
}
|
|
23619
23670
|
}));
|
|
23620
23671
|
// Use account's settings, (like locale), when account inheritance enabled
|
|
23621
|
-
this.registerSubscription(this.accountService.onLogin.subscribe((account) => {
|
|
23672
|
+
this.registerSubscription(this.accountService.onLogin.subscribe(async (account) => {
|
|
23622
23673
|
if (account.settings && this.settings.settings.accountInheritance) {
|
|
23674
|
+
console.debug('[platform] Copying account settings into local settings...');
|
|
23623
23675
|
const accountSettings = account.settings.asLocalSettings();
|
|
23624
|
-
this.settings.apply(accountSettings);
|
|
23676
|
+
await this.settings.apply(accountSettings);
|
|
23625
23677
|
}
|
|
23626
23678
|
}));
|
|
23627
23679
|
}
|
|
@@ -30110,10 +30162,10 @@ class AppValidatorService extends ValidatorService {
|
|
|
30110
30162
|
getRowValidator() {
|
|
30111
30163
|
return this.getFormGroup();
|
|
30112
30164
|
}
|
|
30113
|
-
getFormGroup(data) {
|
|
30165
|
+
getFormGroup(data, opts) {
|
|
30114
30166
|
return this.formBuilder.group(this.getFormGroupConfig(data));
|
|
30115
30167
|
}
|
|
30116
|
-
getFormGroupConfig(data) {
|
|
30168
|
+
getFormGroupConfig(data, opts) {
|
|
30117
30169
|
return {};
|
|
30118
30170
|
}
|
|
30119
30171
|
getI18nFormErrors(control) {
|
|
@@ -34765,9 +34817,12 @@ let PropertyEntity = class PropertyEntity extends Entity {
|
|
|
34765
34817
|
static fromObject;
|
|
34766
34818
|
definition = null;
|
|
34767
34819
|
value = null;
|
|
34820
|
+
get key() {
|
|
34821
|
+
return this.definition?.key || this.id;
|
|
34822
|
+
}
|
|
34768
34823
|
fromObject(source) {
|
|
34769
34824
|
super.fromObject(source);
|
|
34770
|
-
this.id = source.definition?.key
|
|
34825
|
+
this.id = source.definition?.key ?? source.key ?? source.id;
|
|
34771
34826
|
this.definition = source.definition;
|
|
34772
34827
|
this.value = source.value;
|
|
34773
34828
|
}
|
|
@@ -34835,15 +34890,13 @@ class AppPropertiesTable extends AppInMemoryTable {
|
|
|
34835
34890
|
definitions;
|
|
34836
34891
|
showToolbar = true;
|
|
34837
34892
|
filterExpansionPanel;
|
|
34838
|
-
// availableDefinitions$ = new BehaviorSubject<TranslatedFormFieldDefinition[]>([]);
|
|
34839
34893
|
definitionsMapByKey = {};
|
|
34840
|
-
translationsByKey = {};
|
|
34841
34894
|
filterForm;
|
|
34842
34895
|
filterCriteriaCount = 0;
|
|
34843
34896
|
filterPanelFloating = true;
|
|
34844
34897
|
constructor(injector, formBuilder, validatorService, environment) {
|
|
34845
34898
|
super(injector, [...RESERVED_START_COLUMNS, 'definition', 'value', ...RESERVED_END_COLUMNS], PropertyEntity, new InMemoryEntitiesService(PropertyEntity, PropertyEntityFilter, {
|
|
34846
|
-
sortByReplacement: { definition: 'definition.
|
|
34899
|
+
sortByReplacement: { definition: 'definition.label' },
|
|
34847
34900
|
}), validatorService);
|
|
34848
34901
|
this.injector = injector;
|
|
34849
34902
|
this.formBuilder = formBuilder;
|
|
@@ -34860,11 +34913,14 @@ class AppPropertiesTable extends AppInMemoryTable {
|
|
|
34860
34913
|
}
|
|
34861
34914
|
ngOnInit() {
|
|
34862
34915
|
super.ngOnInit();
|
|
34863
|
-
// Fill
|
|
34864
|
-
this.
|
|
34865
|
-
|
|
34866
|
-
|
|
34916
|
+
// Fill definitions map
|
|
34917
|
+
this.definitions = (this.definitions || []).map((def) => {
|
|
34918
|
+
return {
|
|
34919
|
+
...def,
|
|
34920
|
+
label: this.translate.instant(def.label),
|
|
34921
|
+
};
|
|
34867
34922
|
});
|
|
34923
|
+
this.definitionsMapByKey = splitByProperty(this.definitions, 'key');
|
|
34868
34924
|
this.registerCellValueChanges('definition').subscribe((definition) => {
|
|
34869
34925
|
if (isNotNil(definition) && this.editedRow?.id === -1) {
|
|
34870
34926
|
this.editedRow.validator.patchValue({ id: definition.key, value: definition.defaultValue });
|
|
@@ -34897,18 +34953,18 @@ class AppPropertiesTable extends AppInMemoryTable {
|
|
|
34897
34953
|
}
|
|
34898
34954
|
definitionByRow = (row) => this.definitionsMapByKey[row.currentData.id];
|
|
34899
34955
|
setValue(value, opts) {
|
|
34900
|
-
// Update translations
|
|
34901
|
-
this.translationsByKey = isNotEmptyArray(this.definitions) ? this.translate.instant(this.definitions.map((def) => def.label)) : {};
|
|
34902
34956
|
// Build entities
|
|
34903
|
-
const
|
|
34904
|
-
|
|
34905
|
-
|
|
34906
|
-
|
|
34907
|
-
|
|
34908
|
-
|
|
34909
|
-
|
|
34910
|
-
|
|
34911
|
-
|
|
34957
|
+
const target = this.definitions.map((definition) => {
|
|
34958
|
+
const property = (value || [])?.find((source) => source.key === definition.key);
|
|
34959
|
+
const propertyValue = property?.value ?? definition.defaultValue;
|
|
34960
|
+
// Convert to entity
|
|
34961
|
+
return PropertyEntity.fromObject({
|
|
34962
|
+
id: definition.key,
|
|
34963
|
+
definition,
|
|
34964
|
+
// get user value or default value
|
|
34965
|
+
value: propertyValue,
|
|
34966
|
+
});
|
|
34967
|
+
});
|
|
34912
34968
|
super.setValue(target, opts);
|
|
34913
34969
|
}
|
|
34914
34970
|
clearControlValue(event, formControl) {
|
|
@@ -34959,26 +35015,18 @@ class AppPropertiesTable extends AppInMemoryTable {
|
|
|
34959
35015
|
if (this.filterExpansionPanel && this.filterPanelFloating)
|
|
34960
35016
|
this.filterExpansionPanel.close();
|
|
34961
35017
|
}
|
|
34962
|
-
toTranslatedFormFieldDefinition = (definition) => ({
|
|
34963
|
-
...definition,
|
|
34964
|
-
translatedName: this.translationsByKey[definition.label],
|
|
34965
|
-
});
|
|
34966
35018
|
resetProperty(event, row) {
|
|
34967
35019
|
event?.preventDefault();
|
|
34968
35020
|
row.validator.patchValue({ value: row.currentData.definition.defaultValue });
|
|
34969
|
-
|
|
35021
|
+
this.confirmEditCreate();
|
|
34970
35022
|
this.markRowAsDirty();
|
|
34971
35023
|
}
|
|
34972
|
-
toValue(values, definition) {
|
|
34973
|
-
const value = values.find((v) => v.id === definition.key)?.value;
|
|
34974
|
-
return isNotNil(value) ? value : definition.defaultValue;
|
|
34975
|
-
}
|
|
34976
35024
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AppPropertiesTable, deps: [{ token: i0.Injector }, { token: i1$3.UntypedFormBuilder }, { token: PropertyEntityValidator }, { token: ENVIRONMENT }], target: i0.ɵɵFactoryTarget.Component });
|
|
34977
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: AppPropertiesTable, selector: "app-properties-table", inputs: { definitions: "definitions", showToolbar: "showToolbar" }, providers: [{ provide: PropertyEntityValidator, useClass: PropertyEntityValidator }], viewQueries: [{ propertyName: "filterExpansionPanel", first: true, predicate: MatExpansionPanel, descendants: true, static: true }], usesInheritance: true, ngImport: i0, template: "<mat-toolbar *ngIf=\"showToolbar\" [class.expanded]=\"filterExpansionPanel.expanded\">\n <!-- Refresh -->\n <button mat-icon-button *ngIf=\"!mobile\" [title]=\"'COMMON.BTN_REFRESH' | translate\" (click)=\"emitRefresh()\">\n <mat-icon>refresh</mat-icon>\n </button>\n\n <ion-item *ngIf=\"!mobile && error; let error\" lines=\"none\">\n <ion-icon color=\"danger\" slot=\"start\" name=\"alert-circle\"></ion-icon>\n <ion-label color=\"danger\" [innerHTML]=\"error | translate\"></ion-label>\n </ion-item>\n\n <div class=\"toolbar-spacer\"></div>\n\n <!-- Reset filter -->\n <button mat-icon-button (click)=\"resetFilter()\" *ngIf=\"filterCriteriaCount\">\n <mat-icon color=\"accent\">filter_list_alt</mat-icon>\n <mat-icon class=\"icon-secondary\" style=\"left: 16px; top: 5px; font-weight: bold\">close</mat-icon>\n </button>\n\n <!-- Show filter -->\n <button mat-icon-button (click)=\"filterExpansionPanel.toggle()\">\n <mat-icon\n [matBadge]=\"filterCriteriaCount\"\n [matBadgeHidden]=\"filterIsEmpty\"\n matBadgeColor=\"accent\"\n matBadgeSize=\"small\"\n matBadgePosition=\"above after\"\n aria-hidden=\"false\"\n >\n filter_list_alt\n </mat-icon>\n </button>\n</mat-toolbar>\n\n<ion-content class=\"ion-no-padding\">\n <!-- search -->\n <mat-expansion-panel\n #filterExpansionPanel\n class=\"filter-panel\"\n [class.ion-no-padding]=\"mobile\"\n [class.filter-panel-floating]=\"filterPanelFloating\"\n >\n <form class=\"form-container\" [formGroup]=\"filterForm\" (ngSubmit)=\"emitRefresh()\">\n <ion-grid>\n <ion-row>\n <ion-col>\n <!-- search -->\n <mat-form-field>\n <mat-label>{{ 'SETTINGS.FILTER.SEARCH' | translate }}</mat-label>\n <input matInput formControlName=\"searchText\" />\n\n <button\n mat-icon-button\n matSuffix\n tabindex=\"-1\"\n type=\"button\"\n (click)=\"clearControlValue($event, filterForm.controls.searchText)\"\n [hidden]=\"filterForm.controls.searchText.disabled || !filterForm.controls.searchText.value\"\n >\n <mat-icon>close</mat-icon>\n </button>\n </mat-form-field>\n </ion-col>\n\n <ion-col>\n <mat-boolean-field\n [style]=\"'checkbox'\"\n formControlName=\"notDefaultOnly\"\n [placeholder]=\"'SETTINGS.FILTER.ONLY_NOT_DEFAULT' | translate\"\n floatLabel=\"always\"\n ></mat-boolean-field>\n </ion-col>\n </ion-row>\n </ion-grid>\n </form>\n\n <mat-action-row>\n <!-- Counter -->\n <ion-label\n [hidden]=\"(loadingSubject | async) || filterForm.dirty\"\n [color]=\"empty && 'danger'\"\n class=\"ion-padding\"\n >\n {{\n (totalRowCount ? 'COMMON.RESULT_COUNT' : 'COMMON.NO_RESULT')\n | translate\n : {\n count: (totalRowCount | numberFormat)\n }\n }}\n </ion-label>\n\n <div class=\"toolbar-spacer\"></div>\n\n <button\n mat-icon-button\n color=\"accent\"\n *ngIf=\"filterPanelFloating\"\n (click)=\"toggleFilterPanelFloating()\"\n class=\"hidden-xs hidden-sm hidden-md\"\n [title]=\"(filterPanelFloating ? 'COMMON.BTN_EXPAND' : 'COMMON.BTN_HIDE') | translate\"\n >\n <mat-icon>\n <span style=\"transform: rotate(90deg)\">{{ filterPanelFloating ? '»' : '«' }}</span>\n </mat-icon>\n </button>\n\n <!-- Close panel -->\n <ion-button mat-button fill=\"clear\" color=\"dark\" (click)=\"closeFilterPanel()\" [disabled]=\"loadingSubject | async\">\n <ion-text translate>COMMON.BTN_CLOSE</ion-text>\n </ion-button>\n\n <!-- Search button -->\n <ion-button\n mat-button\n [color]=\"filterForm.dirty ? 'tertiary' : 'dark'\"\n [fill]=\"filterForm.dirty ? 'solid' : 'clear'\"\n (click)=\"applyFilterAndClosePanel($event)\"\n [disabled]=\"loadingSubject | async\"\n >\n <ion-text translate>COMMON.BTN_APPLY</ion-text>\n </ion-button>\n </mat-action-row>\n </mat-expansion-panel>\n\n <ion-refresher slot=\"fixed\" *ngIf=\"mobile\" (ionRefresh)=\"doRefresh($event)\">\n <ion-refresher-content></ion-refresher-content>\n </ion-refresher>\n\n <!-- table -->\n <div class=\"table-container\">\n <table\n #table\n mat-table\n matSort\n matSortDisableClear\n [dataSource]=\"dataSource\"\n [matSortActive]=\"defaultSortBy\"\n [matSortDirection]=\"defaultSortDirection\"\n [trackBy]=\"trackByFn\"\n [style.--mat-row-height]=\"'52px'\"\n >\n <ng-container matColumnDef=\"select\">\n <th mat-header-cell *matHeaderCellDef [class.cdk-visually-hidden]=\"true\"></th>\n <td mat-cell *matCellDef=\"let row\" [class.cdk-visually-hidden]=\"true\"></td>\n </ng-container>\n\n <!-- id column (hidden) -->\n <ng-container matColumnDef=\"id\">\n <th mat-header-cell *matHeaderCellDef [class.cdk-visually-hidden]=\"!debug\"></th>\n <td mat-cell *matCellDef=\"let row\" [class.cdk-visually-hidden]=\"!debug\">\n {{ row.currentData.id }}\n </td>\n </ng-container>\n\n <!-- definition column -->\n <ng-container matColumnDef=\"definition\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header class=\"ion-padding-start\">\n <ion-label>{{ i18nColumnPrefix + 'DEFINITION' | translate }}</ion-label>\n </th>\n <td mat-cell *matCellDef=\"let row\" class=\"ion-padding-start\">\n {{ row.currentData | propertyGet: 'definition.translatedName' }}\n </td>\n </ng-container>\n\n <!-- value column -->\n <app-row-field\n name=\"value\"\n floatLabel=\"never\"\n [definitionFn]=\"definitionByRow\"\n [headerI18n]=\"i18nColumnPrefix + 'VALUE'\"\n [required]=\"true\"\n ></app-row-field>\n\n <!-- Actions buttons column -->\n <app-actions-column\n [stickyEnd]=\"true\"\n [canCancel]=\"false\"\n [canDelete]=\"false\"\n [dirtyIcon]=\"false\"\n [cellTemplate]=\"cellInjection\"\n >\n <!-- cell injection-->\n <ng-template #cellInjection let-row>\n <button\n type=\"button\"\n mat-icon-button\n *ngIf=\"\n !mobile &&\n !disabled &&\n (row.validator | formGetValue: 'value') !== (row.validator | formGetValue: 'definition').defaultValue\n \"\n [class.visible-hover-row]=\"!mobile\"\n [tabindex]=\"-1\"\n [title]=\"'SETTINGS.BTN_RESET_PROPERTY' | translate\"\n (click)=\"resetProperty($event, row)\"\n >\n <mat-icon>undo</mat-icon>\n </button>\n </ng-template>\n </app-actions-column>\n\n <tr mat-header-row *matHeaderRowDef=\"displayedColumns; sticky: true\"></tr>\n <tr\n mat-row\n *matRowDef=\"let row; columns: displayedColumns\"\n [class.mat-row-selected]=\"row.editing\"\n [class.mat-row-error]=\"row.validator?.invalid\"\n [class.mat-row-dirty]=\"row.validator?.dirty\"\n (click)=\"clickRow($event, row)\"\n (keydown.escape)=\"escapeEditingRow($event)\"\n [cdkTrapFocus]=\"row.validator?.invalid\"\n ></tr>\n </table>\n\n <ng-container *ngIf=\"loadingSubject | async; else noResult\">\n <ion-item>\n <ion-skeleton-text animated></ion-skeleton-text>\n </ion-item>\n </ng-container>\n\n <ng-template #noResult>\n <ion-item *ngIf=\"totalRowCount === 0\">\n <ion-text color=\"danger\" class=\"text-italic\" translate>COMMON.NO_RESULT</ion-text>\n </ion-item>\n </ng-template>\n </div>\n</ion-content>\n", styles: [""], dependencies: [{ 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.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", "forceOverscroll", "fullscreen", "scrollEvents", "scrollX", "scrollY"] }, { kind: "component", type: i2$1.IonGrid, selector: "ion-grid", inputs: ["fixed"] }, { 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.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$1.IonLabel, selector: "ion-label", inputs: ["color", "mode", "position"] }, { kind: "component", type: i2$1.IonRefresher, selector: "ion-refresher", inputs: ["closeDuration", "disabled", "mode", "pullFactor", "pullMax", "pullMin", "snapbackDuration"] }, { kind: "component", type: i2$1.IonRefresherContent, selector: "ion-refresher-content", inputs: ["pullingIcon", "pullingText", "refreshingSpinner", "refreshingText"] }, { kind: "component", type: i2$1.IonRow, selector: "ion-row" }, { kind: "component", type: i2$1.IonSkeletonText, selector: "ion-skeleton-text", inputs: ["animated"] }, { kind: "component", type: i2$1.IonText, selector: "ion-text", inputs: ["color", "mode"] }, { kind: "directive", type: i1$1.TranslateDirective, selector: "[translate],[ngx-translate]", inputs: ["translate", "translateParams"] }, { kind: "directive", type: i1$3.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$3.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$3.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$3.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$3.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: i1$6.MatTable, selector: "mat-table, table[mat-table]", exportAs: ["matTable"] }, { kind: "directive", type: i1$6.MatHeaderCellDef, selector: "[matHeaderCellDef]" }, { kind: "directive", type: i1$6.MatHeaderRowDef, selector: "[matHeaderRowDef]", inputs: ["matHeaderRowDef", "matHeaderRowDefSticky"] }, { kind: "directive", type: i1$6.MatColumnDef, selector: "[matColumnDef]", inputs: ["matColumnDef"] }, { kind: "directive", type: i1$6.MatCellDef, selector: "[matCellDef]" }, { kind: "directive", type: i1$6.MatRowDef, selector: "[matRowDef]", inputs: ["matRowDefColumns", "matRowDefWhen"] }, { kind: "directive", type: i1$6.MatHeaderCell, selector: "mat-header-cell, th[mat-header-cell]" }, { kind: "directive", type: i1$6.MatCell, selector: "mat-cell, td[mat-cell]" }, { kind: "component", type: i1$6.MatHeaderRow, selector: "mat-header-row, tr[mat-header-row]", exportAs: ["matHeaderRow"] }, { kind: "component", type: i1$6.MatRow, selector: "mat-row, tr[mat-row]", exportAs: ["matRow"] }, { kind: "directive", type: i8$2.MatSort, selector: "[matSort]", inputs: ["matSortActive", "matSortStart", "matSortDirection", "matSortDisableClear", "matSortDisabled"], outputs: ["matSortChange"], exportAs: ["matSort"] }, { kind: "component", type: i8$2.MatSortHeader, selector: "[mat-sort-header]", inputs: ["mat-sort-header", "arrowPosition", "start", "disabled", "sortActionDescription", "disableClear"], exportAs: ["matSortHeader"] }, { kind: "component", type: i6.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i6.MatLabel, selector: "mat-label" }, { kind: "directive", type: i6.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "directive", type: i7.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "component", type: i13$2.MatExpansionPanel, selector: "mat-expansion-panel", inputs: ["hideToggle", "togglePosition"], outputs: ["afterExpand", "afterCollapse"], exportAs: ["matExpansionPanel"] }, { kind: "directive", type: i13$2.MatExpansionPanelActionRow, selector: "mat-action-row" }, { kind: "component", type: i11$2.MatToolbar, selector: "mat-toolbar", inputs: ["color"], exportAs: ["matToolbar"] }, { kind: "component", type: i6$2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i9.MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "directive", type: i8.MatBadge, selector: "[matBadge]", inputs: ["matBadgeColor", "matBadgeOverlap", "matBadgeDisabled", "matBadgePosition", "matBadge", "matBadgeDescription", "matBadgeSize", "matBadgeHidden"] }, { kind: "directive", type: i1$4.CdkTrapFocus, selector: "[cdkTrapFocus]", inputs: ["cdkTrapFocus", "cdkTrapFocusAutoCapture"], exportAs: ["cdkTrapFocus"] }, { kind: "component", type: MatBooleanField, selector: "mat-boolean-field", inputs: ["disabled", "formControl", "formControlName", "placeholder", "floatLabel", "appearance", "subscriptSizing", "readonly", "required", "compact", "style", "buttonsColCount", "class", "yesLabel", "noLabel", "showButtonIcons", "yesIcon", "noIcon", "clearable", "labelPosition", "tabindex", "showRadio", "value"], outputs: ["keyup.enter", "focus", "blur"] }, { kind: "component", type: ActionsColumnComponent, selector: "app-actions-column", inputs: ["matColumnDef", "style", "stickyEnd", "canCancel", "canConfirm", "canDelete", "canBackward", "canForward", "canConfirmAndAdd", "dirtyIcon", "optionsTitle", "class", "cellTemplate"], outputs: ["optionsClick", "cancelOrDeleteClick", "confirmEditCreateClick", "confirmAndAddClick", "backward", "forward"] }, { kind: "component", type: AppRowField, selector: "app-row-field", inputs: ["name", "definition", "definitionFn", "headerI18n", "sortable", "resizable", "required", "readonly", "sticky", "draggable", "disabled", "placeholder", "compact", "floatLabel", "appearance", "tabindex", "autofocus", "clearable", "chipColor", "class", "debug"] }, { kind: "pipe", type: i3.AsyncPipe, name: "async" }, { kind: "pipe", type: i1$1.TranslatePipe, name: "translate" }, { kind: "pipe", type: PropertyGetPipe, name: "propertyGet" }, { kind: "pipe", type: NumberFormatPipe, name: "numberFormat" }, { kind: "pipe", type: FormGetValuePipe, name: "formGetValue" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
35025
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: AppPropertiesTable, selector: "app-properties-table", inputs: { definitions: "definitions", showToolbar: "showToolbar" }, providers: [{ provide: PropertyEntityValidator, useClass: PropertyEntityValidator }], viewQueries: [{ propertyName: "filterExpansionPanel", first: true, predicate: MatExpansionPanel, descendants: true, static: true }], usesInheritance: true, ngImport: i0, template: "<mat-toolbar *ngIf=\"showToolbar\" [class.expanded]=\"filterExpansionPanel.expanded\">\n <!-- Refresh -->\n <button mat-icon-button *ngIf=\"!mobile\" [title]=\"'COMMON.BTN_REFRESH' | translate\" (click)=\"emitRefresh()\">\n <mat-icon>refresh</mat-icon>\n </button>\n\n <ion-item *ngIf=\"!mobile && error; let error\" lines=\"none\">\n <ion-icon color=\"danger\" slot=\"start\" name=\"alert-circle\"></ion-icon>\n <ion-label color=\"danger\" [innerHTML]=\"error | translate\"></ion-label>\n </ion-item>\n\n <div class=\"toolbar-spacer\"></div>\n\n <!-- Reset filter -->\n <button mat-icon-button (click)=\"resetFilter()\" *ngIf=\"filterCriteriaCount\">\n <mat-icon color=\"accent\">filter_list_alt</mat-icon>\n <mat-icon class=\"icon-secondary\" style=\"left: 16px; top: 5px; font-weight: bold\">close</mat-icon>\n </button>\n\n <!-- Show filter -->\n <button mat-icon-button (click)=\"filterExpansionPanel.toggle()\">\n <mat-icon\n [matBadge]=\"filterCriteriaCount\"\n [matBadgeHidden]=\"filterIsEmpty\"\n matBadgeColor=\"accent\"\n matBadgeSize=\"small\"\n matBadgePosition=\"above after\"\n aria-hidden=\"false\"\n >\n filter_list_alt\n </mat-icon>\n </button>\n</mat-toolbar>\n\n<ion-content class=\"ion-no-padding\">\n <!-- search -->\n <mat-expansion-panel\n #filterExpansionPanel\n class=\"filter-panel\"\n [class.ion-no-padding]=\"mobile\"\n [class.filter-panel-floating]=\"filterPanelFloating\"\n >\n <form class=\"form-container\" [formGroup]=\"filterForm\" (ngSubmit)=\"emitRefresh()\">\n <ion-grid>\n <ion-row>\n <ion-col>\n <!-- search -->\n <mat-form-field>\n <mat-label>{{ 'SETTINGS.FILTER.SEARCH' | translate }}</mat-label>\n <input matInput formControlName=\"searchText\" />\n\n <button\n mat-icon-button\n matSuffix\n tabindex=\"-1\"\n type=\"button\"\n (click)=\"clearControlValue($event, filterForm.controls.searchText)\"\n [hidden]=\"filterForm.controls.searchText.disabled || !filterForm.controls.searchText.value\"\n >\n <mat-icon>close</mat-icon>\n </button>\n </mat-form-field>\n </ion-col>\n\n <ion-col>\n <mat-boolean-field\n [style]=\"'checkbox'\"\n formControlName=\"notDefaultOnly\"\n [placeholder]=\"'SETTINGS.FILTER.ONLY_NOT_DEFAULT' | translate\"\n floatLabel=\"always\"\n ></mat-boolean-field>\n </ion-col>\n </ion-row>\n </ion-grid>\n </form>\n\n <mat-action-row>\n <!-- Counter -->\n <ion-label\n [hidden]=\"(loadingSubject | async) || filterForm.dirty\"\n [color]=\"empty && 'danger'\"\n class=\"ion-padding\"\n >\n {{\n (totalRowCount ? 'COMMON.RESULT_COUNT' : 'COMMON.NO_RESULT')\n | translate\n : {\n count: (totalRowCount | numberFormat),\n }\n }}\n </ion-label>\n\n <div class=\"toolbar-spacer\"></div>\n\n <button\n mat-icon-button\n color=\"accent\"\n *ngIf=\"filterPanelFloating\"\n (click)=\"toggleFilterPanelFloating()\"\n class=\"hidden-xs hidden-sm hidden-md\"\n [title]=\"(filterPanelFloating ? 'COMMON.BTN_EXPAND' : 'COMMON.BTN_HIDE') | translate\"\n >\n <mat-icon>\n <span style=\"transform: rotate(90deg)\">{{ filterPanelFloating ? '»' : '«' }}</span>\n </mat-icon>\n </button>\n\n <!-- Close panel -->\n <ion-button mat-button fill=\"clear\" color=\"dark\" (click)=\"closeFilterPanel()\" [disabled]=\"loadingSubject | async\">\n <ion-text translate>COMMON.BTN_CLOSE</ion-text>\n </ion-button>\n\n <!-- Search button -->\n <ion-button\n mat-button\n [color]=\"filterForm.dirty ? 'tertiary' : 'dark'\"\n [fill]=\"filterForm.dirty ? 'solid' : 'clear'\"\n (click)=\"applyFilterAndClosePanel($event)\"\n [disabled]=\"loadingSubject | async\"\n >\n <ion-text translate>COMMON.BTN_APPLY</ion-text>\n </ion-button>\n </mat-action-row>\n </mat-expansion-panel>\n\n <ion-refresher slot=\"fixed\" *ngIf=\"mobile\" (ionRefresh)=\"doRefresh($event)\">\n <ion-refresher-content></ion-refresher-content>\n </ion-refresher>\n\n <!-- table -->\n <div class=\"table-container\">\n <table\n #table\n mat-table\n matSort\n matSortDisableClear\n [dataSource]=\"dataSource\"\n [matSortActive]=\"defaultSortBy\"\n [matSortDirection]=\"defaultSortDirection\"\n [trackBy]=\"trackByFn\"\n [style.--mat-row-height]=\"'52px'\"\n >\n <ng-container matColumnDef=\"select\">\n <th mat-header-cell *matHeaderCellDef [class.cdk-visually-hidden]=\"true\"></th>\n <td mat-cell *matCellDef=\"let row\" [class.cdk-visually-hidden]=\"true\"></td>\n </ng-container>\n\n <!-- id column (hidden) -->\n <ng-container matColumnDef=\"id\">\n <th mat-header-cell *matHeaderCellDef [class.cdk-visually-hidden]=\"!debug\"></th>\n <td mat-cell *matCellDef=\"let row\" [class.cdk-visually-hidden]=\"!debug\">\n {{ row.currentData.id }}\n </td>\n </ng-container>\n\n <!-- definition column -->\n <ng-container matColumnDef=\"definition\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header class=\"ion-padding-start\">\n <ion-label>{{ i18nColumnPrefix + 'DEFINITION' | translate }}</ion-label>\n </th>\n <td mat-cell *matCellDef=\"let row\" class=\"ion-padding-start\">\n {{ row.currentData | propertyGet: 'definition.label' }}\n </td>\n </ng-container>\n\n <!-- value column -->\n <app-row-field\n name=\"value\"\n floatLabel=\"never\"\n [definitionFn]=\"definitionByRow\"\n [headerI18n]=\"i18nColumnPrefix + 'VALUE'\"\n [required]=\"true\"\n ></app-row-field>\n\n <!-- Actions buttons column -->\n <app-actions-column\n [stickyEnd]=\"true\"\n [canCancel]=\"false\"\n [canDelete]=\"false\"\n [dirtyIcon]=\"false\"\n [cellTemplate]=\"cellInjection\"\n >\n <!-- cell injection-->\n <ng-template #cellInjection let-row>\n <button\n type=\"button\"\n mat-icon-button\n *ngIf=\"\n !mobile &&\n !disabled &&\n (row.validator | formGetValue: 'value') !== (row.validator | formGetValue: 'definition').defaultValue\n \"\n [class.visible-hover-row]=\"!mobile\"\n [tabindex]=\"-1\"\n [title]=\"'SETTINGS.BTN_RESET_PROPERTY' | translate\"\n (click)=\"resetProperty($event, row)\"\n >\n <mat-icon>undo</mat-icon>\n </button>\n </ng-template>\n </app-actions-column>\n\n <tr mat-header-row *matHeaderRowDef=\"displayedColumns; sticky: true\"></tr>\n <tr\n mat-row\n *matRowDef=\"let row; columns: displayedColumns\"\n [class.mat-row-selected]=\"row.editing\"\n [class.mat-row-error]=\"row.validator?.invalid\"\n [class.mat-row-dirty]=\"row.validator?.dirty\"\n (click)=\"clickRow($event, row)\"\n (keydown.escape)=\"escapeEditingRow($event)\"\n [cdkTrapFocus]=\"row.validator?.invalid\"\n ></tr>\n </table>\n\n <ng-container *ngIf=\"loadingSubject | async; else noResult\">\n <ion-item>\n <ion-skeleton-text animated></ion-skeleton-text>\n </ion-item>\n </ng-container>\n\n <ng-template #noResult>\n <ion-item *ngIf=\"totalRowCount === 0\">\n <ion-text color=\"danger\" class=\"text-italic\" translate>COMMON.NO_RESULT</ion-text>\n </ion-item>\n </ng-template>\n </div>\n</ion-content>\n", styles: [""], dependencies: [{ 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.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", "forceOverscroll", "fullscreen", "scrollEvents", "scrollX", "scrollY"] }, { kind: "component", type: i2$1.IonGrid, selector: "ion-grid", inputs: ["fixed"] }, { 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.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$1.IonLabel, selector: "ion-label", inputs: ["color", "mode", "position"] }, { kind: "component", type: i2$1.IonRefresher, selector: "ion-refresher", inputs: ["closeDuration", "disabled", "mode", "pullFactor", "pullMax", "pullMin", "snapbackDuration"] }, { kind: "component", type: i2$1.IonRefresherContent, selector: "ion-refresher-content", inputs: ["pullingIcon", "pullingText", "refreshingSpinner", "refreshingText"] }, { kind: "component", type: i2$1.IonRow, selector: "ion-row" }, { kind: "component", type: i2$1.IonSkeletonText, selector: "ion-skeleton-text", inputs: ["animated"] }, { kind: "component", type: i2$1.IonText, selector: "ion-text", inputs: ["color", "mode"] }, { kind: "directive", type: i1$1.TranslateDirective, selector: "[translate],[ngx-translate]", inputs: ["translate", "translateParams"] }, { kind: "directive", type: i1$3.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$3.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$3.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$3.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$3.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: i1$6.MatTable, selector: "mat-table, table[mat-table]", exportAs: ["matTable"] }, { kind: "directive", type: i1$6.MatHeaderCellDef, selector: "[matHeaderCellDef]" }, { kind: "directive", type: i1$6.MatHeaderRowDef, selector: "[matHeaderRowDef]", inputs: ["matHeaderRowDef", "matHeaderRowDefSticky"] }, { kind: "directive", type: i1$6.MatColumnDef, selector: "[matColumnDef]", inputs: ["matColumnDef"] }, { kind: "directive", type: i1$6.MatCellDef, selector: "[matCellDef]" }, { kind: "directive", type: i1$6.MatRowDef, selector: "[matRowDef]", inputs: ["matRowDefColumns", "matRowDefWhen"] }, { kind: "directive", type: i1$6.MatHeaderCell, selector: "mat-header-cell, th[mat-header-cell]" }, { kind: "directive", type: i1$6.MatCell, selector: "mat-cell, td[mat-cell]" }, { kind: "component", type: i1$6.MatHeaderRow, selector: "mat-header-row, tr[mat-header-row]", exportAs: ["matHeaderRow"] }, { kind: "component", type: i1$6.MatRow, selector: "mat-row, tr[mat-row]", exportAs: ["matRow"] }, { kind: "directive", type: i8$2.MatSort, selector: "[matSort]", inputs: ["matSortActive", "matSortStart", "matSortDirection", "matSortDisableClear", "matSortDisabled"], outputs: ["matSortChange"], exportAs: ["matSort"] }, { kind: "component", type: i8$2.MatSortHeader, selector: "[mat-sort-header]", inputs: ["mat-sort-header", "arrowPosition", "start", "disabled", "sortActionDescription", "disableClear"], exportAs: ["matSortHeader"] }, { kind: "component", type: i6.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i6.MatLabel, selector: "mat-label" }, { kind: "directive", type: i6.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "directive", type: i7.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "component", type: i13$2.MatExpansionPanel, selector: "mat-expansion-panel", inputs: ["hideToggle", "togglePosition"], outputs: ["afterExpand", "afterCollapse"], exportAs: ["matExpansionPanel"] }, { kind: "directive", type: i13$2.MatExpansionPanelActionRow, selector: "mat-action-row" }, { kind: "component", type: i11$2.MatToolbar, selector: "mat-toolbar", inputs: ["color"], exportAs: ["matToolbar"] }, { kind: "component", type: i6$2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i9.MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "directive", type: i8.MatBadge, selector: "[matBadge]", inputs: ["matBadgeColor", "matBadgeOverlap", "matBadgeDisabled", "matBadgePosition", "matBadge", "matBadgeDescription", "matBadgeSize", "matBadgeHidden"] }, { kind: "directive", type: i1$4.CdkTrapFocus, selector: "[cdkTrapFocus]", inputs: ["cdkTrapFocus", "cdkTrapFocusAutoCapture"], exportAs: ["cdkTrapFocus"] }, { kind: "component", type: MatBooleanField, selector: "mat-boolean-field", inputs: ["disabled", "formControl", "formControlName", "placeholder", "floatLabel", "appearance", "subscriptSizing", "readonly", "required", "compact", "style", "buttonsColCount", "class", "yesLabel", "noLabel", "showButtonIcons", "yesIcon", "noIcon", "clearable", "labelPosition", "tabindex", "showRadio", "value"], outputs: ["keyup.enter", "focus", "blur"] }, { kind: "component", type: ActionsColumnComponent, selector: "app-actions-column", inputs: ["matColumnDef", "style", "stickyEnd", "canCancel", "canConfirm", "canDelete", "canBackward", "canForward", "canConfirmAndAdd", "dirtyIcon", "optionsTitle", "class", "cellTemplate"], outputs: ["optionsClick", "cancelOrDeleteClick", "confirmEditCreateClick", "confirmAndAddClick", "backward", "forward"] }, { kind: "component", type: AppRowField, selector: "app-row-field", inputs: ["name", "definition", "definitionFn", "headerI18n", "sortable", "resizable", "required", "readonly", "sticky", "draggable", "disabled", "placeholder", "compact", "floatLabel", "appearance", "tabindex", "autofocus", "clearable", "chipColor", "class", "debug"] }, { kind: "pipe", type: i3.AsyncPipe, name: "async" }, { kind: "pipe", type: i1$1.TranslatePipe, name: "translate" }, { kind: "pipe", type: PropertyGetPipe, name: "propertyGet" }, { kind: "pipe", type: NumberFormatPipe, name: "numberFormat" }, { kind: "pipe", type: FormGetValuePipe, name: "formGetValue" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
34978
35026
|
}
|
|
34979
35027
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AppPropertiesTable, decorators: [{
|
|
34980
35028
|
type: Component,
|
|
34981
|
-
args: [{ selector: 'app-properties-table', providers: [{ provide: PropertyEntityValidator, useClass: PropertyEntityValidator }], changeDetection: ChangeDetectionStrategy.OnPush, template: "<mat-toolbar *ngIf=\"showToolbar\" [class.expanded]=\"filterExpansionPanel.expanded\">\n <!-- Refresh -->\n <button mat-icon-button *ngIf=\"!mobile\" [title]=\"'COMMON.BTN_REFRESH' | translate\" (click)=\"emitRefresh()\">\n <mat-icon>refresh</mat-icon>\n </button>\n\n <ion-item *ngIf=\"!mobile && error; let error\" lines=\"none\">\n <ion-icon color=\"danger\" slot=\"start\" name=\"alert-circle\"></ion-icon>\n <ion-label color=\"danger\" [innerHTML]=\"error | translate\"></ion-label>\n </ion-item>\n\n <div class=\"toolbar-spacer\"></div>\n\n <!-- Reset filter -->\n <button mat-icon-button (click)=\"resetFilter()\" *ngIf=\"filterCriteriaCount\">\n <mat-icon color=\"accent\">filter_list_alt</mat-icon>\n <mat-icon class=\"icon-secondary\" style=\"left: 16px; top: 5px; font-weight: bold\">close</mat-icon>\n </button>\n\n <!-- Show filter -->\n <button mat-icon-button (click)=\"filterExpansionPanel.toggle()\">\n <mat-icon\n [matBadge]=\"filterCriteriaCount\"\n [matBadgeHidden]=\"filterIsEmpty\"\n matBadgeColor=\"accent\"\n matBadgeSize=\"small\"\n matBadgePosition=\"above after\"\n aria-hidden=\"false\"\n >\n filter_list_alt\n </mat-icon>\n </button>\n</mat-toolbar>\n\n<ion-content class=\"ion-no-padding\">\n <!-- search -->\n <mat-expansion-panel\n #filterExpansionPanel\n class=\"filter-panel\"\n [class.ion-no-padding]=\"mobile\"\n [class.filter-panel-floating]=\"filterPanelFloating\"\n >\n <form class=\"form-container\" [formGroup]=\"filterForm\" (ngSubmit)=\"emitRefresh()\">\n <ion-grid>\n <ion-row>\n <ion-col>\n <!-- search -->\n <mat-form-field>\n <mat-label>{{ 'SETTINGS.FILTER.SEARCH' | translate }}</mat-label>\n <input matInput formControlName=\"searchText\" />\n\n <button\n mat-icon-button\n matSuffix\n tabindex=\"-1\"\n type=\"button\"\n (click)=\"clearControlValue($event, filterForm.controls.searchText)\"\n [hidden]=\"filterForm.controls.searchText.disabled || !filterForm.controls.searchText.value\"\n >\n <mat-icon>close</mat-icon>\n </button>\n </mat-form-field>\n </ion-col>\n\n <ion-col>\n <mat-boolean-field\n [style]=\"'checkbox'\"\n formControlName=\"notDefaultOnly\"\n [placeholder]=\"'SETTINGS.FILTER.ONLY_NOT_DEFAULT' | translate\"\n floatLabel=\"always\"\n ></mat-boolean-field>\n </ion-col>\n </ion-row>\n </ion-grid>\n </form>\n\n <mat-action-row>\n <!-- Counter -->\n <ion-label\n [hidden]=\"(loadingSubject | async) || filterForm.dirty\"\n [color]=\"empty && 'danger'\"\n class=\"ion-padding\"\n >\n {{\n (totalRowCount ? 'COMMON.RESULT_COUNT' : 'COMMON.NO_RESULT')\n | translate\n : {\n count: (totalRowCount | numberFormat)
|
|
35029
|
+
args: [{ selector: 'app-properties-table', providers: [{ provide: PropertyEntityValidator, useClass: PropertyEntityValidator }], changeDetection: ChangeDetectionStrategy.OnPush, template: "<mat-toolbar *ngIf=\"showToolbar\" [class.expanded]=\"filterExpansionPanel.expanded\">\n <!-- Refresh -->\n <button mat-icon-button *ngIf=\"!mobile\" [title]=\"'COMMON.BTN_REFRESH' | translate\" (click)=\"emitRefresh()\">\n <mat-icon>refresh</mat-icon>\n </button>\n\n <ion-item *ngIf=\"!mobile && error; let error\" lines=\"none\">\n <ion-icon color=\"danger\" slot=\"start\" name=\"alert-circle\"></ion-icon>\n <ion-label color=\"danger\" [innerHTML]=\"error | translate\"></ion-label>\n </ion-item>\n\n <div class=\"toolbar-spacer\"></div>\n\n <!-- Reset filter -->\n <button mat-icon-button (click)=\"resetFilter()\" *ngIf=\"filterCriteriaCount\">\n <mat-icon color=\"accent\">filter_list_alt</mat-icon>\n <mat-icon class=\"icon-secondary\" style=\"left: 16px; top: 5px; font-weight: bold\">close</mat-icon>\n </button>\n\n <!-- Show filter -->\n <button mat-icon-button (click)=\"filterExpansionPanel.toggle()\">\n <mat-icon\n [matBadge]=\"filterCriteriaCount\"\n [matBadgeHidden]=\"filterIsEmpty\"\n matBadgeColor=\"accent\"\n matBadgeSize=\"small\"\n matBadgePosition=\"above after\"\n aria-hidden=\"false\"\n >\n filter_list_alt\n </mat-icon>\n </button>\n</mat-toolbar>\n\n<ion-content class=\"ion-no-padding\">\n <!-- search -->\n <mat-expansion-panel\n #filterExpansionPanel\n class=\"filter-panel\"\n [class.ion-no-padding]=\"mobile\"\n [class.filter-panel-floating]=\"filterPanelFloating\"\n >\n <form class=\"form-container\" [formGroup]=\"filterForm\" (ngSubmit)=\"emitRefresh()\">\n <ion-grid>\n <ion-row>\n <ion-col>\n <!-- search -->\n <mat-form-field>\n <mat-label>{{ 'SETTINGS.FILTER.SEARCH' | translate }}</mat-label>\n <input matInput formControlName=\"searchText\" />\n\n <button\n mat-icon-button\n matSuffix\n tabindex=\"-1\"\n type=\"button\"\n (click)=\"clearControlValue($event, filterForm.controls.searchText)\"\n [hidden]=\"filterForm.controls.searchText.disabled || !filterForm.controls.searchText.value\"\n >\n <mat-icon>close</mat-icon>\n </button>\n </mat-form-field>\n </ion-col>\n\n <ion-col>\n <mat-boolean-field\n [style]=\"'checkbox'\"\n formControlName=\"notDefaultOnly\"\n [placeholder]=\"'SETTINGS.FILTER.ONLY_NOT_DEFAULT' | translate\"\n floatLabel=\"always\"\n ></mat-boolean-field>\n </ion-col>\n </ion-row>\n </ion-grid>\n </form>\n\n <mat-action-row>\n <!-- Counter -->\n <ion-label\n [hidden]=\"(loadingSubject | async) || filterForm.dirty\"\n [color]=\"empty && 'danger'\"\n class=\"ion-padding\"\n >\n {{\n (totalRowCount ? 'COMMON.RESULT_COUNT' : 'COMMON.NO_RESULT')\n | translate\n : {\n count: (totalRowCount | numberFormat),\n }\n }}\n </ion-label>\n\n <div class=\"toolbar-spacer\"></div>\n\n <button\n mat-icon-button\n color=\"accent\"\n *ngIf=\"filterPanelFloating\"\n (click)=\"toggleFilterPanelFloating()\"\n class=\"hidden-xs hidden-sm hidden-md\"\n [title]=\"(filterPanelFloating ? 'COMMON.BTN_EXPAND' : 'COMMON.BTN_HIDE') | translate\"\n >\n <mat-icon>\n <span style=\"transform: rotate(90deg)\">{{ filterPanelFloating ? '»' : '«' }}</span>\n </mat-icon>\n </button>\n\n <!-- Close panel -->\n <ion-button mat-button fill=\"clear\" color=\"dark\" (click)=\"closeFilterPanel()\" [disabled]=\"loadingSubject | async\">\n <ion-text translate>COMMON.BTN_CLOSE</ion-text>\n </ion-button>\n\n <!-- Search button -->\n <ion-button\n mat-button\n [color]=\"filterForm.dirty ? 'tertiary' : 'dark'\"\n [fill]=\"filterForm.dirty ? 'solid' : 'clear'\"\n (click)=\"applyFilterAndClosePanel($event)\"\n [disabled]=\"loadingSubject | async\"\n >\n <ion-text translate>COMMON.BTN_APPLY</ion-text>\n </ion-button>\n </mat-action-row>\n </mat-expansion-panel>\n\n <ion-refresher slot=\"fixed\" *ngIf=\"mobile\" (ionRefresh)=\"doRefresh($event)\">\n <ion-refresher-content></ion-refresher-content>\n </ion-refresher>\n\n <!-- table -->\n <div class=\"table-container\">\n <table\n #table\n mat-table\n matSort\n matSortDisableClear\n [dataSource]=\"dataSource\"\n [matSortActive]=\"defaultSortBy\"\n [matSortDirection]=\"defaultSortDirection\"\n [trackBy]=\"trackByFn\"\n [style.--mat-row-height]=\"'52px'\"\n >\n <ng-container matColumnDef=\"select\">\n <th mat-header-cell *matHeaderCellDef [class.cdk-visually-hidden]=\"true\"></th>\n <td mat-cell *matCellDef=\"let row\" [class.cdk-visually-hidden]=\"true\"></td>\n </ng-container>\n\n <!-- id column (hidden) -->\n <ng-container matColumnDef=\"id\">\n <th mat-header-cell *matHeaderCellDef [class.cdk-visually-hidden]=\"!debug\"></th>\n <td mat-cell *matCellDef=\"let row\" [class.cdk-visually-hidden]=\"!debug\">\n {{ row.currentData.id }}\n </td>\n </ng-container>\n\n <!-- definition column -->\n <ng-container matColumnDef=\"definition\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header class=\"ion-padding-start\">\n <ion-label>{{ i18nColumnPrefix + 'DEFINITION' | translate }}</ion-label>\n </th>\n <td mat-cell *matCellDef=\"let row\" class=\"ion-padding-start\">\n {{ row.currentData | propertyGet: 'definition.label' }}\n </td>\n </ng-container>\n\n <!-- value column -->\n <app-row-field\n name=\"value\"\n floatLabel=\"never\"\n [definitionFn]=\"definitionByRow\"\n [headerI18n]=\"i18nColumnPrefix + 'VALUE'\"\n [required]=\"true\"\n ></app-row-field>\n\n <!-- Actions buttons column -->\n <app-actions-column\n [stickyEnd]=\"true\"\n [canCancel]=\"false\"\n [canDelete]=\"false\"\n [dirtyIcon]=\"false\"\n [cellTemplate]=\"cellInjection\"\n >\n <!-- cell injection-->\n <ng-template #cellInjection let-row>\n <button\n type=\"button\"\n mat-icon-button\n *ngIf=\"\n !mobile &&\n !disabled &&\n (row.validator | formGetValue: 'value') !== (row.validator | formGetValue: 'definition').defaultValue\n \"\n [class.visible-hover-row]=\"!mobile\"\n [tabindex]=\"-1\"\n [title]=\"'SETTINGS.BTN_RESET_PROPERTY' | translate\"\n (click)=\"resetProperty($event, row)\"\n >\n <mat-icon>undo</mat-icon>\n </button>\n </ng-template>\n </app-actions-column>\n\n <tr mat-header-row *matHeaderRowDef=\"displayedColumns; sticky: true\"></tr>\n <tr\n mat-row\n *matRowDef=\"let row; columns: displayedColumns\"\n [class.mat-row-selected]=\"row.editing\"\n [class.mat-row-error]=\"row.validator?.invalid\"\n [class.mat-row-dirty]=\"row.validator?.dirty\"\n (click)=\"clickRow($event, row)\"\n (keydown.escape)=\"escapeEditingRow($event)\"\n [cdkTrapFocus]=\"row.validator?.invalid\"\n ></tr>\n </table>\n\n <ng-container *ngIf=\"loadingSubject | async; else noResult\">\n <ion-item>\n <ion-skeleton-text animated></ion-skeleton-text>\n </ion-item>\n </ng-container>\n\n <ng-template #noResult>\n <ion-item *ngIf=\"totalRowCount === 0\">\n <ion-text color=\"danger\" class=\"text-italic\" translate>COMMON.NO_RESULT</ion-text>\n </ion-item>\n </ng-template>\n </div>\n</ion-content>\n" }]
|
|
34982
35030
|
}], ctorParameters: () => [{ type: i0.Injector }, { type: i1$3.UntypedFormBuilder }, { type: PropertyEntityValidator }, { type: Environment, decorators: [{
|
|
34983
35031
|
type: Inject,
|
|
34984
35032
|
args: [ENVIRONMENT]
|
|
@@ -39272,15 +39320,19 @@ class AccountPage extends AppForm {
|
|
|
39272
39320
|
get valid() {
|
|
39273
39321
|
return super.valid && (this.propertiesTable?.valid || true);
|
|
39274
39322
|
}
|
|
39323
|
+
get invalid() {
|
|
39324
|
+
return super.invalid && (this.propertiesTable ? this.propertiesTable.invalid : false);
|
|
39325
|
+
}
|
|
39326
|
+
get dirty() {
|
|
39327
|
+
return super.dirty || this.propertiesTable?.dirty || false;
|
|
39328
|
+
}
|
|
39275
39329
|
showLatLonFormat = true;
|
|
39276
39330
|
canChangePassword = false;
|
|
39277
39331
|
showSecurityDetails = false;
|
|
39278
39332
|
showTechnicalDetails = true;
|
|
39279
39333
|
showApiTokens = false;
|
|
39280
|
-
constructor(injector, formBuilder, accountService, network, navController, validatorService,
|
|
39281
|
-
|
|
39282
|
-
configService, cd, locales) {
|
|
39283
|
-
super(injector, validatorService.getFormGroup(accountService.account));
|
|
39334
|
+
constructor(injector, formBuilder, accountService, network, navController, validatorService, configService, cd, locales) {
|
|
39335
|
+
super(injector, validatorService.getFormGroup(accountService.account, { withSettings: true }));
|
|
39284
39336
|
this.formBuilder = formBuilder;
|
|
39285
39337
|
this.accountService = accountService;
|
|
39286
39338
|
this.network = network;
|
|
@@ -39289,10 +39341,6 @@ class AccountPage extends AppForm {
|
|
|
39289
39341
|
this.configService = configService;
|
|
39290
39342
|
this.cd = cd;
|
|
39291
39343
|
this.locales = locales;
|
|
39292
|
-
// Add settings fo form
|
|
39293
|
-
// this.settingsForm = settingsValidatorService.getFormGroup(accountService.account && accountService.account.settings);
|
|
39294
|
-
// this.settingsContentForm = (this.settingsForm.controls['content'] as UntypedFormGroup);
|
|
39295
|
-
// this.form.addControl('settings', this.settingsForm);
|
|
39296
39344
|
this.mobile = this.settings.mobile;
|
|
39297
39345
|
this.debug = !environment.production;
|
|
39298
39346
|
// By default, disable the form
|
|
@@ -39369,16 +39417,28 @@ class AccountPage extends AppForm {
|
|
|
39369
39417
|
async setValue(data, opts) {
|
|
39370
39418
|
super.setValue(data, opts);
|
|
39371
39419
|
// Set options
|
|
39372
|
-
if (isNotEmptyArray(this.optionDefinitions) && this.propertiesTable) {
|
|
39373
|
-
|
|
39374
|
-
|
|
39375
|
-
|
|
39376
|
-
|
|
39377
|
-
|
|
39378
|
-
|
|
39379
|
-
|
|
39380
|
-
|
|
39381
|
-
|
|
39420
|
+
// if (isNotEmptyArray(this.optionDefinitions) && this.propertiesTable) {
|
|
39421
|
+
// const properties = data?.settings?.asLocalSettings()?.properties || {};
|
|
39422
|
+
// const propertiesEntities: PropertyEntity[] = [];
|
|
39423
|
+
// this.optionDefinitions
|
|
39424
|
+
// .map((definition) => definition.key)
|
|
39425
|
+
// .forEach((key) => {
|
|
39426
|
+
// if (isNotNil(properties[key])) {
|
|
39427
|
+
// propertiesEntities.push(PropertyEntity.fromObject({ id: key, value: properties[key] }));
|
|
39428
|
+
// }
|
|
39429
|
+
// });
|
|
39430
|
+
// await this.propertiesTable.ready();
|
|
39431
|
+
// this.propertiesTable.value = propertiesEntities;
|
|
39432
|
+
// }
|
|
39433
|
+
// Set options
|
|
39434
|
+
const { properties } = data?.settings?.asLocalSettings({ definitions: this.optionDefinitions }) || {};
|
|
39435
|
+
const propertiesEntities = this.optionDefinitions
|
|
39436
|
+
.map((definition) => {
|
|
39437
|
+
const value = properties?.[definition.key];
|
|
39438
|
+
return isNotNil(value) ? PropertyEntity.fromObject({ definition, value }) : null;
|
|
39439
|
+
})
|
|
39440
|
+
.filter(isNotNil);
|
|
39441
|
+
if (this.propertiesTable) {
|
|
39382
39442
|
await this.propertiesTable.ready();
|
|
39383
39443
|
this.propertiesTable.value = propertiesEntities;
|
|
39384
39444
|
}
|
|
@@ -39441,7 +39501,7 @@ class AccountPage extends AppForm {
|
|
|
39441
39501
|
...this.form.value,
|
|
39442
39502
|
});
|
|
39443
39503
|
if (isNotEmptyArray(this.optionDefinitions) && this.propertiesTable) {
|
|
39444
|
-
//
|
|
39504
|
+
// Merge properties
|
|
39445
39505
|
await this.propertiesTable.save();
|
|
39446
39506
|
const propertyEntities = this.propertiesTable.value || [];
|
|
39447
39507
|
const properties = propertyEntities.reduce((res, item) => {
|