@jm-7c3/common-lib 22.2.0 → 22.3.1
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.
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { input, signal, effect, ChangeDetectionStrategy, Component, Injectable, inject, Inject, ChangeDetectorRef, viewChild, ViewContainerRef, Service, Directive, contentChild, output, InjectionToken, computed, ViewEncapsulation, NgModule } from '@angular/core';
|
|
2
|
+
import { input, signal, effect, ChangeDetectionStrategy, Component, Injectable, inject, Inject, ChangeDetectorRef, viewChild, ViewContainerRef, Service, Directive, contentChild, output, InjectionToken, computed, ViewEncapsulation, NgModule, model } from '@angular/core';
|
|
3
3
|
import * as i1 from 'primeng/button';
|
|
4
4
|
import { ButtonModule } from 'primeng/button';
|
|
5
5
|
import * as i2 from 'primeng/api';
|
|
@@ -26,6 +26,7 @@ import * as i1$6 from 'primeng/toast';
|
|
|
26
26
|
import { ToastModule } from 'primeng/toast';
|
|
27
27
|
import { cloneDeep } from 'lodash-es';
|
|
28
28
|
import { v4 } from 'uuid';
|
|
29
|
+
import { validate, form } from '@angular/forms/signals';
|
|
29
30
|
import * as i2$3 from '@angular/material/icon';
|
|
30
31
|
import { MatIconModule } from '@angular/material/icon';
|
|
31
32
|
|
|
@@ -578,13 +579,13 @@ class PanelComponent {
|
|
|
578
579
|
title = input('', /* @ts-ignore */
|
|
579
580
|
...(ngDevMode ? [{ debugName: "title" }] : /* istanbul ignore next */ []));
|
|
580
581
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: PanelComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
581
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.6", type: PanelComponent, isStandalone: true, selector: "cl-panel", inputs: { title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null } }, queries: [{ propertyName: "contentTemplate", first: true, predicate: ["contentTemplate"], descendants: true, isSignal: true }, { propertyName: "footerTemplate", first: true, predicate: ["footerTemplate"], descendants: true, isSignal: true }, { propertyName: "headerTemplate", first: true, predicate: ["headerTemplate"], descendants: true, isSignal: true }], ngImport: i0, template: "<div class=\"border-1 border-gray-300 p-5 rounded-lg\">\n @if (headerTemplate() || title()) {\n <div>\n @if (title()) {\n <div class=\"font-medium mb-5 text-xl\">\n {{ title() }}\n </div>\n } @else {\n <ng-container [ngTemplateOutlet]=\"headerTemplate()\" />\n }\n </div>\n }\n <div>\n <ng-container [ngTemplateOutlet]=\"contentTemplate()\" />\n </div>\n @if (footerTemplate()) {\n <div>\n <ng-container [ngTemplateOutlet]=\"footerTemplate()\" />\n </div>\n }\n</div>\n\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$2.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }] });
|
|
582
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.6", type: PanelComponent, isStandalone: true, selector: "cl-panel", inputs: { title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null } }, queries: [{ propertyName: "contentTemplate", first: true, predicate: ["contentTemplate"], descendants: true, isSignal: true }, { propertyName: "footerTemplate", first: true, predicate: ["footerTemplate"], descendants: true, isSignal: true }, { propertyName: "headerTemplate", first: true, predicate: ["headerTemplate"], descendants: true, isSignal: true }], ngImport: i0, template: "<div class=\"border-1 border-gray-300 p-5 rounded-lg\">\n <!-- TODO - Use flex and gap instead of margins -->\n @if (headerTemplate() || title()) {\n <div>\n @if (title()) {\n <div class=\"font-medium mb-5 text-xl\">\n {{ title() }}\n </div>\n } @else {\n <ng-container [ngTemplateOutlet]=\"headerTemplate()\" />\n }\n </div>\n }\n <div>\n <ng-container [ngTemplateOutlet]=\"contentTemplate()\" />\n </div>\n @if (footerTemplate()) {\n <div class=\"mt-5\">\n <ng-container [ngTemplateOutlet]=\"footerTemplate()\" />\n </div>\n }\n</div>\n\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$2.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }] });
|
|
582
583
|
}
|
|
583
584
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: PanelComponent, decorators: [{
|
|
584
585
|
type: Component,
|
|
585
586
|
args: [{ selector: 'cl-panel', imports: [
|
|
586
587
|
CommonModule,
|
|
587
|
-
], template: "<div class=\"border-1 border-gray-300 p-5 rounded-lg\">\n @if (headerTemplate() || title()) {\n <div>\n @if (title()) {\n <div class=\"font-medium mb-5 text-xl\">\n {{ title() }}\n </div>\n } @else {\n <ng-container [ngTemplateOutlet]=\"headerTemplate()\" />\n }\n </div>\n }\n <div>\n <ng-container [ngTemplateOutlet]=\"contentTemplate()\" />\n </div>\n @if (footerTemplate()) {\n <div>\n <ng-container [ngTemplateOutlet]=\"footerTemplate()\" />\n </div>\n }\n</div>\n\n" }]
|
|
588
|
+
], template: "<div class=\"border-1 border-gray-300 p-5 rounded-lg\">\n <!-- TODO - Use flex and gap instead of margins -->\n @if (headerTemplate() || title()) {\n <div>\n @if (title()) {\n <div class=\"font-medium mb-5 text-xl\">\n {{ title() }}\n </div>\n } @else {\n <ng-container [ngTemplateOutlet]=\"headerTemplate()\" />\n }\n </div>\n }\n <div>\n <ng-container [ngTemplateOutlet]=\"contentTemplate()\" />\n </div>\n @if (footerTemplate()) {\n <div class=\"mt-5\">\n <ng-container [ngTemplateOutlet]=\"footerTemplate()\" />\n </div>\n }\n</div>\n\n" }]
|
|
588
589
|
}], propDecorators: { contentTemplate: [{ type: i0.ContentChild, args: ['contentTemplate', { isSignal: true }] }], footerTemplate: [{ type: i0.ContentChild, args: ['footerTemplate', { isSignal: true }] }], headerTemplate: [{ type: i0.ContentChild, args: ['headerTemplate', { isSignal: true }] }], title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: false }] }] } });
|
|
589
590
|
|
|
590
591
|
class ProgressBarDialogComponent {
|
|
@@ -1125,62 +1126,61 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImpor
|
|
|
1125
1126
|
}]
|
|
1126
1127
|
}] });
|
|
1127
1128
|
|
|
1129
|
+
function matFileInputRequired(message = 'This field is required') {
|
|
1130
|
+
return (path) => {
|
|
1131
|
+
return validate(path, ({ value }) => {
|
|
1132
|
+
const firstValue = (value() || []).at(-1);
|
|
1133
|
+
if (!value() || (!firstValue?.isNew && firstValue?.toDelete)) {
|
|
1134
|
+
return {
|
|
1135
|
+
kind: 'mat-file-input-required',
|
|
1136
|
+
message,
|
|
1137
|
+
};
|
|
1138
|
+
}
|
|
1139
|
+
return null;
|
|
1140
|
+
});
|
|
1141
|
+
};
|
|
1142
|
+
}
|
|
1128
1143
|
class MatFileInputComponent {
|
|
1144
|
+
// #region Inputs, outputs and viewChild
|
|
1129
1145
|
directory = input('', /* @ts-ignore */
|
|
1130
1146
|
...(ngDevMode ? [{ debugName: "directory" }] : /* istanbul ignore next */ []));
|
|
1147
|
+
disabled = input(false, /* @ts-ignore */
|
|
1148
|
+
...(ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []));
|
|
1131
1149
|
icon = input('add', /* @ts-ignore */
|
|
1132
1150
|
...(ngDevMode ? [{ debugName: "icon" }] : /* istanbul ignore next */ []));
|
|
1133
1151
|
label = input('Browse', /* @ts-ignore */
|
|
1134
1152
|
...(ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []));
|
|
1135
1153
|
readonly = input(false, /* @ts-ignore */
|
|
1136
1154
|
...(ngDevMode ? [{ debugName: "readonly" }] : /* istanbul ignore next */ []));
|
|
1137
|
-
onDownloadEmitter = output({
|
|
1155
|
+
onDownloadEmitter = output({
|
|
1156
|
+
alias: 'onDownload',
|
|
1157
|
+
});
|
|
1138
1158
|
fileInput = viewChild('fileInput', /* @ts-ignore */
|
|
1139
1159
|
...(ngDevMode ? [{ debugName: "fileInput" }] : /* istanbul ignore next */ []));
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
...(ngDevMode ? [{ debugName: "isDisabled" }] : /* istanbul ignore next */ []));
|
|
1144
|
-
isFileSelected = signal(false, /* @ts-ignore */
|
|
1145
|
-
...(ngDevMode ? [{ debugName: "isFileSelected" }] : /* istanbul ignore next */ []));
|
|
1146
|
-
value = signal(null, /* @ts-ignore */
|
|
1160
|
+
// #endregion
|
|
1161
|
+
// #region Properties
|
|
1162
|
+
value = model(null, /* @ts-ignore */
|
|
1147
1163
|
...(ngDevMode ? [{ debugName: "value" }] : /* istanbul ignore next */ []));
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
}
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
}
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
if (Array.isArray(value)) {
|
|
1163
|
-
newValue = cloneDeep(value);
|
|
1164
|
-
this.selectFile(newValue[0]);
|
|
1165
|
-
}
|
|
1166
|
-
else if (typeof value === 'string') {
|
|
1167
|
-
const hash = this.getHashFromFileName(value);
|
|
1168
|
-
const file = {
|
|
1169
|
-
isNew: !value,
|
|
1170
|
-
hash,
|
|
1171
|
-
name: value,
|
|
1172
|
-
path: this.directory(),
|
|
1173
|
-
toDelete: false,
|
|
1174
|
-
};
|
|
1175
|
-
newValue.push(file);
|
|
1176
|
-
this.selectFile(file);
|
|
1177
|
-
}
|
|
1178
|
-
this.setValue(newValue);
|
|
1164
|
+
form = form(this.value, (path) => {
|
|
1165
|
+
matFileInputRequired()(path);
|
|
1166
|
+
});
|
|
1167
|
+
// #endregion
|
|
1168
|
+
// #region Computed properties
|
|
1169
|
+
isFileSelected = computed(() => this.value()?.filter((file) => !file?.toDelete).length, /* @ts-ignore */
|
|
1170
|
+
...(ngDevMode ? [{ debugName: "isFileSelected" }] : /* istanbul ignore next */ []));
|
|
1171
|
+
fileName = computed(() => {
|
|
1172
|
+
const file = this.getLastFile(this.value());
|
|
1173
|
+
return this.getSafeFileName(file);
|
|
1174
|
+
}, /* @ts-ignore */
|
|
1175
|
+
...(ngDevMode ? [{ debugName: "fileName" }] : /* istanbul ignore next */ []));
|
|
1176
|
+
ngOnInit() {
|
|
1177
|
+
this.writeValue(this.value());
|
|
1179
1178
|
}
|
|
1180
|
-
//
|
|
1181
|
-
|
|
1179
|
+
// #endregion
|
|
1180
|
+
// #region Protected methods
|
|
1181
|
+
onClick(event) {
|
|
1182
|
+
event.preventDefault();
|
|
1182
1183
|
this.fileInput()?.nativeElement.click();
|
|
1183
|
-
this.onTouched();
|
|
1184
1184
|
}
|
|
1185
1185
|
onFileSelected(event) {
|
|
1186
1186
|
const file = event.target.files[0];
|
|
@@ -1197,8 +1197,7 @@ class MatFileInputComponent {
|
|
|
1197
1197
|
};
|
|
1198
1198
|
const newValue = [...(this.value() ?? [])];
|
|
1199
1199
|
newValue.push(newFile);
|
|
1200
|
-
this.
|
|
1201
|
-
this.setValue(newValue);
|
|
1200
|
+
this.value.set(newValue);
|
|
1202
1201
|
}
|
|
1203
1202
|
}
|
|
1204
1203
|
onDelete() {
|
|
@@ -1211,15 +1210,18 @@ class MatFileInputComponent {
|
|
|
1211
1210
|
else {
|
|
1212
1211
|
file.toDelete = true;
|
|
1213
1212
|
}
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1213
|
+
if (newValue.length === 0) {
|
|
1214
|
+
this.value.set(null);
|
|
1215
|
+
}
|
|
1216
|
+
else {
|
|
1217
|
+
this.value.set(newValue);
|
|
1218
|
+
}
|
|
1217
1219
|
}
|
|
1218
1220
|
}
|
|
1219
1221
|
onDownload() {
|
|
1220
1222
|
this.onDownloadEmitter.emit(this.value());
|
|
1221
1223
|
}
|
|
1222
|
-
//
|
|
1224
|
+
// #region Private methods
|
|
1223
1225
|
getFileNameParts(fileName) {
|
|
1224
1226
|
const lastDotIndex = fileName.lastIndexOf('.');
|
|
1225
1227
|
if (lastDotIndex === -1) {
|
|
@@ -1236,148 +1238,128 @@ class MatFileInputComponent {
|
|
|
1236
1238
|
return parts.length > 2 ? parts[parts.length - 2] : '';
|
|
1237
1239
|
}
|
|
1238
1240
|
getLastFile(value) {
|
|
1239
|
-
|
|
1241
|
+
const response = (value ?? []).at(-1);
|
|
1242
|
+
return response ?? null;
|
|
1240
1243
|
}
|
|
1241
1244
|
getSafeFileName(file) {
|
|
1245
|
+
if (!file) {
|
|
1246
|
+
return '';
|
|
1247
|
+
}
|
|
1242
1248
|
const { name, extension } = this.getFileNameParts(file.name);
|
|
1243
1249
|
const hash = this.getHashFromFileName(file.name);
|
|
1244
1250
|
const fileName = name.replace(`.${hash}`, '');
|
|
1245
1251
|
return `${decodeURIComponent(fileName)}.${extension}`;
|
|
1246
1252
|
}
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1253
|
+
writeValue(value = null) {
|
|
1254
|
+
if (Array.isArray(value)) {
|
|
1255
|
+
this.value.set(cloneDeep(value));
|
|
1256
|
+
}
|
|
1257
|
+
else if (typeof value === 'string') {
|
|
1258
|
+
const hash = this.getHashFromFileName(value);
|
|
1259
|
+
const file = {
|
|
1260
|
+
isNew: !value,
|
|
1261
|
+
hash,
|
|
1262
|
+
name: value,
|
|
1263
|
+
path: this.directory(),
|
|
1264
|
+
toDelete: false,
|
|
1265
|
+
};
|
|
1266
|
+
this.value.set([file]);
|
|
1267
|
+
}
|
|
1258
1268
|
}
|
|
1259
1269
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: MatFileInputComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1260
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.6", type: MatFileInputComponent, isStandalone: true, selector: "cl-mat-file-input", inputs: { directory: { classPropertyName: "directory", publicName: "directory", isSignal: true, isRequired: false, transformFunction: null }, icon: { classPropertyName: "icon", publicName: "icon", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, readonly: { classPropertyName: "readonly", publicName: "readonly", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { onDownloadEmitter: "onDownload" },
|
|
1261
|
-
{
|
|
1262
|
-
multi: true,
|
|
1263
|
-
provide: NG_VALUE_ACCESSOR,
|
|
1264
|
-
useExisting: MatFileInputComponent,
|
|
1265
|
-
},
|
|
1266
|
-
], viewQueries: [{ propertyName: "fileInput", first: true, predicate: ["fileInput"], descendants: true, isSignal: true }], ngImport: i0, template: "<div class=\"file-input-container\">\n <input #fileInput (change)=\"onFileSelected($event)\" [disabled]=\"isDisabled()\" class=\"file-input\" hidden type=\"file\" />\n\n @if (isFileSelected()) {\n <div class=\"file-details\">\n <span class=\"file-name\" (click)=\"onDownload()\">{{ fileName() }}</span>\n @if (!readonly()) {\n <button mat-icon-button (click)=\"onDelete()\" [disabled]=\"isDisabled()\">\n <mat-icon>delete</mat-icon>\n </button>\n }\n </div>\n } @else {\n <button mat-raised-button (click)=\"onClick()\" [disabled]=\"isDisabled() || readonly()\">\n <mat-icon>{{ icon() }}</mat-icon>\n <span>{{ label() }}</span>\n </button>\n }\n</div>", styles: [":host .file-input-container{display:flex;align-items:center}:host .file-details{display:flex;align-items:center;gap:8px}:host .file-name{cursor:pointer;text-decoration:underline;color:#00f}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i1$4.MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i1$4.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i2$3.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }] });
|
|
1270
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.6", type: MatFileInputComponent, isStandalone: true, selector: "cl-mat-file-input", inputs: { directory: { classPropertyName: "directory", publicName: "directory", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, icon: { classPropertyName: "icon", publicName: "icon", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, readonly: { classPropertyName: "readonly", publicName: "readonly", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { onDownloadEmitter: "onDownload", value: "valueChange" }, viewQueries: [{ propertyName: "fileInput", first: true, predicate: ["fileInput"], descendants: true, isSignal: true }], ngImport: i0, template: "<div class=\"file-input-container\">\n <input\n (change)=\"onFileSelected($event)\"\n class=\"file-input\"\n [disabled]=\"disabled()\"\n #fileInput\n hidden\n type=\"file\"\n />\n\n @if (isFileSelected()) {\n <div class=\"file-details\">\n <span class=\"file-name\" (click)=\"onDownload()\">{{ fileName() }}</span>\n @if (!readonly()) {\n <button\n (click)=\"onDelete()\"\n [disabled]=\"disabled()\"\n mat-icon-button\n type=\"button\"\n >\n <mat-icon>delete</mat-icon>\n </button>\n }\n </div>\n } @else {\n <button\n (click)=\"onClick($event)\"\n [disabled]=\"disabled() || readonly()\"\n mat-raised-button\n type=\"button\"\n >\n <mat-icon>{{ icon() }}</mat-icon>\n <span>{{ label() }}</span>\n </button>\n }\n</div>\n", styles: [":host .file-input-container{display:flex;align-items:center}:host .file-details{display:flex;align-items:center;gap:8px}:host .file-name{cursor:pointer;text-decoration:underline;color:#00f}\n"], dependencies: [{ kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i1$4.MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i1$4.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i2$3.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }] });
|
|
1267
1271
|
}
|
|
1268
1272
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: MatFileInputComponent, decorators: [{
|
|
1269
1273
|
type: Component,
|
|
1270
|
-
args: [{ selector: 'cl-mat-file-input', standalone: true, imports: [
|
|
1271
|
-
|
|
1272
|
-
multi: true,
|
|
1273
|
-
provide: NG_VALUE_ACCESSOR,
|
|
1274
|
-
useExisting: MatFileInputComponent,
|
|
1275
|
-
},
|
|
1276
|
-
], template: "<div class=\"file-input-container\">\n <input #fileInput (change)=\"onFileSelected($event)\" [disabled]=\"isDisabled()\" class=\"file-input\" hidden type=\"file\" />\n\n @if (isFileSelected()) {\n <div class=\"file-details\">\n <span class=\"file-name\" (click)=\"onDownload()\">{{ fileName() }}</span>\n @if (!readonly()) {\n <button mat-icon-button (click)=\"onDelete()\" [disabled]=\"isDisabled()\">\n <mat-icon>delete</mat-icon>\n </button>\n }\n </div>\n } @else {\n <button mat-raised-button (click)=\"onClick()\" [disabled]=\"isDisabled() || readonly()\">\n <mat-icon>{{ icon() }}</mat-icon>\n <span>{{ label() }}</span>\n </button>\n }\n</div>", styles: [":host .file-input-container{display:flex;align-items:center}:host .file-details{display:flex;align-items:center;gap:8px}:host .file-name{cursor:pointer;text-decoration:underline;color:#00f}\n"] }]
|
|
1277
|
-
}], propDecorators: { directory: [{ type: i0.Input, args: [{ isSignal: true, alias: "directory", required: false }] }], icon: [{ type: i0.Input, args: [{ isSignal: true, alias: "icon", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], readonly: [{ type: i0.Input, args: [{ isSignal: true, alias: "readonly", required: false }] }], onDownloadEmitter: [{ type: i0.Output, args: ["onDownload"] }], fileInput: [{ type: i0.ViewChild, args: ['fileInput', { isSignal: true }] }] } });
|
|
1274
|
+
args: [{ selector: 'cl-mat-file-input', standalone: true, imports: [MatButtonModule, MatIconModule], template: "<div class=\"file-input-container\">\n <input\n (change)=\"onFileSelected($event)\"\n class=\"file-input\"\n [disabled]=\"disabled()\"\n #fileInput\n hidden\n type=\"file\"\n />\n\n @if (isFileSelected()) {\n <div class=\"file-details\">\n <span class=\"file-name\" (click)=\"onDownload()\">{{ fileName() }}</span>\n @if (!readonly()) {\n <button\n (click)=\"onDelete()\"\n [disabled]=\"disabled()\"\n mat-icon-button\n type=\"button\"\n >\n <mat-icon>delete</mat-icon>\n </button>\n }\n </div>\n } @else {\n <button\n (click)=\"onClick($event)\"\n [disabled]=\"disabled() || readonly()\"\n mat-raised-button\n type=\"button\"\n >\n <mat-icon>{{ icon() }}</mat-icon>\n <span>{{ label() }}</span>\n </button>\n }\n</div>\n", styles: [":host .file-input-container{display:flex;align-items:center}:host .file-details{display:flex;align-items:center;gap:8px}:host .file-name{cursor:pointer;text-decoration:underline;color:#00f}\n"] }]
|
|
1275
|
+
}], propDecorators: { directory: [{ type: i0.Input, args: [{ isSignal: true, alias: "directory", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], icon: [{ type: i0.Input, args: [{ isSignal: true, alias: "icon", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], readonly: [{ type: i0.Input, args: [{ isSignal: true, alias: "readonly", required: false }] }], onDownloadEmitter: [{ type: i0.Output, args: ["onDownload"] }], fileInput: [{ type: i0.ViewChild, args: ['fileInput', { isSignal: true }] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }, { type: i0.Output, args: ["valueChange"] }] } });
|
|
1278
1276
|
|
|
1279
|
-
|
|
1280
|
-
|
|
1277
|
+
function matFileInputsRequired(message = 'This field is required') {
|
|
1278
|
+
return (path) => {
|
|
1279
|
+
return validate(path, ({ value }) => {
|
|
1280
|
+
if (value()?.some((file) => file === null || file.at(-1)?.toDelete)) {
|
|
1281
|
+
return {
|
|
1282
|
+
kind: 'mat-file-inputs-required',
|
|
1283
|
+
message,
|
|
1284
|
+
};
|
|
1285
|
+
}
|
|
1286
|
+
return null;
|
|
1287
|
+
});
|
|
1288
|
+
};
|
|
1289
|
+
}
|
|
1290
|
+
class MatFileInputsComponent {
|
|
1291
|
+
// #region Inputs and outputs
|
|
1281
1292
|
directory = input('', /* @ts-ignore */
|
|
1282
1293
|
...(ngDevMode ? [{ debugName: "directory" }] : /* istanbul ignore next */ []));
|
|
1294
|
+
disabled = input(false, /* @ts-ignore */
|
|
1295
|
+
...(ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []));
|
|
1283
1296
|
icon = input('add', /* @ts-ignore */
|
|
1284
1297
|
...(ngDevMode ? [{ debugName: "icon" }] : /* istanbul ignore next */ []));
|
|
1285
1298
|
label = input('Browse', /* @ts-ignore */
|
|
1286
1299
|
...(ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []));
|
|
1287
|
-
|
|
1288
|
-
...(ngDevMode ? [{ debugName: "
|
|
1300
|
+
maxFiles = input(5, /* @ts-ignore */
|
|
1301
|
+
...(ngDevMode ? [{ debugName: "maxFiles" }] : /* istanbul ignore next */ []));
|
|
1289
1302
|
readonly = input(false, /* @ts-ignore */
|
|
1290
1303
|
...(ngDevMode ? [{ debugName: "readonly" }] : /* istanbul ignore next */ []));
|
|
1291
1304
|
onDownloadEmitter = output({ alias: 'onDownload' });
|
|
1305
|
+
// #endregion
|
|
1306
|
+
// #region Properties
|
|
1307
|
+
value = model(null, /* @ts-ignore */
|
|
1308
|
+
...(ngDevMode ? [{ debugName: "value" }] : /* istanbul ignore next */ []));
|
|
1309
|
+
form = form(this.value);
|
|
1310
|
+
// #endregion
|
|
1311
|
+
// #region NG Hooks
|
|
1312
|
+
ngOnInit() {
|
|
1313
|
+
this.writeValue(this.value());
|
|
1314
|
+
}
|
|
1315
|
+
// #endregion
|
|
1316
|
+
// #region Protected methods
|
|
1292
1317
|
onAdd() {
|
|
1293
|
-
this.
|
|
1294
|
-
this.cdRef.markForCheck();
|
|
1318
|
+
this.value.update((value) => [...(value ?? []), null]);
|
|
1295
1319
|
}
|
|
1296
1320
|
onDelete(index) {
|
|
1297
|
-
this.
|
|
1298
|
-
|
|
1321
|
+
this.value.update((currentValue) => {
|
|
1322
|
+
if (!currentValue) {
|
|
1323
|
+
return null;
|
|
1324
|
+
}
|
|
1325
|
+
// Return a new array with the item removed
|
|
1326
|
+
return currentValue.filter((_, i) => i !== index);
|
|
1327
|
+
});
|
|
1299
1328
|
}
|
|
1300
1329
|
onDownload(file) {
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
setDisabledState(isDisabled) {
|
|
1304
|
-
for (const control of this.formArray.controls) {
|
|
1305
|
-
if (isDisabled) {
|
|
1306
|
-
control.disable();
|
|
1307
|
-
}
|
|
1308
|
-
else {
|
|
1309
|
-
control.enable();
|
|
1310
|
-
}
|
|
1330
|
+
if (!file) {
|
|
1331
|
+
return;
|
|
1311
1332
|
}
|
|
1333
|
+
this.onDownloadEmitter.emit(file);
|
|
1312
1334
|
}
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
const
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
required: true
|
|
1320
|
-
};
|
|
1321
|
-
}
|
|
1322
|
-
}
|
|
1323
|
-
return null;
|
|
1335
|
+
onValueChange(file, index) {
|
|
1336
|
+
this.value.update((value) => {
|
|
1337
|
+
const newValue = [...(value ?? [])];
|
|
1338
|
+
newValue[index] = file;
|
|
1339
|
+
return newValue;
|
|
1340
|
+
});
|
|
1324
1341
|
}
|
|
1342
|
+
// #region Private methods
|
|
1325
1343
|
writeValue(value) {
|
|
1326
1344
|
if (Array.isArray(value)) {
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
this.onAdd();
|
|
1334
|
-
}
|
|
1335
|
-
this.setValue(value);
|
|
1336
|
-
}
|
|
1337
|
-
});
|
|
1345
|
+
if (value.length === 0) {
|
|
1346
|
+
this.onAdd();
|
|
1347
|
+
}
|
|
1348
|
+
else {
|
|
1349
|
+
this.value.set(value);
|
|
1350
|
+
}
|
|
1338
1351
|
}
|
|
1339
1352
|
else if (!this.readonly()) {
|
|
1340
1353
|
this.onAdd();
|
|
1341
1354
|
}
|
|
1342
1355
|
}
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
}
|
|
1346
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: MatFileInputsComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
|
|
1347
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.6", type: MatFileInputsComponent, isStandalone: true, selector: "cl-mat-file-inputs", inputs: { directory: { classPropertyName: "directory", publicName: "directory", isSignal: true, isRequired: false, transformFunction: null }, icon: { classPropertyName: "icon", publicName: "icon", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, max: { classPropertyName: "max", publicName: "max", isSignal: true, isRequired: false, transformFunction: null }, readonly: { classPropertyName: "readonly", publicName: "readonly", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { onDownloadEmitter: "onDownload" }, providers: [
|
|
1348
|
-
{
|
|
1349
|
-
multi: true,
|
|
1350
|
-
provide: NG_VALIDATORS,
|
|
1351
|
-
useExisting: MatFileInputsComponent
|
|
1352
|
-
},
|
|
1353
|
-
{
|
|
1354
|
-
multi: true,
|
|
1355
|
-
provide: NG_VALUE_ACCESSOR,
|
|
1356
|
-
useExisting: MatFileInputsComponent
|
|
1357
|
-
}
|
|
1358
|
-
], usesInheritance: true, ngImport: i0, template: "<ng-container [formGroup]=\"formGroup\">\n @for (item of formArray.value; track index; let index = $index) {\n <div class=\"flex mb-3\">\n <cl-mat-file-input [formControlName]=\"index\" [directory]=\"directory()\" [icon]=\"icon()\" [label]=\"label()\"\n (onDownload)=\"onDownload($event)\" [readonly]=\"readonly()\" />\n @if (!readonly()) {\n @if (index === 0) {\n <button (click)=\"onAdd()\" [disabled]=\"formArray.length >= max()\" mat-icon-button type=\"button\">\n <mat-icon>{{ icon() }}</mat-icon>\n </button>\n } @else if (index > 0) {\n <button (click)=\"onDelete(index)\" mat-icon-button type=\"button\">\n <mat-icon>remove</mat-icon>\n </button>\n }\n }\n </div>\n }\n</ng-container>\n", styles: [""], dependencies: [{ kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i1$4.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: MatFileInputComponent, selector: "cl-mat-file-input", inputs: ["directory", "icon", "label", "readonly"], outputs: ["onDownload"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i2$3.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2$2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i2$2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i2$2.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }] });
|
|
1356
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: MatFileInputsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1357
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.6", type: MatFileInputsComponent, isStandalone: true, selector: "cl-mat-file-inputs", inputs: { directory: { classPropertyName: "directory", publicName: "directory", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, icon: { classPropertyName: "icon", publicName: "icon", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, maxFiles: { classPropertyName: "maxFiles", publicName: "maxFiles", isSignal: true, isRequired: false, transformFunction: null }, readonly: { classPropertyName: "readonly", publicName: "readonly", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { onDownloadEmitter: "onDownload", value: "valueChange" }, ngImport: i0, template: "@for (item of value(); track index; let index = $index) {\n <div class=\"flex mb-3\">\n <cl-mat-file-input\n [directory]=\"directory()\"\n [icon]=\"icon()\"\n [label]=\"label()\"\n (onDownload)=\"onDownload($event)\"\n [readonly]=\"readonly()\"\n [value]=\"item\"\n (valueChange)=\"onValueChange($event, index)\"\n />\n @if (!readonly()) {\n @if (index === 0) {\n @let allowMoreFiles = (value()?.length ?? 0) < maxFiles();\n <button\n (click)=\"onAdd()\"\n [disabled]=\"disabled() || !allowMoreFiles\"\n mat-icon-button\n type=\"button\"\n >\n <mat-icon>{{ icon() }}</mat-icon>\n </button>\n } @else if (index > 0) {\n <button (click)=\"onDelete(index)\" mat-icon-button type=\"button\">\n <mat-icon>remove</mat-icon>\n </button>\n }\n }\n </div>\n}\n", styles: [""], dependencies: [{ kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i1$4.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: MatFileInputComponent, selector: "cl-mat-file-input", inputs: ["directory", "disabled", "icon", "label", "readonly", "value"], outputs: ["onDownload", "valueChange"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i2$3.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }] });
|
|
1359
1358
|
}
|
|
1360
1359
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: MatFileInputsComponent, decorators: [{
|
|
1361
1360
|
type: Component,
|
|
1362
|
-
args: [{ selector: 'cl-mat-file-inputs', imports: [
|
|
1363
|
-
|
|
1364
|
-
MatFileInputComponent,
|
|
1365
|
-
MatIconModule,
|
|
1366
|
-
FormsModule,
|
|
1367
|
-
ReactiveFormsModule,
|
|
1368
|
-
], providers: [
|
|
1369
|
-
{
|
|
1370
|
-
multi: true,
|
|
1371
|
-
provide: NG_VALIDATORS,
|
|
1372
|
-
useExisting: MatFileInputsComponent
|
|
1373
|
-
},
|
|
1374
|
-
{
|
|
1375
|
-
multi: true,
|
|
1376
|
-
provide: NG_VALUE_ACCESSOR,
|
|
1377
|
-
useExisting: MatFileInputsComponent
|
|
1378
|
-
}
|
|
1379
|
-
], template: "<ng-container [formGroup]=\"formGroup\">\n @for (item of formArray.value; track index; let index = $index) {\n <div class=\"flex mb-3\">\n <cl-mat-file-input [formControlName]=\"index\" [directory]=\"directory()\" [icon]=\"icon()\" [label]=\"label()\"\n (onDownload)=\"onDownload($event)\" [readonly]=\"readonly()\" />\n @if (!readonly()) {\n @if (index === 0) {\n <button (click)=\"onAdd()\" [disabled]=\"formArray.length >= max()\" mat-icon-button type=\"button\">\n <mat-icon>{{ icon() }}</mat-icon>\n </button>\n } @else if (index > 0) {\n <button (click)=\"onDelete(index)\" mat-icon-button type=\"button\">\n <mat-icon>remove</mat-icon>\n </button>\n }\n }\n </div>\n }\n</ng-container>\n" }]
|
|
1380
|
-
}], propDecorators: { directory: [{ type: i0.Input, args: [{ isSignal: true, alias: "directory", required: false }] }], icon: [{ type: i0.Input, args: [{ isSignal: true, alias: "icon", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], max: [{ type: i0.Input, args: [{ isSignal: true, alias: "max", required: false }] }], readonly: [{ type: i0.Input, args: [{ isSignal: true, alias: "readonly", required: false }] }], onDownloadEmitter: [{ type: i0.Output, args: ["onDownload"] }] } });
|
|
1361
|
+
args: [{ selector: 'cl-mat-file-inputs', imports: [MatButtonModule, MatFileInputComponent, MatIconModule], template: "@for (item of value(); track index; let index = $index) {\n <div class=\"flex mb-3\">\n <cl-mat-file-input\n [directory]=\"directory()\"\n [icon]=\"icon()\"\n [label]=\"label()\"\n (onDownload)=\"onDownload($event)\"\n [readonly]=\"readonly()\"\n [value]=\"item\"\n (valueChange)=\"onValueChange($event, index)\"\n />\n @if (!readonly()) {\n @if (index === 0) {\n @let allowMoreFiles = (value()?.length ?? 0) < maxFiles();\n <button\n (click)=\"onAdd()\"\n [disabled]=\"disabled() || !allowMoreFiles\"\n mat-icon-button\n type=\"button\"\n >\n <mat-icon>{{ icon() }}</mat-icon>\n </button>\n } @else if (index > 0) {\n <button (click)=\"onDelete(index)\" mat-icon-button type=\"button\">\n <mat-icon>remove</mat-icon>\n </button>\n }\n }\n </div>\n}\n" }]
|
|
1362
|
+
}], propDecorators: { directory: [{ type: i0.Input, args: [{ isSignal: true, alias: "directory", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], icon: [{ type: i0.Input, args: [{ isSignal: true, alias: "icon", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], maxFiles: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxFiles", required: false }] }], readonly: [{ type: i0.Input, args: [{ isSignal: true, alias: "readonly", required: false }] }], onDownloadEmitter: [{ type: i0.Output, args: ["onDownload"] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }, { type: i0.Output, args: ["valueChange"] }] } });
|
|
1381
1363
|
|
|
1382
1364
|
;
|
|
1383
1365
|
|
|
@@ -1416,5 +1398,5 @@ function concatWithToArray(values) {
|
|
|
1416
1398
|
* Generated bundle index. Do not edit.
|
|
1417
1399
|
*/
|
|
1418
1400
|
|
|
1419
|
-
export { BaseFormComponent, ButtonComponent, ClStateService, CommonLibModule, ConfirmationComponent, ConfirmationService, ContentDialogComponent, ContentDialogService, ERROR_DIRECTIVE, ErrorDirective, FORM_FIELD, FileInputComponent, FileInputsComponent, FormDialogComponent, FormDialogService, FormFieldComponent, FormFieldModule, IconButtonComponent, LABEL_DIRECTIVE, LabelDirective, MatConfirmationComponent, MatConfirmationService, MatFileInputComponent, MatFileInputsComponent, MatFormDialogComponent, MatFormDialogService, MatFormHostableComponent, PanelComponent, ProgressBarDialogComponent, ProgressBarDialogService, ReadonlyValueComponent, ToastsComponent, ToastsService, concatWithToArray };
|
|
1401
|
+
export { BaseFormComponent, ButtonComponent, ClStateService, CommonLibModule, ConfirmationComponent, ConfirmationService, ContentDialogComponent, ContentDialogService, ERROR_DIRECTIVE, ErrorDirective, FORM_FIELD, FileInputComponent, FileInputsComponent, FormDialogComponent, FormDialogService, FormFieldComponent, FormFieldModule, IconButtonComponent, LABEL_DIRECTIVE, LabelDirective, MatConfirmationComponent, MatConfirmationService, MatFileInputComponent, MatFileInputsComponent, MatFormDialogComponent, MatFormDialogService, MatFormHostableComponent, PanelComponent, ProgressBarDialogComponent, ProgressBarDialogService, ReadonlyValueComponent, ToastsComponent, ToastsService, concatWithToArray, matFileInputRequired, matFileInputsRequired };
|
|
1420
1402
|
//# sourceMappingURL=jm-7c3-common-lib.mjs.map
|