@masterteam/components 0.0.131 → 0.0.132

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.
Files changed (49) hide show
  1. package/fesm2022/masterteam-components-business-fields.mjs +597 -0
  2. package/fesm2022/masterteam-components-business-fields.mjs.map +1 -0
  3. package/fesm2022/masterteam-components-button-group.mjs +20 -0
  4. package/fesm2022/masterteam-components-button-group.mjs.map +1 -0
  5. package/fesm2022/masterteam-components-chip.mjs +35 -0
  6. package/fesm2022/masterteam-components-chip.mjs.map +1 -0
  7. package/fesm2022/masterteam-components-client-page-menu.mjs +92 -0
  8. package/fesm2022/masterteam-components-client-page-menu.mjs.map +1 -0
  9. package/fesm2022/masterteam-components-client-page.mjs +160 -0
  10. package/fesm2022/masterteam-components-client-page.mjs.map +1 -0
  11. package/fesm2022/masterteam-components-color-picker-field.mjs +94 -0
  12. package/fesm2022/masterteam-components-color-picker-field.mjs.map +1 -0
  13. package/fesm2022/masterteam-components-date-field.mjs +93 -0
  14. package/fesm2022/masterteam-components-date-field.mjs.map +1 -0
  15. package/fesm2022/masterteam-components-drawer.mjs +69 -0
  16. package/fesm2022/masterteam-components-drawer.mjs.map +1 -0
  17. package/fesm2022/masterteam-components-editor-field.mjs +96 -0
  18. package/fesm2022/masterteam-components-editor-field.mjs.map +1 -0
  19. package/fesm2022/masterteam-components-entities.mjs +864 -0
  20. package/fesm2022/masterteam-components-entities.mjs.map +1 -0
  21. package/fesm2022/masterteam-components-formula.mjs +3116 -0
  22. package/fesm2022/masterteam-components-formula.mjs.map +1 -0
  23. package/fesm2022/masterteam-components-list.mjs +31 -0
  24. package/fesm2022/masterteam-components-list.mjs.map +1 -0
  25. package/fesm2022/masterteam-components-progress.mjs +49 -0
  26. package/fesm2022/masterteam-components-progress.mjs.map +1 -0
  27. package/fesm2022/masterteam-components-table.mjs +1153 -0
  28. package/fesm2022/masterteam-components-table.mjs.map +1 -0
  29. package/fesm2022/masterteam-components-upload-field.mjs +554 -0
  30. package/fesm2022/masterteam-components-upload-field.mjs.map +1 -0
  31. package/fesm2022/masterteam-components-user-search-field.mjs +153 -0
  32. package/fesm2022/masterteam-components-user-search-field.mjs.map +1 -0
  33. package/package.json +1 -1
  34. package/types/masterteam-components-business-fields.d.ts +213 -0
  35. package/types/masterteam-components-button-group.d.ts +8 -0
  36. package/types/masterteam-components-chip.d.ts +19 -0
  37. package/types/masterteam-components-client-page-menu.d.ts +35 -0
  38. package/types/masterteam-components-client-page.d.ts +56 -0
  39. package/types/masterteam-components-color-picker-field.d.ts +35 -0
  40. package/types/masterteam-components-date-field.d.ts +41 -0
  41. package/types/masterteam-components-drawer.d.ts +30 -0
  42. package/types/masterteam-components-editor-field.d.ts +34 -0
  43. package/types/masterteam-components-entities.d.ts +367 -0
  44. package/types/masterteam-components-formula.d.ts +656 -0
  45. package/types/masterteam-components-list.d.ts +18 -0
  46. package/types/masterteam-components-progress.d.ts +22 -0
  47. package/types/masterteam-components-table.d.ts +255 -0
  48. package/types/masterteam-components-upload-field.d.ts +77 -0
  49. package/types/masterteam-components-user-search-field.d.ts +61 -0
