@flusys/ng-shared 9.1.1 → 9.2.0
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.
|
@@ -379,7 +379,7 @@ function getAcceptString(contentTypes) {
|
|
|
379
379
|
return contentTypes.length ? contentTypes.join(",") : "*/*";
|
|
380
380
|
}
|
|
381
381
|
function isFileTypeAllowed(file, allowedTypes) {
|
|
382
|
-
if (!allowedTypes.length) return true;
|
|
382
|
+
if (!allowedTypes.length || allowedTypes.includes("*/*")) return true;
|
|
383
383
|
return allowedTypes.some((type) => type.endsWith("/*") ? file.type.startsWith(type.replace("/*", "/")) : file.type === type);
|
|
384
384
|
}
|
|
385
385
|
function getFileIconClass(contentType) {
|
|
@@ -584,13 +584,16 @@ var TranslateService = class TranslateService {
|
|
|
584
584
|
registry = inject(FALLBACK_MESSAGES_REGISTRY, { optional: false });
|
|
585
585
|
translate(key, params) {
|
|
586
586
|
if (this.localizationState === null) {
|
|
587
|
-
const value = this.registry
|
|
587
|
+
const value = this.lookup(this.registry, key) ?? key;
|
|
588
588
|
return this.interpolate(value, params);
|
|
589
589
|
}
|
|
590
|
-
let value = this.localizationState.translations()
|
|
591
|
-
if (!value) value = this.localizationState.fallbackMessages()
|
|
590
|
+
let value = this.lookup(this.localizationState.translations(), key);
|
|
591
|
+
if (!value) value = this.lookup(this.localizationState.fallbackMessages(), key) ?? key;
|
|
592
592
|
return this.interpolate(value, params);
|
|
593
593
|
}
|
|
594
|
+
lookup(messages, key) {
|
|
595
|
+
return Object.hasOwn(messages, key) ? messages[key] : void 0;
|
|
596
|
+
}
|
|
594
597
|
translateRef(ref) {
|
|
595
598
|
const params = {};
|
|
596
599
|
for (const [name, value] of Object.entries(ref.messageVariables ?? {})) params[name] = this.isMessageRef(value) ? this.translateRef(value) : value;
|
|
@@ -607,7 +610,7 @@ var TranslateService = class TranslateService {
|
|
|
607
610
|
interpolate(template, params) {
|
|
608
611
|
if (!params || !template) return template;
|
|
609
612
|
return template.replace(/\{\{(\w+)\}\}/g, (match, paramKey) => {
|
|
610
|
-
const value = params[paramKey];
|
|
613
|
+
const value = Object.hasOwn(params, paramKey) ? params[paramKey] : void 0;
|
|
611
614
|
return value !== void 0 ? String(value) : match;
|
|
612
615
|
});
|
|
613
616
|
}
|
|
@@ -644,9 +647,12 @@ var FaviconService = class FaviconService {
|
|
|
644
647
|
this.render(this.svgTemplate);
|
|
645
648
|
return;
|
|
646
649
|
}
|
|
647
|
-
this.http.get("/favicon.svg", { responseType: "text" }).subscribe(
|
|
648
|
-
|
|
649
|
-
|
|
650
|
+
this.http.get("/favicon.svg", { responseType: "text" }).subscribe({
|
|
651
|
+
next: (text) => {
|
|
652
|
+
this.svgTemplate = text;
|
|
653
|
+
this.render(text);
|
|
654
|
+
},
|
|
655
|
+
error: () => void 0
|
|
650
656
|
});
|
|
651
657
|
}
|
|
652
658
|
render(svgText) {
|
|
@@ -1086,7 +1092,7 @@ function extractErrorInfo(error, translateAdapter) {
|
|
|
1086
1092
|
messageVariables
|
|
1087
1093
|
});
|
|
1088
1094
|
else if (typeof error.error?.message === "string") detail = error.error.message;
|
|
1089
|
-
else if (Array.isArray(error.error?.message)) detail = error.error.message[0];
|
|
1095
|
+
else if (Array.isArray(error.error?.message) && error.error.message.length) detail = error.error.message[0];
|
|
1090
1096
|
else if (error.message) detail = error.message;
|
|
1091
1097
|
else detail = translateAdapter ? translateAdapter.translate("shared.unexpected.error") : "shared.unexpected.error";
|
|
1092
1098
|
let summary;
|
|
@@ -1304,22 +1310,21 @@ var BaseFormControl = class BaseFormControl {
|
|
|
1304
1310
|
touched = model(false, ...ngDevMode ? [{ debugName: "touched" }] : /* istanbul ignore next */ []);
|
|
1305
1311
|
onChange = () => {};
|
|
1306
1312
|
onTouched = () => {};
|
|
1307
|
-
|
|
1313
|
+
pendingWrite = null;
|
|
1308
1314
|
initializeFormControl() {
|
|
1309
1315
|
runInInjectionContext(this.injector, () => {
|
|
1310
1316
|
effect(() => {
|
|
1311
1317
|
const next = this.value();
|
|
1312
|
-
|
|
1318
|
+
const written = this.pendingWrite;
|
|
1319
|
+
this.pendingWrite = null;
|
|
1320
|
+
if (written && Object.is(written.value, next)) return;
|
|
1321
|
+
untracked(() => this.onChange(next));
|
|
1313
1322
|
});
|
|
1314
1323
|
});
|
|
1315
1324
|
}
|
|
1316
1325
|
writeValue(value) {
|
|
1317
|
-
this.
|
|
1318
|
-
|
|
1319
|
-
this.value.set(value);
|
|
1320
|
-
} finally {
|
|
1321
|
-
this.writeDepth--;
|
|
1322
|
-
}
|
|
1326
|
+
this.pendingWrite = Object.is(untracked(this.value), value) ? null : { value };
|
|
1327
|
+
this.value.set(value);
|
|
1323
1328
|
}
|
|
1324
1329
|
registerOnChange(fn) {
|
|
1325
1330
|
this.onChange = fn;
|
|
@@ -2123,6 +2128,7 @@ var BaseFormComponent = class BaseFormComponent {
|
|
|
2123
2128
|
_submitted = signal(false, ...ngDevMode ? [{ debugName: "_submitted" }] : /* istanbul ignore next */ []);
|
|
2124
2129
|
_isLoadingInternal = signal(false, ...ngDevMode ? [{ debugName: "_isLoadingInternal" }] : /* istanbul ignore next */ []);
|
|
2125
2130
|
_touchedFields = signal(/* @__PURE__ */ new Set(), ...ngDevMode ? [{ debugName: "_touchedFields" }] : /* istanbul ignore next */ []);
|
|
2131
|
+
loadSeq = 0;
|
|
2126
2132
|
formData = this._formData.asReadonly();
|
|
2127
2133
|
submitted = this._submitted.asReadonly();
|
|
2128
2134
|
effectiveIsEditMode = computed(() => this.isEditMode() || !!this.editId(), ...ngDevMode ? [{ debugName: "effectiveIsEditMode" }] : /* istanbul ignore next */ []);
|
|
@@ -2160,9 +2166,11 @@ var BaseFormComponent = class BaseFormComponent {
|
|
|
2160
2166
|
});
|
|
2161
2167
|
}
|
|
2162
2168
|
async loadEntity(id, service, mapFn) {
|
|
2169
|
+
const seq = ++this.loadSeq;
|
|
2163
2170
|
this._isLoadingInternal.set(true);
|
|
2164
2171
|
try {
|
|
2165
2172
|
const response = await service.findById(id);
|
|
2173
|
+
if (seq !== this.loadSeq) return;
|
|
2166
2174
|
if (response.success && response.data) {
|
|
2167
2175
|
this._formData.update((prev) => ({
|
|
2168
2176
|
...prev,
|
|
@@ -2171,9 +2179,9 @@ var BaseFormComponent = class BaseFormComponent {
|
|
|
2171
2179
|
this._submitted.set(false);
|
|
2172
2180
|
}
|
|
2173
2181
|
} catch {
|
|
2174
|
-
this.navigateTo(this.cancelRoute());
|
|
2182
|
+
if (seq === this.loadSeq) this.navigateTo(this.cancelRoute());
|
|
2175
2183
|
} finally {
|
|
2176
|
-
this._isLoadingInternal.set(false);
|
|
2184
|
+
if (seq === this.loadSeq) this._isLoadingInternal.set(false);
|
|
2177
2185
|
}
|
|
2178
2186
|
}
|
|
2179
2187
|
getFieldValue(key) {
|
|
@@ -2200,6 +2208,7 @@ var BaseFormComponent = class BaseFormComponent {
|
|
|
2200
2208
|
return this.fieldTemplates().find((t) => t.key() === key)?.templateRef ?? null;
|
|
2201
2209
|
}
|
|
2202
2210
|
async handleSubmit() {
|
|
2211
|
+
if (this._isLoadingInternal()) return;
|
|
2203
2212
|
this._submitted.set(true);
|
|
2204
2213
|
if (!this.isFormValid()) return;
|
|
2205
2214
|
const service = this.service();
|
|
@@ -3025,6 +3034,16 @@ i0.ɵɵngDeclareClassMetadata({
|
|
|
3025
3034
|
}]
|
|
3026
3035
|
}] }
|
|
3027
3036
|
});
|
|
3037
|
+
const HTML_ESCAPES = {
|
|
3038
|
+
"&": "&",
|
|
3039
|
+
"<": "<",
|
|
3040
|
+
">": ">",
|
|
3041
|
+
"\"": """,
|
|
3042
|
+
"'": "'"
|
|
3043
|
+
};
|
|
3044
|
+
function escapeHtml(value) {
|
|
3045
|
+
return value.replace(/[&<>"']/g, (ch) => HTML_ESCAPES[ch]);
|
|
3046
|
+
}
|
|
3028
3047
|
var BaseListComponent = class BaseListComponent {
|
|
3029
3048
|
translateAdapter = inject(TranslateService, { optional: true });
|
|
3030
3049
|
router = inject(Router, { optional: true });
|
|
@@ -3136,7 +3155,7 @@ var BaseListComponent = class BaseListComponent {
|
|
|
3136
3155
|
const name = this.getFieldValueAsString(item, nameField);
|
|
3137
3156
|
const id = this.getFieldValueAsString(item, this.idField());
|
|
3138
3157
|
this.confirmationService?.confirm({
|
|
3139
|
-
message: this.t("shared.confirm.delete.item", { name }),
|
|
3158
|
+
message: this.t("shared.confirm.delete.item", { name: escapeHtml(name) }),
|
|
3140
3159
|
header: this.t("shared.confirm.delete"),
|
|
3141
3160
|
icon: "exclamation-triangle",
|
|
3142
3161
|
acceptButtonStyleClass: "p-button-danger",
|
|
@@ -4500,7 +4519,7 @@ var FileSelectorDialogComponent = class FileSelectorDialogComponent {
|
|
|
4500
4519
|
destroyRef = inject(DestroyRef);
|
|
4501
4520
|
translateAdapter = inject(TranslateService, { optional: true });
|
|
4502
4521
|
fileProvider = inject(FILE_PROVIDER, { optional: true });
|
|
4503
|
-
|
|
4522
|
+
requestSeq = 0;
|
|
4504
4523
|
searchDebounceTimer = null;
|
|
4505
4524
|
header = input(...ngDevMode ? [void 0, { debugName: "header" }] : /* istanbul ignore next */ []);
|
|
4506
4525
|
acceptTypes = input([], ...ngDevMode ? [{ debugName: "acceptTypes" }] : /* istanbul ignore next */ []);
|
|
@@ -4558,8 +4577,8 @@ var FileSelectorDialogComponent = class FileSelectorDialogComponent {
|
|
|
4558
4577
|
uploadMultipleFilesFn = this.fileProvider?.uploadMultipleFiles ? (files, options) => this.fileProvider.uploadMultipleFiles(files, options) : void 0;
|
|
4559
4578
|
constructor() {
|
|
4560
4579
|
this.destroyRef.onDestroy(() => {
|
|
4561
|
-
this.
|
|
4562
|
-
|
|
4580
|
+
this.requestSeq++;
|
|
4581
|
+
this.clearSearchTimer();
|
|
4563
4582
|
});
|
|
4564
4583
|
effect(() => {
|
|
4565
4584
|
if (this.visible()) untracked(() => {
|
|
@@ -4579,8 +4598,9 @@ var FileSelectorDialogComponent = class FileSelectorDialogComponent {
|
|
|
4579
4598
|
});
|
|
4580
4599
|
}
|
|
4581
4600
|
onSearchChange(value) {
|
|
4582
|
-
|
|
4601
|
+
this.clearSearchTimer();
|
|
4583
4602
|
this.searchDebounceTimer = setTimeout(() => {
|
|
4603
|
+
this.searchDebounceTimer = null;
|
|
4584
4604
|
this.searchTerm.set(value);
|
|
4585
4605
|
this.pagination.update((p) => ({
|
|
4586
4606
|
...p,
|
|
@@ -4614,7 +4634,7 @@ var FileSelectorDialogComponent = class FileSelectorDialogComponent {
|
|
|
4614
4634
|
}
|
|
4615
4635
|
isFileAllowed(file) {
|
|
4616
4636
|
const allowedTypes = this.acceptTypes();
|
|
4617
|
-
if (!allowedTypes.length) return true;
|
|
4637
|
+
if (!allowedTypes.length || allowedTypes.includes("*/*")) return true;
|
|
4618
4638
|
return allowedTypes.some((type) => {
|
|
4619
4639
|
if (type.endsWith("/*")) return file.contentType.startsWith(type.replace("/*", "/"));
|
|
4620
4640
|
return file.contentType === type;
|
|
@@ -4733,9 +4753,13 @@ var FileSelectorDialogComponent = class FileSelectorDialogComponent {
|
|
|
4733
4753
|
} else this.selectedFiles.set([fileInfo]);
|
|
4734
4754
|
this.fetchFiles();
|
|
4735
4755
|
}
|
|
4756
|
+
clearSearchTimer() {
|
|
4757
|
+
if (this.searchDebounceTimer) clearTimeout(this.searchDebounceTimer);
|
|
4758
|
+
this.searchDebounceTimer = null;
|
|
4759
|
+
}
|
|
4736
4760
|
resetState() {
|
|
4737
|
-
this.
|
|
4738
|
-
this.
|
|
4761
|
+
this.requestSeq++;
|
|
4762
|
+
this.clearSearchTimer();
|
|
4739
4763
|
this.isLoading.set(false);
|
|
4740
4764
|
this.files.set([]);
|
|
4741
4765
|
this.selectedFiles.set([]);
|
|
@@ -4763,9 +4787,8 @@ var FileSelectorDialogComponent = class FileSelectorDialogComponent {
|
|
|
4763
4787
|
this.storageConfigsTotal.set(void 0);
|
|
4764
4788
|
}
|
|
4765
4789
|
async fetchFiles(append = false) {
|
|
4766
|
-
if (!this.fileProvider || this.isLoading()) return;
|
|
4767
|
-
this.
|
|
4768
|
-
this.abortController = new AbortController();
|
|
4790
|
+
if (!this.fileProvider || append && this.isLoading()) return;
|
|
4791
|
+
const seq = ++this.requestSeq;
|
|
4769
4792
|
this.isLoading.set(true);
|
|
4770
4793
|
try {
|
|
4771
4794
|
const pag = this.pagination();
|
|
@@ -4778,11 +4801,13 @@ var FileSelectorDialogComponent = class FileSelectorDialogComponent {
|
|
|
4778
4801
|
storageConfigId: this.selectedStorageConfigId() || void 0
|
|
4779
4802
|
};
|
|
4780
4803
|
const response = await firstValueFrom(this.fileProvider.loadFiles(filter));
|
|
4804
|
+
if (seq !== this.requestSeq) return;
|
|
4781
4805
|
if (response.success && response.data) {
|
|
4782
4806
|
let files = response.data;
|
|
4783
4807
|
if (this.fileProvider.getFileUrls && files.length > 0) {
|
|
4784
4808
|
const fileIds = files.map((f) => f.id);
|
|
4785
4809
|
const urlResponse = await firstValueFrom(this.fileProvider.getFileUrls(fileIds));
|
|
4810
|
+
if (seq !== this.requestSeq) return;
|
|
4786
4811
|
if (urlResponse.success && urlResponse.data) {
|
|
4787
4812
|
const urlMap = new Map(urlResponse.data.map((f) => [f.id, f.url]));
|
|
4788
4813
|
files = files.map((f) => ({
|
|
@@ -4796,9 +4821,9 @@ var FileSelectorDialogComponent = class FileSelectorDialogComponent {
|
|
|
4796
4821
|
this.total.set(response.meta?.total);
|
|
4797
4822
|
}
|
|
4798
4823
|
} catch (error) {
|
|
4799
|
-
if (
|
|
4824
|
+
if (seq === this.requestSeq) this.onError.emit(error);
|
|
4800
4825
|
} finally {
|
|
4801
|
-
this.isLoading.set(false);
|
|
4826
|
+
if (seq === this.requestSeq) this.isLoading.set(false);
|
|
4802
4827
|
}
|
|
4803
4828
|
}
|
|
4804
4829
|
t(key, variables) {
|
|
@@ -5824,9 +5849,9 @@ function sanitizeSvgMarkup(svgText) {
|
|
|
5824
5849
|
const element = node;
|
|
5825
5850
|
Array.from(element.attributes).forEach((attr) => {
|
|
5826
5851
|
const name = attr.name.toLowerCase();
|
|
5827
|
-
const value = attr.value.
|
|
5852
|
+
const value = attr.value.replace(/[\u0000-\u0020]/g, "").toLowerCase();
|
|
5828
5853
|
const isEventHandler = name.startsWith("on");
|
|
5829
|
-
const isScriptUri =
|
|
5854
|
+
const isScriptUri = value.includes("javascript:");
|
|
5830
5855
|
if (isEventHandler || isScriptUri) element.removeAttribute(attr.name);
|
|
5831
5856
|
});
|
|
5832
5857
|
node = walker.nextNode();
|
|
@@ -6023,6 +6048,7 @@ var LazyMultiSelectComponent = class LazyMultiSelectComponent extends BaseFormCo
|
|
|
6023
6048
|
event.stopPropagation();
|
|
6024
6049
|
}
|
|
6025
6050
|
handleDocumentClick(event) {
|
|
6051
|
+
if (!this.openOptions()) return;
|
|
6026
6052
|
const target = event.target;
|
|
6027
6053
|
const clickedInSelect = this.pSelectRef()?.nativeElement.contains(target);
|
|
6028
6054
|
const clickedInOverlay = this.overlayViewRef?.rootNodes[0]?.contains(target);
|
|
@@ -7285,7 +7311,7 @@ var BaseUserSelectComponent = class BaseUserSelectComponent {
|
|
|
7285
7311
|
injector = inject(Injector);
|
|
7286
7312
|
userProvider = inject(USER_PROVIDER);
|
|
7287
7313
|
translateAdapter = inject(TranslateService);
|
|
7288
|
-
|
|
7314
|
+
requestSeq = 0;
|
|
7289
7315
|
loadUsers = input(...ngDevMode ? [void 0, { debugName: "loadUsers" }] : /* istanbul ignore next */ []);
|
|
7290
7316
|
placeHolder = input("", ...ngDevMode ? [{ debugName: "placeHolder" }] : /* istanbul ignore next */ []);
|
|
7291
7317
|
isEditMode = input.required(...ngDevMode ? [{ debugName: "isEditMode" }] : /* istanbul ignore next */ []);
|
|
@@ -7344,7 +7370,7 @@ var BaseUserSelectComponent = class BaseUserSelectComponent {
|
|
|
7344
7370
|
}, ...ngDevMode ? [{ debugName: "displayPlaceholder" }] : /* istanbul ignore next */ []);
|
|
7345
7371
|
constructor() {
|
|
7346
7372
|
this.destroyRef.onDestroy(() => {
|
|
7347
|
-
this.
|
|
7373
|
+
this.requestSeq++;
|
|
7348
7374
|
});
|
|
7349
7375
|
effect(() => {
|
|
7350
7376
|
const size = this.pageSize();
|
|
@@ -7382,9 +7408,8 @@ var BaseUserSelectComponent = class BaseUserSelectComponent {
|
|
|
7382
7408
|
this.fetchUsers();
|
|
7383
7409
|
}
|
|
7384
7410
|
async fetchUsers(append = false) {
|
|
7385
|
-
if (this.isLoading()) return;
|
|
7386
|
-
this.
|
|
7387
|
-
this.abortController = new AbortController();
|
|
7411
|
+
if (append && this.isLoading()) return;
|
|
7412
|
+
const seq = ++this.requestSeq;
|
|
7388
7413
|
this.isLoading.set(true);
|
|
7389
7414
|
try {
|
|
7390
7415
|
const pag = this.pagination();
|
|
@@ -7396,6 +7421,7 @@ var BaseUserSelectComponent = class BaseUserSelectComponent {
|
|
|
7396
7421
|
};
|
|
7397
7422
|
const customLoadUsers = this.loadUsers();
|
|
7398
7423
|
const response = await firstValueFrom(customLoadUsers ? customLoadUsers(filter) : this.loadUsersFromProvider(filter));
|
|
7424
|
+
if (seq !== this.requestSeq) return;
|
|
7399
7425
|
if (response.success && response.data) {
|
|
7400
7426
|
if (append) this.users.update((current) => [...current, ...response.data]);
|
|
7401
7427
|
else this.users.set(response.data);
|
|
@@ -7403,9 +7429,9 @@ var BaseUserSelectComponent = class BaseUserSelectComponent {
|
|
|
7403
7429
|
this.rememberUsers(response.data);
|
|
7404
7430
|
}
|
|
7405
7431
|
} catch (error) {
|
|
7406
|
-
if (
|
|
7432
|
+
if (seq === this.requestSeq) this.onError.emit(error);
|
|
7407
7433
|
} finally {
|
|
7408
|
-
this.isLoading.set(false);
|
|
7434
|
+
if (seq === this.requestSeq) this.isLoading.set(false);
|
|
7409
7435
|
}
|
|
7410
7436
|
}
|
|
7411
7437
|
loadUsersFromProvider(filter) {
|
|
@@ -7955,16 +7981,6 @@ function errorToMessageRef(error, fallbackKey = "shared.unexpected.error") {
|
|
|
7955
7981
|
} : { messageKey: body.messageKey };
|
|
7956
7982
|
return { messageKey: fallbackKey };
|
|
7957
7983
|
}
|
|
7958
|
-
const HTML_ESCAPES = {
|
|
7959
|
-
"&": "&",
|
|
7960
|
-
"<": "<",
|
|
7961
|
-
">": ">",
|
|
7962
|
-
"\"": """,
|
|
7963
|
-
"'": "'"
|
|
7964
|
-
};
|
|
7965
|
-
function escapeHtml(value) {
|
|
7966
|
-
return value.replace(/[&<>"']/g, (ch) => HTML_ESCAPES[ch]);
|
|
7967
|
-
}
|
|
7968
7984
|
function compareBranches(a, b) {
|
|
7969
7985
|
return (a.serial ?? 0) - (b.serial ?? 0) || (a.name ?? "").localeCompare(b.name ?? "");
|
|
7970
7986
|
}
|