@@ -0,0 +1,554 @@
1
+ import * as i0 from '@angular/core';
2
+ import { inject, ChangeDetectorRef, Pipe, input, output, model, computed, Component, signal } from '@angular/core';
3
+ import { Button } from '@masterteam/components/button';
4
+ import { map, tap, finalize, shareReplay, distinctUntilChanged, switchMap, filter, catchError } from 'rxjs/operators';
5
+ import { DomSanitizer } from '@angular/platform-browser';
6
+ import { Subscription, BehaviorSubject, of, finalize as finalize$1, catchError as catchError$1, throwError, take, forkJoin, map as map$1 } from 'rxjs';
7
+ import { HttpClient, HttpContext } from '@angular/common/http';
8
+ import { Avatar } from '@masterteam/components/avatar';
9
+ import * as i1 from '@jsverse/transloco';
10
+ import { TranslocoModule } from '@jsverse/transloco';
11
+ import { Tooltip } from '@masterteam/components/tooltip';
12
+ import { Icon } from '@masterteam/icons';
13
+ import { Validators, NgControl } from '@angular/forms';
14
+ import { FieldValidation } from '@masterteam/components/field-validation';
15
+ import { Card } from '@masterteam/components/card';
16
+
17
+ class SecureImagePipe {
18
+ static cachedBlobUrls = new Map();
19
+ static pendingRequests = new Map();
20
+ httpClient = inject(HttpClient);
21
+ domSanitizer = inject(DomSanitizer);
22
+ cdr = inject(ChangeDetectorRef);
23
+ constructor() {
24
+ this.setUpSubscription();
25
+ }
26
+ ngOnDestroy() {
27
+ this.subscription.unsubscribe();
28
+ }
29
+ subscription = new Subscription();
30
+ latestValue = '';
31
+ transformValue = new BehaviorSubject(null);
32
+ loading = false;
33
+ transform(imagePath, wrapUrlOrContext, contextOrEndpoint, endPoint = 'uploader/') {
34
+ const hasExtraArgs = arguments.length > 1;
35
+ const isWrapFlag = typeof wrapUrlOrContext === 'boolean';
36
+ let context;
37
+ let wrapUrl = true;
38
+ let useEndpoint = false;
39
+ let endpoint = '';
40
+ let sanitize = true;
41
+ if (!hasExtraArgs || isWrapFlag) {
42
+ // Backward compatible mode: (imagePath, wrapUrl?, context?, endPoint?)
43
+ wrapUrl = isWrapFlag ? wrapUrlOrContext : false;
44
+ useEndpoint = true;
45
+ endpoint = endPoint;
46
+ if (contextOrEndpoint instanceof HttpContext) {
47
+ context = contextOrEndpoint;
48
+ }
49
+ else if (typeof contextOrEndpoint === 'string') {
50
+ endpoint = contextOrEndpoint;
51
+ }
52
+ sanitize = false;
53
+ }
54
+ else {
55
+ // Components mode: (imagePath, context)
56
+ context = wrapUrlOrContext;
57
+ wrapUrl = true;
58
+ useEndpoint = false;
59
+ endpoint = '';
60
+ sanitize = true;
61
+ }
62
+ const fullPath = useEndpoint
63
+ ? imagePath
64
+ ? endpoint + imagePath
65
+ : ''
66
+ : imagePath;
67
+ if (!fullPath || fullPath.includes('null')) {
68
+ this.latestValue = '';
69
+ this.loading = false;
70
+ this.transformValue.next(null);
71
+ return '';
72
+ }
73
+ this.transformValue.next({
74
+ fullPath,
75
+ cacheKey: SecureImagePipe.createCacheKey(fullPath, context),
76
+ context,
77
+ wrapUrl,
78
+ useEndpoint,
79
+ sanitize,
80
+ });
81
+ if (this.loading || !this.latestValue) {
82
+ return '';
83
+ }
84
+ if (!useEndpoint || wrapUrl) {
85
+ return this.latestValue;
86
+ }
87
+ return `url('${this.latestValue}')`;
88
+ }
89
+ static createCacheKey(fullPath, context) {
90
+ if (!context) {
91
+ return `default:${fullPath}`;
92
+ }
93
+ const contextSnapshot = Array.from(context.keys())
94
+ .map((token) => SecureImagePipe.serializeContextValue(context.get(token)))
95
+ .sort()
96
+ .join('|');
97
+ return `${contextSnapshot}:${fullPath}`;
98
+ }
99
+ static serializeContextValue(value) {
100
+ if (value === null) {
101
+ return 'null';
102
+ }
103
+ if (value === undefined) {
104
+ return 'undefined';
105
+ }
106
+ if (typeof value !== 'object') {
107
+ return String(value);
108
+ }
109
+ if (Array.isArray(value)) {
110
+ return `[${value
111
+ .map((item) => SecureImagePipe.serializeContextValue(item))
112
+ .join(',')}]`;
113
+ }
114
+ const normalizedEntries = Object.entries(value)
115
+ .sort(([leftKey], [rightKey]) => leftKey.localeCompare(rightKey))
116
+ .map(([key, entryValue]) => `${key}:${SecureImagePipe.serializeContextValue(entryValue)}`);
117
+ return `{${normalizedEntries.join(',')}}`;
118
+ }
119
+ getOrLoadBlobUrl(request) {
120
+ const cachedBlobUrl = SecureImagePipe.cachedBlobUrls.get(request.cacheKey);
121
+ if (cachedBlobUrl) {
122
+ return of(cachedBlobUrl);
123
+ }
124
+ const pendingRequest = SecureImagePipe.pendingRequests.get(request.cacheKey);
125
+ if (pendingRequest) {
126
+ return pendingRequest;
127
+ }
128
+ const request$ = this.httpClient
129
+ .get(request.fullPath, {
130
+ observe: 'response',
131
+ responseType: 'blob',
132
+ context: request.context,
133
+ })
134
+ .pipe(map((response) => response.body ? URL.createObjectURL(response.body) : ''), tap((blobUrl) => {
135
+ if (blobUrl) {
136
+ SecureImagePipe.cachedBlobUrls.set(request.cacheKey, blobUrl);
137
+ }
138
+ }), finalize(() => {
139
+ SecureImagePipe.pendingRequests.delete(request.cacheKey);
140
+ }), shareReplay(1));
141
+ SecureImagePipe.pendingRequests.set(request.cacheKey, request$);
142
+ return request$;
143
+ }
144
+ setUpSubscription() {
145
+ const transformSubscription = this.transformValue
146
+ .asObservable()
147
+ .pipe(distinctUntilChanged((previous, current) => {
148
+ if (previous === current) {
149
+ return true;
150
+ }
151
+ if (!previous || !current) {
152
+ return previous === current;
153
+ }
154
+ return (previous.cacheKey === current.cacheKey &&
155
+ previous.wrapUrl === current.wrapUrl &&
156
+ previous.useEndpoint === current.useEndpoint &&
157
+ previous.sanitize === current.sanitize);
158
+ }), switchMap((request) => {
159
+ if (!request) {
160
+ this.loading = false;
161
+ return of('');
162
+ }
163
+ this.latestValue = '';
164
+ this.loading = true;
165
+ return this.getOrLoadBlobUrl(request).pipe(filter((blobUrl) => !!blobUrl), map((unsafeBlobUrl) => request.sanitize
166
+ ? this.domSanitizer.bypassSecurityTrustUrl(unsafeBlobUrl)
167
+ : unsafeBlobUrl), catchError(() => of('')), finalize(() => (this.loading = false)));
168
+ }), tap((imagePath) => {
169
+ this.latestValue = imagePath;
170
+ this.cdr.markForCheck();
171
+ }))
172
+ .subscribe();
173
+ this.subscription.add(transformSubscription);
174
+ }
175
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: SecureImagePipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
176
+ static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "21.0.3", ngImport: i0, type: SecureImagePipe, isStandalone: true, name: "secureImage", pure: false });
177
+ }
178
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: SecureImagePipe, decorators: [{
179
+ type: Pipe,
180
+ args: [{
181
+ name: 'secureImage',
182
+ pure: false,
183
+ standalone: true,
184
+ }]
185
+ }], ctorParameters: () => [] });
186
+
187
+ class UploadFilePreview {
188
+ value = input(null, ...(ngDevMode ? [{ debugName: "value" }] : []));
189
+ imgPath = input(...(ngDevMode ? [undefined, { debugName: "imgPath" }] : []));
190
+ context = input(undefined, ...(ngDevMode ? [{ debugName: "context" }] : []));
191
+ loading = input(false, ...(ngDevMode ? [{ debugName: "loading" }] : []));
192
+ uploadProgress = input(0, ...(ngDevMode ? [{ debugName: "uploadProgress" }] : []));
193
+ onUploadInputClicked = output();
194
+ ondDownloadFile = output();
195
+ onDeleteFile = output();
196
+ disabled = model(false, ...(ngDevMode ? [{ debugName: "disabled" }] : []));
197
+ readonly = input(false, ...(ngDevMode ? [{ debugName: "readonly" }] : []));
198
+ size = input(...(ngDevMode ? [undefined, { debugName: "size" }] : []));
199
+ isImag = computed(() => {
200
+ return this.value()?.contentType?.startsWith('image/');
201
+ }, ...(ngDevMode ? [{ debugName: "isImag" }] : []));
202
+ ngOnInit() {
203
+ if (this.readonly()) {
204
+ this.disabled.set(true);
205
+ }
206
+ }
207
+ defaultIcon = computed(() => {
208
+ switch (this.value()?.extension) {
209
+ case '.pdf':
210
+ return 'file.file-06';
211
+ case '.docx':
212
+ case '.doc':
213
+ return 'file.file-06';
214
+ case '.xlsx':
215
+ case '.xls':
216
+ return 'file.file-06';
217
+ default:
218
+ return 'image.image-03';
219
+ }
220
+ }, ...(ngDevMode ? [{ debugName: "defaultIcon" }] : []));
221
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: UploadFilePreview, deps: [], target: i0.ɵɵFactoryTarget.Component });
222
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.3", type: UploadFilePreview, isStandalone: true, selector: "mt-upload-file-preview", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, imgPath: { classPropertyName: "imgPath", publicName: "imgPath", isSignal: true, isRequired: false, transformFunction: null }, context: { classPropertyName: "context", publicName: "context", isSignal: true, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null }, uploadProgress: { classPropertyName: "uploadProgress", publicName: "uploadProgress", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, readonly: { classPropertyName: "readonly", publicName: "readonly", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { onUploadInputClicked: "onUploadInputClicked", ondDownloadFile: "ondDownloadFile", onDeleteFile: "onDeleteFile", disabled: "disabledChange" }, ngImport: i0, template: "<div class=\"flex items-center justify-between gap-2 w-full p-2 overflow-hidden\">\r\n <div class=\"flex gap-2 items-center flex-1 min-w-0 overflow-hidden\">\r\n <mt-avatar\r\n [size]=\"size()\"\r\n [shape]=\"'square'\"\r\n [image]=\"\r\n isImag() && imgPath() ? (imgPath() | secureImage: context()) : ''\r\n \"\r\n [icon]=\"defaultIcon()\"\r\n styleClass=\"text-2xl!\"\r\n >\r\n </mt-avatar>\r\n\r\n <span class=\"truncate\" [mtTooltip]=\"value().name\" tooltipPosition=\"top\">\r\n {{ value().name }}\r\n </span>\r\n </div>\r\n <div class=\"flex items-center justify-center shrink-0\">\r\n @if (!!value() && !loading() && (!disabled() || readonly())) {\r\n <mt-button\r\n variant=\"text\"\r\n icon=\"general.download-01\"\r\n [tooltip]=\"'components.upload.download' | transloco\"\r\n (onClick)=\"ondDownloadFile.emit(value())\"\r\n (click)=\"$event.stopPropagation()\"\r\n >\r\n </mt-button>\r\n }\r\n @if (!disabled() && !readonly() && !!value() && !loading()) {\r\n <mt-button\r\n variant=\"text\"\r\n icon=\"general.trash-01\"\r\n [tooltip]=\"'components.upload.delete' | transloco\"\r\n severity=\"danger\"\r\n (onClick)=\"onDeleteFile.emit(true)\"\r\n (click)=\"$event.stopPropagation()\"\r\n >\r\n </mt-button>\r\n }\r\n </div>\r\n</div>\r\n", styles: [""], dependencies: [{ kind: "component", type: Button, selector: "mt-button", inputs: ["icon", "label", "tooltip", "class", "type", "styleClass", "severity", "badge", "variant", "badgeSeverity", "size", "iconPos", "autofocus", "fluid", "raised", "rounded", "text", "plain", "outlined", "link", "disabled", "loading", "pInputs"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "component", type: Avatar, selector: "mt-avatar", inputs: ["label", "icon", "image", "styleClass", "size", "shape", "badge", "badgeSize", "badgeSeverity"], outputs: ["onImageError"] }, { kind: "ngmodule", type: TranslocoModule }, { kind: "directive", type: Tooltip, selector: "[mtTooltip]" }, { kind: "pipe", type: SecureImagePipe, name: "secureImage" }, { kind: "pipe", type: i1.TranslocoPipe, name: "transloco" }] });
223
+ }
224
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: UploadFilePreview, decorators: [{
225
+ type: Component,
226
+ args: [{ selector: 'mt-upload-file-preview', standalone: true, imports: [SecureImagePipe, Button, Avatar, TranslocoModule, Tooltip], template: "<div class=\"flex items-center justify-between gap-2 w-full p-2 overflow-hidden\">\r\n <div class=\"flex gap-2 items-center flex-1 min-w-0 overflow-hidden\">\r\n <mt-avatar\r\n [size]=\"size()\"\r\n [shape]=\"'square'\"\r\n [image]=\"\r\n isImag() && imgPath() ? (imgPath() | secureImage: context()) : ''\r\n \"\r\n [icon]=\"defaultIcon()\"\r\n styleClass=\"text-2xl!\"\r\n >\r\n </mt-avatar>\r\n\r\n <span class=\"truncate\" [mtTooltip]=\"value().name\" tooltipPosition=\"top\">\r\n {{ value().name }}\r\n </span>\r\n </div>\r\n <div class=\"flex items-center justify-center shrink-0\">\r\n @if (!!value() && !loading() && (!disabled() || readonly())) {\r\n <mt-button\r\n variant=\"text\"\r\n icon=\"general.download-01\"\r\n [tooltip]=\"'components.upload.download' | transloco\"\r\n (onClick)=\"ondDownloadFile.emit(value())\"\r\n (click)=\"$event.stopPropagation()\"\r\n >\r\n </mt-button>\r\n }\r\n @if (!disabled() && !readonly() && !!value() && !loading()) {\r\n <mt-button\r\n variant=\"text\"\r\n icon=\"general.trash-01\"\r\n [tooltip]=\"'components.upload.delete' | transloco\"\r\n severity=\"danger\"\r\n (onClick)=\"onDeleteFile.emit(true)\"\r\n (click)=\"$event.stopPropagation()\"\r\n >\r\n </mt-button>\r\n }\r\n </div>\r\n</div>\r\n" }]
227
+ }], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }], imgPath: [{ type: i0.Input, args: [{ isSignal: true, alias: "imgPath", required: false }] }], context: [{ type: i0.Input, args: [{ isSignal: true, alias: "context", required: false }] }], loading: [{ type: i0.Input, args: [{ isSignal: true, alias: "loading", required: false }] }], uploadProgress: [{ type: i0.Input, args: [{ isSignal: true, alias: "uploadProgress", required: false }] }], onUploadInputClicked: [{ type: i0.Output, args: ["onUploadInputClicked"] }], ondDownloadFile: [{ type: i0.Output, args: ["ondDownloadFile"] }], onDeleteFile: [{ type: i0.Output, args: ["onDeleteFile"] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }, { type: i0.Output, args: ["disabledChange"] }], readonly: [{ type: i0.Input, args: [{ isSignal: true, alias: "readonly", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }] } });
228
+
229
+ class UploadUserPreview {
230
+ value = input(null, ...(ngDevMode ? [{ debugName: "value" }] : []));
231
+ imgPath = input(...(ngDevMode ? [undefined, { debugName: "imgPath" }] : []));
232
+ context = input(undefined, ...(ngDevMode ? [{ debugName: "context" }] : []));
233
+ loading = input(false, ...(ngDevMode ? [{ debugName: "loading" }] : []));
234
+ uploadProgress = input(0, ...(ngDevMode ? [{ debugName: "uploadProgress" }] : []));
235
+ isDragging = input(false, ...(ngDevMode ? [{ debugName: "isDragging" }] : []));
236
+ defaultIcon = signal('image.image-03', ...(ngDevMode ? [{ debugName: "defaultIcon" }] : []));
237
+ onUploadInputClicked = output();
238
+ ondDownloadFile = output();
239
+ onDeleteFile = output();
240
+ onDragOver = output();
241
+ onDragLeave = output();
242
+ onDrop = output();
243
+ disabled = model(false, ...(ngDevMode ? [{ debugName: "disabled" }] : []));
244
+ readonly = input(false, ...(ngDevMode ? [{ debugName: "readonly" }] : []));
245
+ size = input(...(ngDevMode ? [undefined, { debugName: "size" }] : []));
246
+ userImgClass = input('', ...(ngDevMode ? [{ debugName: "userImgClass" }] : []));
247
+ OnUploadInputClicked() {
248
+ if (!this.imgPath() && !this.loading() && !this.disabled()) {
249
+ this.onUploadInputClicked.emit(true);
250
+ }
251
+ }
252
+ ngOnInit() {
253
+ if (this.readonly()) {
254
+ this.disabled.set(true);
255
+ }
256
+ }
257
+ OnDragOver(event) {
258
+ this.onDragOver.emit(event);
259
+ }
260
+ OnDragLeave(event) {
261
+ this.onDragLeave.emit(event);
262
+ }
263
+ OnDrop(event) {
264
+ this.onDrop.emit(event);
265
+ }
266
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: UploadUserPreview, deps: [], target: i0.ɵɵFactoryTarget.Component });
267
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.3", type: UploadUserPreview, isStandalone: true, selector: "mt-upload-user-preview", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, imgPath: { classPropertyName: "imgPath", publicName: "imgPath", isSignal: true, isRequired: false, transformFunction: null }, context: { classPropertyName: "context", publicName: "context", isSignal: true, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null }, uploadProgress: { classPropertyName: "uploadProgress", publicName: "uploadProgress", isSignal: true, isRequired: false, transformFunction: null }, isDragging: { classPropertyName: "isDragging", publicName: "isDragging", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, readonly: { classPropertyName: "readonly", publicName: "readonly", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, userImgClass: { classPropertyName: "userImgClass", publicName: "userImgClass", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { onUploadInputClicked: "onUploadInputClicked", ondDownloadFile: "ondDownloadFile", onDeleteFile: "onDeleteFile", onDragOver: "onDragOver", onDragLeave: "onDragLeave", onDrop: "onDrop", disabled: "disabledChange" }, ngImport: i0, template: "<div\r\n class=\"rounded-full p-1 w-fit\"\r\n [style.background]=\"\r\n 'conic-gradient(var(--p-primary-300) ' +\r\n uploadProgress() +\r\n '%, transparent ' +\r\n uploadProgress() +\r\n '%)'\r\n \"\r\n>\r\n <div\r\n class=\"relative rounded-full w-fit border-2 border-dashed border-gray-300 bg-white\"\r\n [class.opacity-50]=\"isDragging()\"\r\n >\r\n <mt-avatar\r\n [size]=\"size()\"\r\n [image]=\"imgPath() ? (imgPath() | secureImage: context()) : ''\"\r\n [icon]=\"defaultIcon()\"\r\n [styleClass]=\"userImgClass()\"\r\n >\r\n </mt-avatar>\r\n\r\n @if (!loading()) {\r\n <div\r\n class=\"absolute inset-0 flex items-center justify-center rounded-full bg-surface-400/50 opacity-0 hover:opacity-100 transition-opacity\"\r\n [class]=\"!imgPath() && !disabled() ? 'cursor-pointer' : ''\"\r\n (click)=\"OnUploadInputClicked()\"\r\n (dragover)=\"OnDragOver($event)\"\r\n (dragleave)=\"OnDragLeave($event)\"\r\n (drop)=\"OnDrop($event)\"\r\n >\r\n @if (!disabled() && !!imgPath()) {\r\n <mt-button\r\n variant=\"text\"\r\n icon=\"general.download-01\"\r\n [tooltip]=\"'components.upload.download' | transloco\"\r\n (onClick)=\"ondDownloadFile.emit(value())\"\r\n >\r\n </mt-button>\r\n <mt-button\r\n variant=\"text\"\r\n icon=\"general.trash-01\"\r\n [tooltip]=\"'components.upload.delete' | transloco\"\r\n severity=\"danger\"\r\n (onClick)=\"onDeleteFile.emit(true)\"\r\n >\r\n </mt-button>\r\n }\r\n @if (!imgPath() && !disabled()) {\r\n <mt-icon\r\n icon=\"general.upload-01\"\r\n class=\"text-primary-400 text-xl\"\r\n ></mt-icon>\r\n }\r\n </div>\r\n } @else if (loading()) {\r\n <div\r\n class=\"absolute inset-0 flex items-center justify-center rounded-full bg-surface-400/50\"\r\n >\r\n @if (uploadProgress() === 100) {\r\n <mt-icon\r\n icon=\"general.check\"\r\n class=\"text-primary-400 text-2xl\"\r\n ></mt-icon>\r\n } @else {\r\n <small class=\"text-primary-300 font-bold text-lg\">{{\r\n uploadProgress() + \"%\"\r\n }}</small>\r\n }\r\n </div>\r\n }\r\n </div>\r\n</div>\r\n", styles: [""], dependencies: [{ kind: "component", type: Icon, selector: "mt-icon", inputs: ["icon"] }, { kind: "component", type: Button, selector: "mt-button", inputs: ["icon", "label", "tooltip", "class", "type", "styleClass", "severity", "badge", "variant", "badgeSeverity", "size", "iconPos", "autofocus", "fluid", "raised", "rounded", "text", "plain", "outlined", "link", "disabled", "loading", "pInputs"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "component", type: Avatar, selector: "mt-avatar", inputs: ["label", "icon", "image", "styleClass", "size", "shape", "badge", "badgeSize", "badgeSeverity"], outputs: ["onImageError"] }, { kind: "ngmodule", type: TranslocoModule }, { kind: "pipe", type: SecureImagePipe, name: "secureImage" }, { kind: "pipe", type: i1.TranslocoPipe, name: "transloco" }] });
268
+ }
269
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: UploadUserPreview, decorators: [{
270
+ type: Component,
271
+ args: [{ selector: 'mt-upload-user-preview', standalone: true, imports: [Icon, SecureImagePipe, Button, Icon, Avatar, TranslocoModule], template: "<div\r\n class=\"rounded-full p-1 w-fit\"\r\n [style.background]=\"\r\n 'conic-gradient(var(--p-primary-300) ' +\r\n uploadProgress() +\r\n '%, transparent ' +\r\n uploadProgress() +\r\n '%)'\r\n \"\r\n>\r\n <div\r\n class=\"relative rounded-full w-fit border-2 border-dashed border-gray-300 bg-white\"\r\n [class.opacity-50]=\"isDragging()\"\r\n >\r\n <mt-avatar\r\n [size]=\"size()\"\r\n [image]=\"imgPath() ? (imgPath() | secureImage: context()) : ''\"\r\n [icon]=\"defaultIcon()\"\r\n [styleClass]=\"userImgClass()\"\r\n >\r\n </mt-avatar>\r\n\r\n @if (!loading()) {\r\n <div\r\n class=\"absolute inset-0 flex items-center justify-center rounded-full bg-surface-400/50 opacity-0 hover:opacity-100 transition-opacity\"\r\n [class]=\"!imgPath() && !disabled() ? 'cursor-pointer' : ''\"\r\n (click)=\"OnUploadInputClicked()\"\r\n (dragover)=\"OnDragOver($event)\"\r\n (dragleave)=\"OnDragLeave($event)\"\r\n (drop)=\"OnDrop($event)\"\r\n >\r\n @if (!disabled() && !!imgPath()) {\r\n <mt-button\r\n variant=\"text\"\r\n icon=\"general.download-01\"\r\n [tooltip]=\"'components.upload.download' | transloco\"\r\n (onClick)=\"ondDownloadFile.emit(value())\"\r\n >\r\n </mt-button>\r\n <mt-button\r\n variant=\"text\"\r\n icon=\"general.trash-01\"\r\n [tooltip]=\"'components.upload.delete' | transloco\"\r\n severity=\"danger\"\r\n (onClick)=\"onDeleteFile.emit(true)\"\r\n >\r\n </mt-button>\r\n }\r\n @if (!imgPath() && !disabled()) {\r\n <mt-icon\r\n icon=\"general.upload-01\"\r\n class=\"text-primary-400 text-xl\"\r\n ></mt-icon>\r\n }\r\n </div>\r\n } @else if (loading()) {\r\n <div\r\n class=\"absolute inset-0 flex items-center justify-center rounded-full bg-surface-400/50\"\r\n >\r\n @if (uploadProgress() === 100) {\r\n <mt-icon\r\n icon=\"general.check\"\r\n class=\"text-primary-400 text-2xl\"\r\n ></mt-icon>\r\n } @else {\r\n <small class=\"text-primary-300 font-bold text-lg\">{{\r\n uploadProgress() + \"%\"\r\n }}</small>\r\n }\r\n </div>\r\n }\r\n </div>\r\n</div>\r\n" }]
272
+ }], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }], imgPath: [{ type: i0.Input, args: [{ isSignal: true, alias: "imgPath", required: false }] }], context: [{ type: i0.Input, args: [{ isSignal: true, alias: "context", required: false }] }], loading: [{ type: i0.Input, args: [{ isSignal: true, alias: "loading", required: false }] }], uploadProgress: [{ type: i0.Input, args: [{ isSignal: true, alias: "uploadProgress", required: false }] }], isDragging: [{ type: i0.Input, args: [{ isSignal: true, alias: "isDragging", required: false }] }], onUploadInputClicked: [{ type: i0.Output, args: ["onUploadInputClicked"] }], ondDownloadFile: [{ type: i0.Output, args: ["ondDownloadFile"] }], onDeleteFile: [{ type: i0.Output, args: ["onDeleteFile"] }], onDragOver: [{ type: i0.Output, args: ["onDragOver"] }], onDragLeave: [{ type: i0.Output, args: ["onDragLeave"] }], onDrop: [{ type: i0.Output, args: ["onDrop"] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }, { type: i0.Output, args: ["disabledChange"] }], readonly: [{ type: i0.Input, args: [{ isSignal: true, alias: "readonly", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], userImgClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "userImgClass", required: false }] }] } });
273
+
274
+ class UploadField {
275
+ label = input(...(ngDevMode ? [undefined, { debugName: "label" }] : []));
276
+ title = input('Upload File', ...(ngDevMode ? [{ debugName: "title" }] : []));
277
+ description = input('Click or drop a file to upload', ...(ngDevMode ? [{ debugName: "description" }] : []));
278
+ endPoint = input('uploader', ...(ngDevMode ? [{ debugName: "endPoint" }] : []));
279
+ size = input(...(ngDevMode ? [undefined, { debugName: "size" }] : []));
280
+ userImgClass = input('w-25! h-25! text-4xl! text-gray-400!', ...(ngDevMode ? [{ debugName: "userImgClass" }] : []));
281
+ shape = input('field', ...(ngDevMode ? [{ debugName: "shape" }] : []));
282
+ multiple = input(false, ...(ngDevMode ? [{ debugName: "multiple" }] : []));
283
+ accept = input('.pdf,.doc,.docx,.xlsx,image/*', ...(ngDevMode ? [{ debugName: "accept" }] : []));
284
+ isDragging = model(false, ...(ngDevMode ? [{ debugName: "isDragging" }] : []));
285
+ fileSizeLimit = input(...(ngDevMode ? [undefined, { debugName: "fileSizeLimit" }] : []));
286
+ readonly = input(false, ...(ngDevMode ? [{ debugName: "readonly" }] : []));
287
+ context = input(undefined, ...(ngDevMode ? [{ debugName: "context" }] : []));
288
+ onChange = output();
289
+ requiredValidator = Validators.required;
290
+ value = signal(null, ...(ngDevMode ? [{ debugName: "value" }] : []));
291
+ files = computed(() => {
292
+ const value = this.value();
293
+ if (Array.isArray(value)) {
294
+ return value.filter((item) => item != null);
295
+ }
296
+ return value ? [value] : [];
297
+ }, ...(ngDevMode ? [{ debugName: "files" }] : []));
298
+ primaryFile = computed(() => this.files()[0] ?? null, ...(ngDevMode ? [{ debugName: "primaryFile" }] : []));
299
+ imgPath = computed(() => this.resolveImgPath(this.primaryFile()), ...(ngDevMode ? [{ debugName: "imgPath" }] : []));
300
+ disabled = signal(false, ...(ngDevMode ? [{ debugName: "disabled" }] : []));
301
+ uploadProgress = signal(0, ...(ngDevMode ? [{ debugName: "uploadProgress" }] : []));
302
+ loading = signal(false, ...(ngDevMode ? [{ debugName: "loading" }] : []));
303
+ httpClient = inject(HttpClient);
304
+ pendingUploads = signal(0, ...(ngDevMode ? [{ debugName: "pendingUploads" }] : []));
305
+ onTouched = () => { };
306
+ onModelChange = () => { };
307
+ ngControl = inject(NgControl, { self: true });
308
+ constructor() {
309
+ if (this.ngControl) {
310
+ this.ngControl.valueAccessor = this;
311
+ }
312
+ }
313
+ writeValue(value) {
314
+ if (Array.isArray(value)) {
315
+ const normalized = value.filter((item) => item != null);
316
+ const fileIds = normalized.filter((item) => typeof item === 'string' && item.trim().length > 0);
317
+ const files = normalized.filter((item) => !!item && typeof item === 'object');
318
+ if (fileIds.length) {
319
+ this.fetchMetadata(fileIds, files, true);
320
+ return;
321
+ }
322
+ this.value.set(normalized);
323
+ return;
324
+ }
325
+ if (typeof value === 'string' && value.trim().length > 0) {
326
+ this.fetchMetadata([value], [], false);
327
+ return;
328
+ }
329
+ this.value.set(value ?? null);
330
+ }
331
+ registerOnChange(fn) {
332
+ this.onModelChange = fn;
333
+ }
334
+ registerOnTouched(fn) {
335
+ this.onTouched = fn;
336
+ }
337
+ setDisabledState(disabled) {
338
+ this.disabled.set(disabled);
339
+ }
340
+ onAdd(item) {
341
+ if (this.disabled()) {
342
+ return;
343
+ }
344
+ const nextValue = this.multiple() ? [...this.files(), item] : item;
345
+ this.value.set(nextValue);
346
+ this.onModelChange(nextValue);
347
+ this.onChange.emit(nextValue);
348
+ }
349
+ onDelete(item) {
350
+ if (this.disabled()) {
351
+ return;
352
+ }
353
+ if (!this.multiple()) {
354
+ this.value.set(null);
355
+ this.onModelChange(null);
356
+ this.onChange.emit(null);
357
+ return;
358
+ }
359
+ const nextValue = this.files().filter((file) => !isSameFile(file, item));
360
+ const resolvedValue = nextValue.length ? nextValue : null;
361
+ this.value.set(resolvedValue);
362
+ this.onModelChange(resolvedValue);
363
+ this.onChange.emit(resolvedValue);
364
+ }
365
+ onFileSelect(event) {
366
+ const input = event.target;
367
+ const selectedFiles = Array.from(input?.files ?? []);
368
+ if (!selectedFiles.length) {
369
+ return;
370
+ }
371
+ if (!this.multiple()) {
372
+ this.value.set(null);
373
+ }
374
+ this.prepareFiles(selectedFiles);
375
+ if (input) {
376
+ input.value = '';
377
+ }
378
+ }
379
+ prepareFiles(files) {
380
+ this.ngControl.control?.setErrors({ uploading: true });
381
+ if (this.shape() === 'circle' &&
382
+ files.some((file) => !file?.type.startsWith('image/'))) {
383
+ this.ngControl.control?.setErrors({ invalidFileType: true });
384
+ return;
385
+ }
386
+ const filesToUpload = this.multiple() ? files : [files[0]];
387
+ filesToUpload.forEach((file) => this.uploadFile(file));
388
+ }
389
+ uploadFile(file) {
390
+ this.pendingUploads.update((count) => count + 1);
391
+ this.loading.set(true);
392
+ this.uploadProgress.set(10);
393
+ const formData = new FormData();
394
+ formData.append('file', file);
395
+ this.httpClient
396
+ .post(this.endPoint(), formData, {
397
+ reportProgress: true,
398
+ observe: 'events',
399
+ context: this.context(),
400
+ })
401
+ .pipe(finalize$1(() => {
402
+ const pending = Math.max(this.pendingUploads() - 1, 0);
403
+ this.pendingUploads.set(pending);
404
+ if (!pending) {
405
+ setTimeout(() => {
406
+ this.uploadProgress.set(0);
407
+ this.loading.set(false);
408
+ }, 700);
409
+ }
410
+ }), catchError$1(() => {
411
+ this.uploadProgress.set(0);
412
+ return throwError(() => new Error('Upload failed'));
413
+ }))
414
+ .subscribe((event) => {
415
+ if (!event?.body) {
416
+ if (event.total) {
417
+ this.uploadProgress.set(Math.round((100 * event.loaded) / event.total));
418
+ }
419
+ return;
420
+ }
421
+ this.uploadProgress.set(100);
422
+ this.handleUploadDone({ ...event.body?.data, size: file.size });
423
+ });
424
+ }
425
+ handleUploadDone(file) {
426
+ if (!file) {
427
+ return;
428
+ }
429
+ this.onAdd(file);
430
+ if (this.fileSizeLimit() && file.size > this.fileSizeLimit()) {
431
+ this.ngControl.control?.setErrors({ fileSizeLimited: true });
432
+ return;
433
+ }
434
+ if (this.pendingUploads() <= 1) {
435
+ this.ngControl.control?.setErrors(null);
436
+ }
437
+ }
438
+ downloadFile(value) {
439
+ const downloadUrl = this.resolveImgPath(value);
440
+ const downloadFileName = value?.name;
441
+ const mimeType = value?.contentType;
442
+ if (!downloadUrl || !mimeType || !downloadFileName) {
443
+ console.error('File metadata is incomplete. Cannot download.');
444
+ return;
445
+ }
446
+ this.httpClient
447
+ .get(downloadUrl, {
448
+ responseType: 'blob',
449
+ context: this.context(),
450
+ })
451
+ .pipe(take(1))
452
+ .subscribe((res) => {
453
+ const blob = new Blob([res], { type: mimeType });
454
+ const data = window.URL.createObjectURL(blob);
455
+ const link = document.createElement('a');
456
+ link.href = data;
457
+ link.download = downloadFileName;
458
+ link.click();
459
+ window.URL.revokeObjectURL(data);
460
+ });
461
+ }
462
+ onDragOver(event) {
463
+ event.preventDefault();
464
+ event.stopPropagation();
465
+ if (!this.disabled()) {
466
+ this.isDragging.set(true);
467
+ }
468
+ }
469
+ onDragLeave(event) {
470
+ event.preventDefault();
471
+ event.stopPropagation();
472
+ this.isDragging.set(false);
473
+ }
474
+ onDrop(event) {
475
+ event.preventDefault();
476
+ event.stopPropagation();
477
+ this.isDragging.set(false);
478
+ if (this.disabled()) {
479
+ return;
480
+ }
481
+ const files = Array.from(event.dataTransfer?.files ?? []);
482
+ if (!files.length) {
483
+ return;
484
+ }
485
+ if (!this.multiple()) {
486
+ this.value.set(null);
487
+ }
488
+ this.prepareFiles(files);
489
+ }
490
+ resolveImgPath(value) {
491
+ return value?.fileName ? `${this.endPoint()}/${value.fileName}` : undefined;
492
+ }
493
+ fetchMetadata(fileIds, existingFiles = [], forceArray = false) {
494
+ const normalizedIds = fileIds
495
+ .map((fileId) => fileId.trim())
496
+ .filter((fileId) => fileId.length > 0);
497
+ if (!normalizedIds.length) {
498
+ this.value.set(forceArray ? existingFiles : (existingFiles[0] ?? null));
499
+ return;
500
+ }
501
+ this.loading.set(true);
502
+ forkJoin(normalizedIds.map((fileId) => this.httpClient
503
+ .get(`${this.endPoint()}/${fileId}/metaData`, {
504
+ context: this.context(),
505
+ })
506
+ .pipe(take(1), map$1((response) => response.data), catchError$1((error) => {
507
+ console.error('Failed to fetch file metadata:', error);
508
+ return of({
509
+ id: fileId,
510
+ name: fileId,
511
+ fileName: fileId,
512
+ contentType: '',
513
+ extension: '',
514
+ });
515
+ }))))
516
+ .pipe(finalize$1(() => this.loading.set(false)))
517
+ .subscribe((files) => {
518
+ const resolvedFiles = [...existingFiles, ...files];
519
+ const resolvedValue = forceArray || this.multiple() || resolvedFiles.length > 1
520
+ ? resolvedFiles
521
+ : (resolvedFiles[0] ?? null);
522
+ this.value.set(resolvedValue);
523
+ });
524
+ }
525
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: UploadField, deps: [], target: i0.ɵɵFactoryTarget.Component });
526
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.3", type: UploadField, isStandalone: true, selector: "mt-upload-field", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, description: { classPropertyName: "description", publicName: "description", isSignal: true, isRequired: false, transformFunction: null }, endPoint: { classPropertyName: "endPoint", publicName: "endPoint", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, userImgClass: { classPropertyName: "userImgClass", publicName: "userImgClass", isSignal: true, isRequired: false, transformFunction: null }, shape: { classPropertyName: "shape", publicName: "shape", isSignal: true, isRequired: false, transformFunction: null }, multiple: { classPropertyName: "multiple", publicName: "multiple", isSignal: true, isRequired: false, transformFunction: null }, accept: { classPropertyName: "accept", publicName: "accept", isSignal: true, isRequired: false, transformFunction: null }, isDragging: { classPropertyName: "isDragging", publicName: "isDragging", isSignal: true, isRequired: false, transformFunction: null }, fileSizeLimit: { classPropertyName: "fileSizeLimit", publicName: "fileSizeLimit", isSignal: true, isRequired: false, transformFunction: null }, readonly: { classPropertyName: "readonly", publicName: "readonly", isSignal: true, isRequired: false, transformFunction: null }, context: { classPropertyName: "context", publicName: "context", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { isDragging: "isDraggingChange", onChange: "onChange" }, ngImport: i0, template: "<input\r\n #uploadInput\r\n type=\"file\"\r\n name=\"file[]\"\r\n (change)=\"onFileSelect($event)\"\r\n style=\"display: none\"\r\n [multiple]=\"multiple()\"\r\n [accept]=\"shape() === 'circle' ? 'image/*' : accept()\"\r\n/>\r\n\r\n@if (shape() === \"circle\") {\r\n <div class=\"flex flex-col items-center gap-2 w-full\">\r\n <div class=\"flex\">\r\n <div class=\"flex flex-col items-center\">\r\n <mt-upload-user-preview\r\n [value]=\"primaryFile()\"\r\n [imgPath]=\"imgPath()\"\r\n [disabled]=\"disabled()\"\r\n [readonly]=\"readonly()\"\r\n [loading]=\"loading()\"\r\n [size]=\"size()\"\r\n [context]=\"context()\"\r\n [userImgClass]=\"userImgClass()\"\r\n [isDragging]=\"isDragging()\"\r\n [uploadProgress]=\"uploadProgress()\"\r\n (onUploadInputClicked)=\"uploadInput.click()\"\r\n (ondDownloadFile)=\"downloadFile($event)\"\r\n (onDeleteFile)=\"onDelete(primaryFile())\"\r\n (onDragOver)=\"onDragOver($event)\"\r\n (onDragLeave)=\"onDragLeave($event)\"\r\n (onDrop)=\"onDrop($event)\"\r\n ></mt-upload-user-preview>\r\n @if (label()) {\r\n <label\r\n [class.required]=\"\r\n ngControl?.control?.hasValidator(requiredValidator)\r\n \"\r\n [for]=\"ngControl?.name || label()\"\r\n >{{ label() }}</label\r\n >\r\n }\r\n </div>\r\n </div>\r\n </div>\r\n} @else if (shape() === \"card\") {\r\n <mt-card\r\n headless\r\n class=\"border-2 border-dashed border-gray-300 rounded-lg cursor-pointer hover:bg-gray-50\"\r\n >\r\n <div class=\"content flex flex-col gap-5 items-center text-center\">\r\n @if (!files().length && !loading()) {\r\n <div class=\"flex flex-col gap-1\">\r\n @if (title()) {\r\n <div class=\"title text-lg font-semibold\">\r\n {{ title() }}\r\n </div>\r\n }\r\n @if (description()) {\r\n <div\r\n class=\"description text-sm text-muted-foreground secondary text-surface-500\"\r\n >\r\n {{ description() }}\r\n </div>\r\n }\r\n </div>\r\n }\r\n\r\n @if (files().length) {\r\n <div class=\"flex w-full flex-col gap-2\">\r\n @for (file of files(); track $index) {\r\n <mt-upload-file-preview\r\n style=\"width: 100%\"\r\n [value]=\"file\"\r\n [imgPath]=\"resolveImgPath(file)\"\r\n [disabled]=\"disabled()\"\r\n [readonly]=\"readonly()\"\r\n [loading]=\"loading()\"\r\n [context]=\"context()\"\r\n [uploadProgress]=\"uploadProgress()\"\r\n (onUploadInputClicked)=\"uploadInput.click()\"\r\n (ondDownloadFile)=\"downloadFile(file)\"\r\n (onDeleteFile)=\"onDelete(file)\"\r\n />\r\n }\r\n </div>\r\n } @else if (loading()) {\r\n <div class=\"w-full flex gap-3 items-center justify-center p-3\">\r\n <p class=\"text-lg text-gray-500\">\r\n {{\r\n (\"components.upload.uploading\" | transloco) +\r\n uploadProgress() +\r\n \"%\"\r\n }}\r\n </p>\r\n </div>\r\n } @else {\r\n <mt-button\r\n [size]=\"'small'\"\r\n [label]=\"'components.upload.upload' | transloco\"\r\n [icon]=\"'general.upload-01'\"\r\n (onClick)=\"\r\n !loading() && !disabled() && !readonly() ? uploadInput.click() : ''\r\n \"\r\n [disabled]=\"disabled() || loading() || readonly()\"\r\n />\r\n }\r\n </div>\r\n </mt-card>\r\n} @else {\r\n <div class=\"flex flex-col items-start gap-2 w-full\">\r\n @if (label()) {\r\n <label\r\n [class.required]=\"ngControl?.control?.hasValidator(requiredValidator)\"\r\n [for]=\"ngControl?.name || label()\"\r\n >{{ label() }}</label\r\n >\r\n }\r\n\r\n <div\r\n class=\"w-full flex gap-3 items-center justify-center border-2 border-dashed border-gray-300 rounded-lg cursor-pointer hover:bg-gray-50\"\r\n [class]=\"disabled() ? 'bg-gray-50' : ''\"\r\n (click)=\"\r\n !loading() && !disabled() && !readonly() ? uploadInput.click() : ''\r\n \"\r\n [class.border-blue-500]=\"isDragging()\"\r\n [class.bg-blue-50]=\"isDragging()\"\r\n (dragover)=\"onDragOver($event)\"\r\n (dragleave)=\"onDragLeave($event)\"\r\n (drop)=\"onDrop($event)\"\r\n >\r\n @if (files().length) {\r\n <div class=\"flex w-full flex-col gap-2 p-2\">\r\n @for (file of files(); track $index) {\r\n <mt-upload-file-preview\r\n style=\"width: 100%\"\r\n [value]=\"file\"\r\n [imgPath]=\"resolveImgPath(file)\"\r\n [disabled]=\"disabled()\"\r\n [readonly]=\"readonly()\"\r\n [loading]=\"loading()\"\r\n [context]=\"context()\"\r\n [uploadProgress]=\"uploadProgress()\"\r\n (onUploadInputClicked)=\"uploadInput.click()\"\r\n (ondDownloadFile)=\"downloadFile(file)\"\r\n (onDeleteFile)=\"onDelete(file)\"\r\n />\r\n }\r\n </div>\r\n } @else if (loading()) {\r\n <div class=\"w-full flex gap-3 items-center justify-center p-3\">\r\n <p class=\"text-lg text-gray-500\">\r\n {{\r\n (\"components.upload.uploading\" | transloco) +\r\n uploadProgress() +\r\n \"%\"\r\n }}\r\n </p>\r\n </div>\r\n } @else {\r\n <div class=\"w-full flex gap-3 items-center justify-center p-3\">\r\n <mt-icon icon=\"general.upload-01\" />\r\n <p class=\"text-lg text-gray-500\">\r\n {{ \"components.upload.clickOrDrop\" | transloco }}\r\n </p>\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n}\r\n<mt-field-validation [control]=\"ngControl?.control\"></mt-field-validation>\r\n", dependencies: [{ kind: "component", type: Icon, selector: "mt-icon", inputs: ["icon"] }, { kind: "component", type: UploadUserPreview, selector: "mt-upload-user-preview", inputs: ["value", "imgPath", "context", "loading", "uploadProgress", "isDragging", "disabled", "readonly", "size", "userImgClass"], outputs: ["onUploadInputClicked", "ondDownloadFile", "onDeleteFile", "onDragOver", "onDragLeave", "onDrop", "disabledChange"] }, { kind: "component", type: UploadFilePreview, selector: "mt-upload-file-preview", inputs: ["value", "imgPath", "context", "loading", "uploadProgress", "disabled", "readonly", "size"], outputs: ["onUploadInputClicked", "ondDownloadFile", "onDeleteFile", "disabledChange"] }, { kind: "component", type: FieldValidation, selector: "mt-field-validation", inputs: ["control", "touched"] }, { kind: "component", type: Card, selector: "mt-card", inputs: ["class", "title", "paddingless"] }, { kind: "component", type: Button, selector: "mt-button", inputs: ["icon", "label", "tooltip", "class", "type", "styleClass", "severity", "badge", "variant", "badgeSeverity", "size", "iconPos", "autofocus", "fluid", "raised", "rounded", "text", "plain", "outlined", "link", "disabled", "loading", "pInputs"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "ngmodule", type: TranslocoModule }, { kind: "pipe", type: i1.TranslocoPipe, name: "transloco" }] });
527
+ }
528
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: UploadField, decorators: [{
529
+ type: Component,
530
+ args: [{ selector: 'mt-upload-field', standalone: true, imports: [
531
+ Icon,
532
+ UploadUserPreview,
533
+ UploadFilePreview,
534
+ FieldValidation,
535
+ Card,
536
+ Button,
537
+ TranslocoModule,
538
+ ], template: "<input\r\n #uploadInput\r\n type=\"file\"\r\n name=\"file[]\"\r\n (change)=\"onFileSelect($event)\"\r\n style=\"display: none\"\r\n [multiple]=\"multiple()\"\r\n [accept]=\"shape() === 'circle' ? 'image/*' : accept()\"\r\n/>\r\n\r\n@if (shape() === \"circle\") {\r\n <div class=\"flex flex-col items-center gap-2 w-full\">\r\n <div class=\"flex\">\r\n <div class=\"flex flex-col items-center\">\r\n <mt-upload-user-preview\r\n [value]=\"primaryFile()\"\r\n [imgPath]=\"imgPath()\"\r\n [disabled]=\"disabled()\"\r\n [readonly]=\"readonly()\"\r\n [loading]=\"loading()\"\r\n [size]=\"size()\"\r\n [context]=\"context()\"\r\n [userImgClass]=\"userImgClass()\"\r\n [isDragging]=\"isDragging()\"\r\n [uploadProgress]=\"uploadProgress()\"\r\n (onUploadInputClicked)=\"uploadInput.click()\"\r\n (ondDownloadFile)=\"downloadFile($event)\"\r\n (onDeleteFile)=\"onDelete(primaryFile())\"\r\n (onDragOver)=\"onDragOver($event)\"\r\n (onDragLeave)=\"onDragLeave($event)\"\r\n (onDrop)=\"onDrop($event)\"\r\n ></mt-upload-user-preview>\r\n @if (label()) {\r\n <label\r\n [class.required]=\"\r\n ngControl?.control?.hasValidator(requiredValidator)\r\n \"\r\n [for]=\"ngControl?.name || label()\"\r\n >{{ label() }}</label\r\n >\r\n }\r\n </div>\r\n </div>\r\n </div>\r\n} @else if (shape() === \"card\") {\r\n <mt-card\r\n headless\r\n class=\"border-2 border-dashed border-gray-300 rounded-lg cursor-pointer hover:bg-gray-50\"\r\n >\r\n <div class=\"content flex flex-col gap-5 items-center text-center\">\r\n @if (!files().length && !loading()) {\r\n <div class=\"flex flex-col gap-1\">\r\n @if (title()) {\r\n <div class=\"title text-lg font-semibold\">\r\n {{ title() }}\r\n </div>\r\n }\r\n @if (description()) {\r\n <div\r\n class=\"description text-sm text-muted-foreground secondary text-surface-500\"\r\n >\r\n {{ description() }}\r\n </div>\r\n }\r\n </div>\r\n }\r\n\r\n @if (files().length) {\r\n <div class=\"flex w-full flex-col gap-2\">\r\n @for (file of files(); track $index) {\r\n <mt-upload-file-preview\r\n style=\"width: 100%\"\r\n [value]=\"file\"\r\n [imgPath]=\"resolveImgPath(file)\"\r\n [disabled]=\"disabled()\"\r\n [readonly]=\"readonly()\"\r\n [loading]=\"loading()\"\r\n [context]=\"context()\"\r\n [uploadProgress]=\"uploadProgress()\"\r\n (onUploadInputClicked)=\"uploadInput.click()\"\r\n (ondDownloadFile)=\"downloadFile(file)\"\r\n (onDeleteFile)=\"onDelete(file)\"\r\n />\r\n }\r\n </div>\r\n } @else if (loading()) {\r\n <div class=\"w-full flex gap-3 items-center justify-center p-3\">\r\n <p class=\"text-lg text-gray-500\">\r\n {{\r\n (\"components.upload.uploading\" | transloco) +\r\n uploadProgress() +\r\n \"%\"\r\n }}\r\n </p>\r\n </div>\r\n } @else {\r\n <mt-button\r\n [size]=\"'small'\"\r\n [label]=\"'components.upload.upload' | transloco\"\r\n [icon]=\"'general.upload-01'\"\r\n (onClick)=\"\r\n !loading() && !disabled() && !readonly() ? uploadInput.click() : ''\r\n \"\r\n [disabled]=\"disabled() || loading() || readonly()\"\r\n />\r\n }\r\n </div>\r\n </mt-card>\r\n} @else {\r\n <div class=\"flex flex-col items-start gap-2 w-full\">\r\n @if (label()) {\r\n <label\r\n [class.required]=\"ngControl?.control?.hasValidator(requiredValidator)\"\r\n [for]=\"ngControl?.name || label()\"\r\n >{{ label() }}</label\r\n >\r\n }\r\n\r\n <div\r\n class=\"w-full flex gap-3 items-center justify-center border-2 border-dashed border-gray-300 rounded-lg cursor-pointer hover:bg-gray-50\"\r\n [class]=\"disabled() ? 'bg-gray-50' : ''\"\r\n (click)=\"\r\n !loading() && !disabled() && !readonly() ? uploadInput.click() : ''\r\n \"\r\n [class.border-blue-500]=\"isDragging()\"\r\n [class.bg-blue-50]=\"isDragging()\"\r\n (dragover)=\"onDragOver($event)\"\r\n (dragleave)=\"onDragLeave($event)\"\r\n (drop)=\"onDrop($event)\"\r\n >\r\n @if (files().length) {\r\n <div class=\"flex w-full flex-col gap-2 p-2\">\r\n @for (file of files(); track $index) {\r\n <mt-upload-file-preview\r\n style=\"width: 100%\"\r\n [value]=\"file\"\r\n [imgPath]=\"resolveImgPath(file)\"\r\n [disabled]=\"disabled()\"\r\n [readonly]=\"readonly()\"\r\n [loading]=\"loading()\"\r\n [context]=\"context()\"\r\n [uploadProgress]=\"uploadProgress()\"\r\n (onUploadInputClicked)=\"uploadInput.click()\"\r\n (ondDownloadFile)=\"downloadFile(file)\"\r\n (onDeleteFile)=\"onDelete(file)\"\r\n />\r\n }\r\n </div>\r\n } @else if (loading()) {\r\n <div class=\"w-full flex gap-3 items-center justify-center p-3\">\r\n <p class=\"text-lg text-gray-500\">\r\n {{\r\n (\"components.upload.uploading\" | transloco) +\r\n uploadProgress() +\r\n \"%\"\r\n }}\r\n </p>\r\n </div>\r\n } @else {\r\n <div class=\"w-full flex gap-3 items-center justify-center p-3\">\r\n <mt-icon icon=\"general.upload-01\" />\r\n <p class=\"text-lg text-gray-500\">\r\n {{ \"components.upload.clickOrDrop\" | transloco }}\r\n </p>\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n}\r\n<mt-field-validation [control]=\"ngControl?.control\"></mt-field-validation>\r\n" }]
539
+ }], ctorParameters: () => [], propDecorators: { label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: false }] }], description: [{ type: i0.Input, args: [{ isSignal: true, alias: "description", required: false }] }], endPoint: [{ type: i0.Input, args: [{ isSignal: true, alias: "endPoint", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], userImgClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "userImgClass", required: false }] }], shape: [{ type: i0.Input, args: [{ isSignal: true, alias: "shape", required: false }] }], multiple: [{ type: i0.Input, args: [{ isSignal: true, alias: "multiple", required: false }] }], accept: [{ type: i0.Input, args: [{ isSignal: true, alias: "accept", required: false }] }], isDragging: [{ type: i0.Input, args: [{ isSignal: true, alias: "isDragging", required: false }] }, { type: i0.Output, args: ["isDraggingChange"] }], fileSizeLimit: [{ type: i0.Input, args: [{ isSignal: true, alias: "fileSizeLimit", required: false }] }], readonly: [{ type: i0.Input, args: [{ isSignal: true, alias: "readonly", required: false }] }], context: [{ type: i0.Input, args: [{ isSignal: true, alias: "context", required: false }] }], onChange: [{ type: i0.Output, args: ["onChange"] }] } });
540
+ function isSameFile(source, target) {
541
+ if (!source || !target) {
542
+ return source === target;
543
+ }
544
+ return (source === target ||
545
+ (source.id && target.id && source.id === target.id) ||
546
+ (source.fileName && target.fileName && source.fileName === target.fileName));
547
+ }
548
+
549
+ /**
550
+ * Generated bundle index. Do not edit.
551
+ */
552
+
553
+ export { SecureImagePipe, UploadField };
554
+ //# sourceMappingURL=masterteam-components-upload-field.mjs.map