@masterteam/components 0.0.34 → 0.0.36
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/assets/common.css +1 -1
- package/dialog/index.d.ts +1 -1
- package/fesm2022/masterteam-components-button.mjs +3 -3
- package/fesm2022/masterteam-components-button.mjs.map +1 -1
- package/fesm2022/masterteam-components-color-picker-field.mjs +1 -1
- package/fesm2022/masterteam-components-color-picker-field.mjs.map +1 -1
- package/fesm2022/masterteam-components-dialog.mjs.map +1 -1
- package/fesm2022/masterteam-components-field-validation.mjs +3 -0
- package/fesm2022/masterteam-components-field-validation.mjs.map +1 -1
- package/fesm2022/masterteam-components-formula-builder.mjs +1 -1
- package/fesm2022/masterteam-components-formula-builder.mjs.map +1 -1
- package/fesm2022/masterteam-components-table.mjs +56 -9
- package/fesm2022/masterteam-components-table.mjs.map +1 -1
- package/fesm2022/masterteam-components-text-field.mjs +45 -12
- package/fesm2022/masterteam-components-text-field.mjs.map +1 -1
- package/fesm2022/masterteam-components-tooltip.mjs +5 -5
- package/fesm2022/masterteam-components-tooltip.mjs.map +1 -1
- package/fesm2022/masterteam-components-upload-field.mjs +330 -0
- package/fesm2022/masterteam-components-upload-field.mjs.map +1 -0
- package/fesm2022/masterteam-components-user-search-field.mjs +6 -7
- package/fesm2022/masterteam-components-user-search-field.mjs.map +1 -1
- package/fesm2022/masterteam-components.mjs +16 -1
- package/fesm2022/masterteam-components.mjs.map +1 -1
- package/index.d.ts +15 -1
- package/package.json +34 -30
- package/table/index.d.ts +23 -6
- package/text-field/index.d.ts +6 -3
- package/tooltip/index.d.ts +1 -1
- package/upload-field/index.d.ts +43 -0
|
@@ -5,7 +5,7 @@ import { Tooltip as Tooltip$1 } from 'primeng/tooltip';
|
|
|
5
5
|
|
|
6
6
|
class Tooltip {
|
|
7
7
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: Tooltip, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
8
|
-
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.1.3", type: Tooltip, isStandalone: true, selector: "[mtTooltip]", hostDirectives: [{ directive: i1.Tooltip, inputs: ["pTooltip", "mtTooltip", "tooltipPosition", "
|
|
8
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.1.3", type: Tooltip, isStandalone: true, selector: "[mtTooltip]", hostDirectives: [{ directive: i1.Tooltip, inputs: ["pTooltip", "mtTooltip", "tooltipPosition", "tooltipPosition", "tooltipEvent", "tooltipEvent", "appendTo", "appendTo", "tooltipStyleClass", "tooltipStyleClass", "escape", "escape", "showDelay", "showDelay", "hideDelay", "hideDelay", "life", "life", "positionTop", "positionTop", "positionLeft", "positionLeft", "autoHide", "autoHide", "fitContent", "fitContent", "hideOnEscape", "hideOnEscape", "tooltipDisabled", "tooltipDisabled"] }], ngImport: i0 });
|
|
9
9
|
}
|
|
10
10
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: Tooltip, decorators: [{
|
|
11
11
|
type: Directive,
|
|
@@ -17,10 +17,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.3", ngImpor
|
|
|
17
17
|
directive: Tooltip$1,
|
|
18
18
|
inputs: [
|
|
19
19
|
'pTooltip: mtTooltip',
|
|
20
|
-
'tooltipPosition
|
|
21
|
-
'tooltipEvent
|
|
20
|
+
'tooltipPosition',
|
|
21
|
+
'tooltipEvent',
|
|
22
22
|
'appendTo',
|
|
23
|
-
'tooltipStyleClass
|
|
23
|
+
'tooltipStyleClass',
|
|
24
24
|
'escape',
|
|
25
25
|
'showDelay',
|
|
26
26
|
'hideDelay',
|
|
@@ -30,7 +30,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.3", ngImpor
|
|
|
30
30
|
'autoHide',
|
|
31
31
|
'fitContent',
|
|
32
32
|
'hideOnEscape',
|
|
33
|
-
'tooltipDisabled
|
|
33
|
+
'tooltipDisabled',
|
|
34
34
|
],
|
|
35
35
|
},
|
|
36
36
|
],
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"masterteam-components-tooltip.mjs","sources":["../../../../packages/masterteam/components/tooltip/tooltip.ts","../../../../packages/masterteam/components/tooltip/masterteam-components-tooltip.ts"],"sourcesContent":["import { Directive } from '@angular/core';\nimport { Tooltip as PrimeTooltip } from 'primeng/tooltip';\n\n@Directive({\n selector: '[mtTooltip]',\n standalone: true,\n hostDirectives: [\n {\n directive: PrimeTooltip,\n inputs: [\n 'pTooltip: mtTooltip',\n 'tooltipPosition
|
|
1
|
+
{"version":3,"file":"masterteam-components-tooltip.mjs","sources":["../../../../packages/masterteam/components/tooltip/tooltip.ts","../../../../packages/masterteam/components/tooltip/masterteam-components-tooltip.ts"],"sourcesContent":["import { Directive } from '@angular/core';\nimport { Tooltip as PrimeTooltip } from 'primeng/tooltip';\n\n@Directive({\n selector: '[mtTooltip]',\n standalone: true,\n hostDirectives: [\n {\n directive: PrimeTooltip,\n inputs: [\n 'pTooltip: mtTooltip',\n 'tooltipPosition',\n 'tooltipEvent',\n 'appendTo',\n 'tooltipStyleClass',\n 'escape',\n 'showDelay',\n 'hideDelay',\n 'life',\n 'positionTop',\n 'positionLeft',\n 'autoHide',\n 'fitContent',\n 'hideOnEscape',\n 'tooltipDisabled',\n ],\n },\n ],\n})\nexport class Tooltip {}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":["PrimeTooltip"],"mappings":";;;;;MA6Ba,OAAO,CAAA;uGAAP,OAAO,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;2FAAP,OAAO,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,aAAA,EAAA,cAAA,EAAA,CAAA,EAAA,SAAA,EAAA,EAAA,CAAA,OAAA,EAAA,MAAA,EAAA,CAAA,UAAA,EAAA,WAAA,EAAA,iBAAA,EAAA,iBAAA,EAAA,cAAA,EAAA,cAAA,EAAA,UAAA,EAAA,UAAA,EAAA,mBAAA,EAAA,mBAAA,EAAA,QAAA,EAAA,QAAA,EAAA,WAAA,EAAA,WAAA,EAAA,WAAA,EAAA,WAAA,EAAA,MAAA,EAAA,MAAA,EAAA,aAAA,EAAA,aAAA,EAAA,cAAA,EAAA,cAAA,EAAA,UAAA,EAAA,UAAA,EAAA,YAAA,EAAA,YAAA,EAAA,cAAA,EAAA,cAAA,EAAA,iBAAA,EAAA,iBAAA,CAAA,EAAA,CAAA,EAAA,QAAA,EAAA,EAAA,EAAA,CAAA;;2FAAP,OAAO,EAAA,UAAA,EAAA,CAAA;kBA1BnB,SAAS;AAAC,YAAA,IAAA,EAAA,CAAA;AACT,oBAAA,QAAQ,EAAE,aAAa;AACvB,oBAAA,UAAU,EAAE,IAAI;AAChB,oBAAA,cAAc,EAAE;AACd,wBAAA;AACE,4BAAA,SAAS,EAAEA,SAAY;AACvB,4BAAA,MAAM,EAAE;gCACN,qBAAqB;gCACrB,iBAAiB;gCACjB,cAAc;gCACd,UAAU;gCACV,mBAAmB;gCACnB,QAAQ;gCACR,WAAW;gCACX,WAAW;gCACX,MAAM;gCACN,aAAa;gCACb,cAAc;gCACd,UAAU;gCACV,YAAY;gCACZ,cAAc;gCACd,iBAAiB;AAClB,6BAAA;AACF,yBAAA;AACF,qBAAA;AACF,iBAAA;;;AC5BD;;AAEG;;;;"}
|
|
@@ -0,0 +1,330 @@
|
|
|
1
|
+
import * as i0 from '@angular/core';
|
|
2
|
+
import { inject, ChangeDetectorRef, Pipe, input, output, computed, Component, model, signal } from '@angular/core';
|
|
3
|
+
import { CommonModule } from '@angular/common';
|
|
4
|
+
import { Button } from '@masterteam/components/button';
|
|
5
|
+
import { distinctUntilChanged, filter, switchMap, map, catchError, finalize, tap } from 'rxjs/operators';
|
|
6
|
+
import { DomSanitizer } from '@angular/platform-browser';
|
|
7
|
+
import { Subscription, BehaviorSubject, of, finalize as finalize$1, catchError as catchError$1, throwError, take } from 'rxjs';
|
|
8
|
+
import { HttpClient } from '@angular/common/http';
|
|
9
|
+
import { Icon } from '@masterteam/icons';
|
|
10
|
+
import { FormsModule, Validators, NgControl } from '@angular/forms';
|
|
11
|
+
import { ImageModule } from 'primeng/image';
|
|
12
|
+
import { FieldValidation } from '@masterteam/components/field-validation';
|
|
13
|
+
|
|
14
|
+
class SecureImagePipe {
|
|
15
|
+
httpClient = inject(HttpClient);
|
|
16
|
+
domSanitizer = inject(DomSanitizer);
|
|
17
|
+
cdr = inject(ChangeDetectorRef);
|
|
18
|
+
constructor() {
|
|
19
|
+
this.setUpSubscription();
|
|
20
|
+
}
|
|
21
|
+
ngOnDestroy() {
|
|
22
|
+
this.subscription.unsubscribe();
|
|
23
|
+
}
|
|
24
|
+
subscription = new Subscription();
|
|
25
|
+
loadingImagePath = './assets/images/loading-img.jpg';
|
|
26
|
+
errorImagePath = './assets/images/default-img.png';
|
|
27
|
+
latestValue;
|
|
28
|
+
transformValue = new BehaviorSubject('');
|
|
29
|
+
loading = true;
|
|
30
|
+
transform(imagePath, noDefault, loadingImagePath, errorImagePath) {
|
|
31
|
+
this.loadingImagePath = loadingImagePath ?? this.loadingImagePath;
|
|
32
|
+
this.errorImagePath = noDefault
|
|
33
|
+
? ''
|
|
34
|
+
: (errorImagePath ?? this.errorImagePath);
|
|
35
|
+
this.transformValue.next(imagePath);
|
|
36
|
+
// return (this.latestValue as string) || this.loadingImagePath;
|
|
37
|
+
return this.loading ? this.loadingImagePath : this.latestValue;
|
|
38
|
+
}
|
|
39
|
+
setUpSubscription() {
|
|
40
|
+
const transformSubscription = this.transformValue
|
|
41
|
+
.asObservable()
|
|
42
|
+
.pipe(distinctUntilChanged(), filter((v) => !!v && !v.includes('null')), switchMap((imagePath) => {
|
|
43
|
+
this.latestValue = '';
|
|
44
|
+
return this.httpClient
|
|
45
|
+
.get(imagePath, {
|
|
46
|
+
observe: 'response',
|
|
47
|
+
responseType: 'blob',
|
|
48
|
+
})
|
|
49
|
+
.pipe(map((response) => URL.createObjectURL(response.body)), map((unsafeBlobUrl) => this.domSanitizer.bypassSecurityTrustUrl(unsafeBlobUrl)), filter((blobUrl) => blobUrl !== this.latestValue), catchError(() => of(this.errorImagePath)), finalize(() => (this.loading = false)));
|
|
50
|
+
}), tap((imagePath) => {
|
|
51
|
+
this.latestValue = imagePath;
|
|
52
|
+
this.cdr.markForCheck();
|
|
53
|
+
}))
|
|
54
|
+
.subscribe();
|
|
55
|
+
this.subscription.add(transformSubscription);
|
|
56
|
+
}
|
|
57
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: SecureImagePipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
|
|
58
|
+
static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "20.1.3", ngImport: i0, type: SecureImagePipe, isStandalone: true, name: "secureImage", pure: false });
|
|
59
|
+
}
|
|
60
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: SecureImagePipe, decorators: [{
|
|
61
|
+
type: Pipe,
|
|
62
|
+
args: [{
|
|
63
|
+
name: 'secureImage',
|
|
64
|
+
pure: false,
|
|
65
|
+
standalone: true,
|
|
66
|
+
}]
|
|
67
|
+
}], ctorParameters: () => [] });
|
|
68
|
+
|
|
69
|
+
class UploadFilePreview {
|
|
70
|
+
value = input(null, ...(ngDevMode ? [{ debugName: "value" }] : []));
|
|
71
|
+
imgPath = input(...(ngDevMode ? [undefined, { debugName: "imgPath" }] : []));
|
|
72
|
+
loading = input(false, ...(ngDevMode ? [{ debugName: "loading" }] : []));
|
|
73
|
+
uploadProgress = input(0, ...(ngDevMode ? [{ debugName: "uploadProgress" }] : []));
|
|
74
|
+
onUploadInputClicked = output();
|
|
75
|
+
ondDownloadFile = output();
|
|
76
|
+
onDeleteFile = output();
|
|
77
|
+
disabled = input(false, ...(ngDevMode ? [{ debugName: "disabled" }] : []));
|
|
78
|
+
size = input(...(ngDevMode ? [undefined, { debugName: "size" }] : []));
|
|
79
|
+
isImag = computed(() => {
|
|
80
|
+
return this.value()?.fileType?.startsWith('image/');
|
|
81
|
+
}, ...(ngDevMode ? [{ debugName: "isImag" }] : []));
|
|
82
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: UploadFilePreview, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
83
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.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 }, 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 }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { onUploadInputClicked: "onUploadInputClicked", ondDownloadFile: "ondDownloadFile", onDeleteFile: "onDeleteFile" }, ngImport: i0, template: "<div class=\"flex items-center justify-between gap-2 w-full p-2\">\n <div class=\"flex gap-2 items-center\">\n <img\n [src]=\"\n isImag()\n ? imgPath()\n ? (imgPath() | secureImage)\n : './assets/images/default-img.png'\n : './assets/images/default-img.png'\n \"\n alt=\"image\"\n width=\"40\"\n height=\"40\"\n class=\"rounded-sm\"\n />\n <div class=\"w-[1/3]\">\n {{ value().name }}\n </div>\n </div>\n <div class=\"flex items-center justify-center\">\n @if (!disabled() && !!value() && !loading()) {\n <mt-button\n variant=\"text\"\n icon=\"general.download-01\"\n tooltip=\"Download\"\n (onClick)=\"ondDownloadFile.emit(value())\"\n (click)=\"$event.stopPropagation()\"\n >\n </mt-button>\n <mt-button\n variant=\"text\"\n icon=\"general.trash-01\"\n tooltip=\"Delete\"\n severity=\"danger\"\n (onClick)=\"onDeleteFile.emit(true)\"\n (click)=\"$event.stopPropagation()\"\n >\n </mt-button>\n }\n </div>\n</div>\n", styles: [""], dependencies: [{ kind: "ngmodule", type: CommonModule }, { 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: "pipe", type: SecureImagePipe, name: "secureImage" }] });
|
|
84
|
+
}
|
|
85
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: UploadFilePreview, decorators: [{
|
|
86
|
+
type: Component,
|
|
87
|
+
args: [{ selector: 'mt-upload-file-preview', standalone: true, imports: [CommonModule, SecureImagePipe, Button], template: "<div class=\"flex items-center justify-between gap-2 w-full p-2\">\n <div class=\"flex gap-2 items-center\">\n <img\n [src]=\"\n isImag()\n ? imgPath()\n ? (imgPath() | secureImage)\n : './assets/images/default-img.png'\n : './assets/images/default-img.png'\n \"\n alt=\"image\"\n width=\"40\"\n height=\"40\"\n class=\"rounded-sm\"\n />\n <div class=\"w-[1/3]\">\n {{ value().name }}\n </div>\n </div>\n <div class=\"flex items-center justify-center\">\n @if (!disabled() && !!value() && !loading()) {\n <mt-button\n variant=\"text\"\n icon=\"general.download-01\"\n tooltip=\"Download\"\n (onClick)=\"ondDownloadFile.emit(value())\"\n (click)=\"$event.stopPropagation()\"\n >\n </mt-button>\n <mt-button\n variant=\"text\"\n icon=\"general.trash-01\"\n tooltip=\"Delete\"\n severity=\"danger\"\n (onClick)=\"onDeleteFile.emit(true)\"\n (click)=\"$event.stopPropagation()\"\n >\n </mt-button>\n }\n </div>\n</div>\n" }]
|
|
88
|
+
}] });
|
|
89
|
+
|
|
90
|
+
class UploadUserPreview {
|
|
91
|
+
value = input(null, ...(ngDevMode ? [{ debugName: "value" }] : []));
|
|
92
|
+
imgPath = input(...(ngDevMode ? [undefined, { debugName: "imgPath" }] : []));
|
|
93
|
+
loading = input(false, ...(ngDevMode ? [{ debugName: "loading" }] : []));
|
|
94
|
+
uploadProgress = input(0, ...(ngDevMode ? [{ debugName: "uploadProgress" }] : []));
|
|
95
|
+
isDragging = input(false, ...(ngDevMode ? [{ debugName: "isDragging" }] : []));
|
|
96
|
+
onUploadInputClicked = output();
|
|
97
|
+
ondDownloadFile = output();
|
|
98
|
+
onDeleteFile = output();
|
|
99
|
+
onDragOver = output();
|
|
100
|
+
onDragLeave = output();
|
|
101
|
+
onDrop = output();
|
|
102
|
+
disabled = input(false, ...(ngDevMode ? [{ debugName: "disabled" }] : []));
|
|
103
|
+
size = input(...(ngDevMode ? [undefined, { debugName: "size" }] : []));
|
|
104
|
+
OnUploadInputClicked() {
|
|
105
|
+
if (!this.imgPath() && !this.loading() && !this.disabled()) {
|
|
106
|
+
this.onUploadInputClicked.emit(true);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
OnDragOver(event) {
|
|
110
|
+
this.onDragOver.emit(event);
|
|
111
|
+
}
|
|
112
|
+
OnDragLeave(event) {
|
|
113
|
+
this.onDragLeave.emit(event);
|
|
114
|
+
}
|
|
115
|
+
OnDrop(event) {
|
|
116
|
+
this.onDrop.emit(event);
|
|
117
|
+
}
|
|
118
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: UploadUserPreview, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
119
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.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 }, 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 }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { onUploadInputClicked: "onUploadInputClicked", ondDownloadFile: "ondDownloadFile", onDeleteFile: "onDeleteFile", onDragOver: "onDragOver", onDragLeave: "onDragLeave", onDrop: "onDrop" }, ngImport: i0, template: "<div\n class=\"rounded-full p-1 w-fit\"\n [style.background]=\"\n 'conic-gradient(var(--p-primary-300) ' +\n uploadProgress() +\n '%, transparent ' +\n uploadProgress() +\n '%)'\n \"\n>\n <div class=\"relative rounded-full w-fit\" [class.opacity-50]=\"isDragging()\">\n <img\n [src]=\"\n imgPath()\n ? (imgPath() | secureImage)\n : './assets/images/default-img.png'\n \"\n alt=\"image\"\n [width]=\"size()\"\n [height]=\"size()\"\n class=\"rounded-full\"\n />\n\n @if (!loading()) {\n <div\n class=\"absolute inset-0 flex items-center justify-center rounded-full bg-surface-400/50 opacity-0 hover:opacity-100 transition-opacity\"\n [class]=\"!imgPath() && !disabled() ? 'cursor-pointer' : ''\"\n (click)=\"OnUploadInputClicked()\"\n (dragover)=\"OnDragOver($event)\"\n (dragleave)=\"OnDragLeave($event)\"\n (drop)=\"OnDrop($event)\"\n >\n @if (!disabled() && !!imgPath()) {\n <mt-button\n variant=\"text\"\n icon=\"general.download-01\"\n tooltip=\"Download\"\n (onClick)=\"ondDownloadFile.emit(value())\"\n >\n </mt-button>\n <mt-button\n variant=\"text\"\n icon=\"general.trash-01\"\n tooltip=\"Delete\"\n severity=\"danger\"\n (onClick)=\"onDeleteFile.emit(true)\"\n >\n </mt-button>\n }\n @if (!imgPath() && !disabled()) {\n <mt-icon\n icon=\"general.upload-01\"\n class=\"text-primary-400 text-xl\"\n ></mt-icon>\n }\n </div>\n } @else if (loading()) {\n <div\n class=\"absolute inset-0 flex items-center justify-center rounded-full bg-surface-400/50\"\n >\n @if (uploadProgress() === 100) {\n <mt-icon\n icon=\"general.check\"\n class=\"text-primary-400 text-2xl\"\n ></mt-icon>\n } @else {\n <small class=\"text-primary-300 font-bold\">{{\n uploadProgress() + \"%\"\n }}</small>\n }\n </div>\n }\n </div>\n</div>\n", styles: [""], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { 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: "pipe", type: SecureImagePipe, name: "secureImage" }] });
|
|
120
|
+
}
|
|
121
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: UploadUserPreview, decorators: [{
|
|
122
|
+
type: Component,
|
|
123
|
+
args: [{ selector: 'mt-upload-user-preview', standalone: true, imports: [CommonModule, FormsModule, Icon, SecureImagePipe, Button, Icon], template: "<div\n class=\"rounded-full p-1 w-fit\"\n [style.background]=\"\n 'conic-gradient(var(--p-primary-300) ' +\n uploadProgress() +\n '%, transparent ' +\n uploadProgress() +\n '%)'\n \"\n>\n <div class=\"relative rounded-full w-fit\" [class.opacity-50]=\"isDragging()\">\n <img\n [src]=\"\n imgPath()\n ? (imgPath() | secureImage)\n : './assets/images/default-img.png'\n \"\n alt=\"image\"\n [width]=\"size()\"\n [height]=\"size()\"\n class=\"rounded-full\"\n />\n\n @if (!loading()) {\n <div\n class=\"absolute inset-0 flex items-center justify-center rounded-full bg-surface-400/50 opacity-0 hover:opacity-100 transition-opacity\"\n [class]=\"!imgPath() && !disabled() ? 'cursor-pointer' : ''\"\n (click)=\"OnUploadInputClicked()\"\n (dragover)=\"OnDragOver($event)\"\n (dragleave)=\"OnDragLeave($event)\"\n (drop)=\"OnDrop($event)\"\n >\n @if (!disabled() && !!imgPath()) {\n <mt-button\n variant=\"text\"\n icon=\"general.download-01\"\n tooltip=\"Download\"\n (onClick)=\"ondDownloadFile.emit(value())\"\n >\n </mt-button>\n <mt-button\n variant=\"text\"\n icon=\"general.trash-01\"\n tooltip=\"Delete\"\n severity=\"danger\"\n (onClick)=\"onDeleteFile.emit(true)\"\n >\n </mt-button>\n }\n @if (!imgPath() && !disabled()) {\n <mt-icon\n icon=\"general.upload-01\"\n class=\"text-primary-400 text-xl\"\n ></mt-icon>\n }\n </div>\n } @else if (loading()) {\n <div\n class=\"absolute inset-0 flex items-center justify-center rounded-full bg-surface-400/50\"\n >\n @if (uploadProgress() === 100) {\n <mt-icon\n icon=\"general.check\"\n class=\"text-primary-400 text-2xl\"\n ></mt-icon>\n } @else {\n <small class=\"text-primary-300 font-bold\">{{\n uploadProgress() + \"%\"\n }}</small>\n }\n </div>\n }\n </div>\n</div>\n" }]
|
|
124
|
+
}] });
|
|
125
|
+
|
|
126
|
+
class UploadField {
|
|
127
|
+
label = input(...(ngDevMode ? [undefined, { debugName: "label" }] : []));
|
|
128
|
+
endPoint = input('uploader', ...(ngDevMode ? [{ debugName: "endPoint" }] : []));
|
|
129
|
+
size = input('100', ...(ngDevMode ? [{ debugName: "size" }] : []));
|
|
130
|
+
isUserField = input(false, ...(ngDevMode ? [{ debugName: "isUserField" }] : []));
|
|
131
|
+
accept = input('.pdf,.doc,.docx,image/*', ...(ngDevMode ? [{ debugName: "accept" }] : []));
|
|
132
|
+
isDragging = model(false, ...(ngDevMode ? [{ debugName: "isDragging" }] : []));
|
|
133
|
+
fileSizeLimit = input(...(ngDevMode ? [undefined, { debugName: "fileSizeLimit" }] : []));
|
|
134
|
+
onChange = output();
|
|
135
|
+
requiredValidator = Validators.required;
|
|
136
|
+
value = signal(null, ...(ngDevMode ? [{ debugName: "value" }] : []));
|
|
137
|
+
disabled = signal(false, ...(ngDevMode ? [{ debugName: "disabled" }] : []));
|
|
138
|
+
uploadProgress = signal(0, ...(ngDevMode ? [{ debugName: "uploadProgress" }] : []));
|
|
139
|
+
httpClient = inject(HttpClient);
|
|
140
|
+
loading = signal(false, ...(ngDevMode ? [{ debugName: "loading" }] : []));
|
|
141
|
+
onTouched = () => { };
|
|
142
|
+
onModelChange = () => { };
|
|
143
|
+
ngControl = inject(NgControl, { self: true });
|
|
144
|
+
imgPath = computed(() => {
|
|
145
|
+
if (this.value()?.fileName) {
|
|
146
|
+
return this.value()?.fileName
|
|
147
|
+
? this.endPoint() + '/' + this.value().fileName
|
|
148
|
+
: '';
|
|
149
|
+
}
|
|
150
|
+
else {
|
|
151
|
+
return undefined;
|
|
152
|
+
}
|
|
153
|
+
}, ...(ngDevMode ? [{ debugName: "imgPath" }] : []));
|
|
154
|
+
constructor() {
|
|
155
|
+
if (this.ngControl) {
|
|
156
|
+
this.ngControl.valueAccessor = this;
|
|
157
|
+
setTimeout(() => {
|
|
158
|
+
console.log('this.ngControl', this.size());
|
|
159
|
+
}, 3000);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
writeValue(value) {
|
|
163
|
+
this.value.set(value);
|
|
164
|
+
}
|
|
165
|
+
registerOnChange(fn) {
|
|
166
|
+
this.onModelChange = fn;
|
|
167
|
+
}
|
|
168
|
+
registerOnTouched(fn) {
|
|
169
|
+
this.onTouched = fn;
|
|
170
|
+
}
|
|
171
|
+
setDisabledState(disabled) {
|
|
172
|
+
this.disabled.set(disabled);
|
|
173
|
+
}
|
|
174
|
+
onAdd(item) {
|
|
175
|
+
console.log('onAdd', item);
|
|
176
|
+
if (!this.disabled()) {
|
|
177
|
+
this.value.set(item);
|
|
178
|
+
this.onModelChange(this.value() ?? null);
|
|
179
|
+
this.onChange.emit(this.value());
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
onDelete() {
|
|
183
|
+
if (!this.disabled()) {
|
|
184
|
+
console.log('onDelete');
|
|
185
|
+
this.value.set(null);
|
|
186
|
+
this.onModelChange(this.value() ?? null);
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
onFileSelect(event) {
|
|
190
|
+
console.log('event', event);
|
|
191
|
+
if (event.target.files.length) {
|
|
192
|
+
this.value.set(null);
|
|
193
|
+
const files = event.target.files;
|
|
194
|
+
this.prepareImage(files);
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
prepareImage(files) {
|
|
198
|
+
this.ngControl.control?.setErrors({ uploading: true });
|
|
199
|
+
if (files.length) {
|
|
200
|
+
if (this.isUserField() && !files[0]?.type.startsWith('image/')) {
|
|
201
|
+
this.ngControl.control?.setErrors({ invalidFileType: true });
|
|
202
|
+
return;
|
|
203
|
+
}
|
|
204
|
+
this.uploadFile(files[0]);
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
uploadFile(file) {
|
|
208
|
+
this.loading.set(true);
|
|
209
|
+
this.uploadProgress.set(10);
|
|
210
|
+
const formData = new FormData();
|
|
211
|
+
formData.append('file', file);
|
|
212
|
+
this.httpClient
|
|
213
|
+
.post(this.endPoint(), formData, {
|
|
214
|
+
// 1. Crucial options to report upload progress
|
|
215
|
+
reportProgress: true,
|
|
216
|
+
observe: 'events',
|
|
217
|
+
})
|
|
218
|
+
.pipe(finalize$1(() => {
|
|
219
|
+
setTimeout(() => {
|
|
220
|
+
this.uploadProgress.set(0);
|
|
221
|
+
this.loading.set(false);
|
|
222
|
+
}, 1000);
|
|
223
|
+
}), catchError$1(() => {
|
|
224
|
+
this.uploadProgress.set(0); // Reset on error
|
|
225
|
+
return throwError(() => new Error('Upload failed'));
|
|
226
|
+
}))
|
|
227
|
+
.subscribe((event) => {
|
|
228
|
+
console.log('event', event);
|
|
229
|
+
if (!event?.body) {
|
|
230
|
+
if (event.total) {
|
|
231
|
+
const percentDone = Math.round((100 * event.loaded) / event.total);
|
|
232
|
+
this.uploadProgress.set(percentDone);
|
|
233
|
+
console.log(`Upload Progress: ${percentDone}%`);
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
else {
|
|
237
|
+
this.uploadProgress.set(100);
|
|
238
|
+
this.handleUploadDone({ ...event.body?.data, size: file.size });
|
|
239
|
+
console.log('Upload Complete', event.body);
|
|
240
|
+
}
|
|
241
|
+
});
|
|
242
|
+
}
|
|
243
|
+
handleUploadDone(file) {
|
|
244
|
+
if (file) {
|
|
245
|
+
this.onAdd(file);
|
|
246
|
+
if (this.fileSizeLimit() && file.size > this.fileSizeLimit()) {
|
|
247
|
+
this.ngControl.control?.setErrors({ fileSizeLimited: true });
|
|
248
|
+
}
|
|
249
|
+
else {
|
|
250
|
+
this.ngControl.control?.setErrors(null);
|
|
251
|
+
}
|
|
252
|
+
console.log('this.ngControl.control', this.ngControl.control);
|
|
253
|
+
}
|
|
254
|
+
console.log('handleUploadDone', this.value());
|
|
255
|
+
}
|
|
256
|
+
downloadFile(value) {
|
|
257
|
+
const downloadFileName = value?.name;
|
|
258
|
+
const mimeType = value?.contentType;
|
|
259
|
+
const storedFileName = value?.fileName;
|
|
260
|
+
if (!storedFileName || !mimeType || !downloadFileName) {
|
|
261
|
+
console.error('File metadata is incomplete. Cannot download.');
|
|
262
|
+
return;
|
|
263
|
+
}
|
|
264
|
+
this.httpClient
|
|
265
|
+
.get(this.imgPath(), {
|
|
266
|
+
responseType: 'blob',
|
|
267
|
+
})
|
|
268
|
+
.pipe(take(1))
|
|
269
|
+
.subscribe((res) => {
|
|
270
|
+
const blob = new Blob([res], { type: mimeType });
|
|
271
|
+
const data = window.URL.createObjectURL(blob);
|
|
272
|
+
const link = document.createElement('a');
|
|
273
|
+
link.href = data;
|
|
274
|
+
link.download = downloadFileName;
|
|
275
|
+
link.click();
|
|
276
|
+
window.URL.revokeObjectURL(data);
|
|
277
|
+
});
|
|
278
|
+
}
|
|
279
|
+
onDragOver(event) {
|
|
280
|
+
event.preventDefault();
|
|
281
|
+
event.stopPropagation();
|
|
282
|
+
if (!this.disabled()) {
|
|
283
|
+
this.isDragging.set(true);
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
onDragLeave(event) {
|
|
287
|
+
event.preventDefault();
|
|
288
|
+
event.stopPropagation();
|
|
289
|
+
this.isDragging.set(false);
|
|
290
|
+
}
|
|
291
|
+
onDrop(event) {
|
|
292
|
+
event.preventDefault();
|
|
293
|
+
event.stopPropagation();
|
|
294
|
+
this.isDragging.set(false);
|
|
295
|
+
if (this.disabled()) {
|
|
296
|
+
return;
|
|
297
|
+
}
|
|
298
|
+
const files = event.dataTransfer?.files;
|
|
299
|
+
if (files && files.length > 0) {
|
|
300
|
+
const fileEvent = {
|
|
301
|
+
target: {
|
|
302
|
+
files: files,
|
|
303
|
+
},
|
|
304
|
+
};
|
|
305
|
+
this.onFileSelect(fileEvent);
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: UploadField, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
309
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.3", type: UploadField, isStandalone: true, selector: "mt-upload-field", inputs: { label: { classPropertyName: "label", publicName: "label", 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 }, isUserField: { classPropertyName: "isUserField", publicName: "isUserField", 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 } }, outputs: { isDragging: "isDraggingChange", onChange: "onChange" }, ngImport: i0, template: "<input\n #uploadInput\n type=\"file\"\n name=\"file[]\"\n (change)=\"onFileSelect($event)\"\n style=\"display: none\"\n [accept]=\"isUserField() ? 'image/*' : accept()\"\n/>\n\n@if (isUserField()) {\n <div class=\"flex flex-col items-center gap-2 w-full\">\n <div class=\"flex\">\n <div class=\"flex flex-col items-center\">\n <mt-upload-user-preview\n [value]=\"value()\"\n [imgPath]=\"imgPath()\"\n [endPoint]=\"endPoint()\"\n [disabled]=\"disabled()\"\n [loading]=\"loading()\"\n [size]=\"size()\"\n [isDragging]=\"isDragging()\"\n [uploadProgress]=\"uploadProgress()\"\n (onUploadInputClicked)=\"uploadInput.click()\"\n (ondDownloadFile)=\"downloadFile($event)\"\n (onDeleteFile)=\"onDelete()\"\n (onDragOver)=\"onDragOver($event)\"\n (onDragLeave)=\"onDragLeave($event)\"\n (onDrop)=\"onDrop($event)\"\n ></mt-upload-user-preview>\n @if (label()) {\n <label\n [class.required]=\"\n ngControl?.control?.hasValidator(requiredValidator)\n \"\n [for]=\"ngControl?.name || label()\"\n >{{ label() }}</label\n >\n }\n </div>\n </div>\n </div>\n} @else {\n <div class=\"flex flex-col items-start gap-2 w-full\">\n @if (label()) {\n <label\n [class.required]=\"ngControl?.control?.hasValidator(requiredValidator)\"\n [for]=\"ngControl?.name || label()\"\n >{{ label() }}</label\n >\n }\n\n <div\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\"\n (click)=\"uploadInput.click()\"\n [class.border-blue-500]=\"isDragging()\"\n [class.bg-blue-50]=\"isDragging()\"\n (dragover)=\"onDragOver($event)\"\n (dragleave)=\"onDragLeave($event)\"\n (drop)=\"onDrop($event)\"\n >\n @if (value()) {\n <mt-upload-file-preview\n style=\"width: 100%\"\n [value]=\"value()\"\n [imgPath]=\"imgPath()\"\n [endPoint]=\"endPoint()\"\n [disabled]=\"disabled()\"\n [loading]=\"loading()\"\n [uploadProgress]=\"uploadProgress()\"\n (onUploadInputClicked)=\"uploadInput.click()\"\n (ondDownloadFile)=\"downloadFile($event)\"\n (onDeleteFile)=\"onDelete()\"\n />\n } @else {\n @if (loading()) {\n <div class=\"w-full flex gap-3 items-center justify-center p-3\">\n <p class=\"text-lg text-gray-500\">\n {{ \"Uploading...\" + uploadProgress() + \"%\" }}\n </p>\n </div>\n } @else {\n <div class=\"w-full flex gap-3 items-center justify-center p-3\">\n <mt-icon icon=\"general.upload-01\" />\n <p class=\"text-lg text-gray-500\">Click or drop a file to upload</p>\n </div>\n }\n }\n </div>\n </div>\n}\n<mt-field-validation [control]=\"ngControl?.control\"></mt-field-validation>\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "ngmodule", type: ImageModule }, { kind: "component", type: Icon, selector: "mt-icon", inputs: ["icon"] }, { kind: "component", type: UploadUserPreview, selector: "mt-upload-user-preview", inputs: ["value", "imgPath", "loading", "uploadProgress", "isDragging", "disabled", "size"], outputs: ["onUploadInputClicked", "ondDownloadFile", "onDeleteFile", "onDragOver", "onDragLeave", "onDrop"] }, { kind: "component", type: UploadFilePreview, selector: "mt-upload-file-preview", inputs: ["value", "imgPath", "loading", "uploadProgress", "disabled", "size"], outputs: ["onUploadInputClicked", "ondDownloadFile", "onDeleteFile"] }, { kind: "component", type: FieldValidation, selector: "mt-field-validation", inputs: ["control", "touched"] }] });
|
|
310
|
+
}
|
|
311
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: UploadField, decorators: [{
|
|
312
|
+
type: Component,
|
|
313
|
+
args: [{ selector: 'mt-upload-field', standalone: true, imports: [
|
|
314
|
+
CommonModule,
|
|
315
|
+
FormsModule,
|
|
316
|
+
FormsModule,
|
|
317
|
+
ImageModule,
|
|
318
|
+
Icon,
|
|
319
|
+
UploadUserPreview,
|
|
320
|
+
UploadFilePreview,
|
|
321
|
+
FieldValidation,
|
|
322
|
+
], template: "<input\n #uploadInput\n type=\"file\"\n name=\"file[]\"\n (change)=\"onFileSelect($event)\"\n style=\"display: none\"\n [accept]=\"isUserField() ? 'image/*' : accept()\"\n/>\n\n@if (isUserField()) {\n <div class=\"flex flex-col items-center gap-2 w-full\">\n <div class=\"flex\">\n <div class=\"flex flex-col items-center\">\n <mt-upload-user-preview\n [value]=\"value()\"\n [imgPath]=\"imgPath()\"\n [endPoint]=\"endPoint()\"\n [disabled]=\"disabled()\"\n [loading]=\"loading()\"\n [size]=\"size()\"\n [isDragging]=\"isDragging()\"\n [uploadProgress]=\"uploadProgress()\"\n (onUploadInputClicked)=\"uploadInput.click()\"\n (ondDownloadFile)=\"downloadFile($event)\"\n (onDeleteFile)=\"onDelete()\"\n (onDragOver)=\"onDragOver($event)\"\n (onDragLeave)=\"onDragLeave($event)\"\n (onDrop)=\"onDrop($event)\"\n ></mt-upload-user-preview>\n @if (label()) {\n <label\n [class.required]=\"\n ngControl?.control?.hasValidator(requiredValidator)\n \"\n [for]=\"ngControl?.name || label()\"\n >{{ label() }}</label\n >\n }\n </div>\n </div>\n </div>\n} @else {\n <div class=\"flex flex-col items-start gap-2 w-full\">\n @if (label()) {\n <label\n [class.required]=\"ngControl?.control?.hasValidator(requiredValidator)\"\n [for]=\"ngControl?.name || label()\"\n >{{ label() }}</label\n >\n }\n\n <div\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\"\n (click)=\"uploadInput.click()\"\n [class.border-blue-500]=\"isDragging()\"\n [class.bg-blue-50]=\"isDragging()\"\n (dragover)=\"onDragOver($event)\"\n (dragleave)=\"onDragLeave($event)\"\n (drop)=\"onDrop($event)\"\n >\n @if (value()) {\n <mt-upload-file-preview\n style=\"width: 100%\"\n [value]=\"value()\"\n [imgPath]=\"imgPath()\"\n [endPoint]=\"endPoint()\"\n [disabled]=\"disabled()\"\n [loading]=\"loading()\"\n [uploadProgress]=\"uploadProgress()\"\n (onUploadInputClicked)=\"uploadInput.click()\"\n (ondDownloadFile)=\"downloadFile($event)\"\n (onDeleteFile)=\"onDelete()\"\n />\n } @else {\n @if (loading()) {\n <div class=\"w-full flex gap-3 items-center justify-center p-3\">\n <p class=\"text-lg text-gray-500\">\n {{ \"Uploading...\" + uploadProgress() + \"%\" }}\n </p>\n </div>\n } @else {\n <div class=\"w-full flex gap-3 items-center justify-center p-3\">\n <mt-icon icon=\"general.upload-01\" />\n <p class=\"text-lg text-gray-500\">Click or drop a file to upload</p>\n </div>\n }\n }\n </div>\n </div>\n}\n<mt-field-validation [control]=\"ngControl?.control\"></mt-field-validation>\n" }]
|
|
323
|
+
}], ctorParameters: () => [] });
|
|
324
|
+
|
|
325
|
+
/**
|
|
326
|
+
* Generated bundle index. Do not edit.
|
|
327
|
+
*/
|
|
328
|
+
|
|
329
|
+
export { UploadField };
|
|
330
|
+
//# sourceMappingURL=masterteam-components-upload-field.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"masterteam-components-upload-field.mjs","sources":["../../../../packages/masterteam/components/upload-field/secure-image.pipe.ts","../../../../packages/masterteam/components/upload-field/upload-file-preview/upload-file-preview.ts","../../../../packages/masterteam/components/upload-field/upload-file-preview/upload-file-preview.html","../../../../packages/masterteam/components/upload-field/upload-user-preview/upload-user-preview.ts","../../../../packages/masterteam/components/upload-field/upload-user-preview/upload-user-preview.html","../../../../packages/masterteam/components/upload-field/upload-field.ts","../../../../packages/masterteam/components/upload-field/upload-field.html","../../../../packages/masterteam/components/upload-field/masterteam-components-upload-field.ts"],"sourcesContent":["import {\n filter,\n switchMap,\n map,\n catchError,\n tap,\n distinctUntilChanged,\n finalize,\n} from 'rxjs/operators';\nimport { DomSanitizer, SafeUrl } from '@angular/platform-browser';\nimport { Subscription, BehaviorSubject, of } from 'rxjs';\nimport {\n Pipe,\n PipeTransform,\n OnDestroy,\n ChangeDetectorRef,\n inject,\n} from '@angular/core';\nimport { HttpClient, HttpResponse } from '@angular/common/http';\n@Pipe({\n name: 'secureImage',\n pure: false,\n standalone: true,\n})\nexport class SecureImagePipe implements PipeTransform, OnDestroy {\n httpClient = inject(HttpClient);\n domSanitizer = inject(DomSanitizer);\n cdr = inject(ChangeDetectorRef);\n constructor() {\n this.setUpSubscription();\n }\n ngOnDestroy(): void {\n this.subscription.unsubscribe();\n }\n private subscription = new Subscription();\n private loadingImagePath: string = './assets/images/loading-img.jpg';\n private errorImagePath: string = './assets/images/default-img.png';\n private latestValue!: string | SafeUrl;\n private transformValue = new BehaviorSubject<string>('');\n private loading = true;\n\n transform(\n imagePath: string,\n noDefault?: boolean,\n loadingImagePath?: string,\n errorImagePath?: string,\n ): string {\n this.loadingImagePath = loadingImagePath ?? this.loadingImagePath;\n this.errorImagePath = noDefault\n ? ''\n : (errorImagePath ?? this.errorImagePath);\n\n this.transformValue.next(imagePath);\n // return (this.latestValue as string) || this.loadingImagePath;\n return this.loading ? this.loadingImagePath : (this.latestValue as string);\n }\n\n private setUpSubscription(): void {\n const transformSubscription = this.transformValue\n .asObservable()\n .pipe(\n distinctUntilChanged(),\n filter((v): v is string => !!v && !v.includes('null')),\n switchMap((imagePath: string) => {\n this.latestValue = '';\n return this.httpClient\n .get(imagePath, {\n observe: 'response',\n responseType: 'blob',\n })\n .pipe(\n map((response: HttpResponse<any>) =>\n URL.createObjectURL(response.body),\n ),\n map((unsafeBlobUrl: string) =>\n this.domSanitizer.bypassSecurityTrustUrl(unsafeBlobUrl),\n ),\n filter((blobUrl) => blobUrl !== this.latestValue),\n catchError(() => of(this.errorImagePath)),\n finalize(() => (this.loading = false)),\n );\n }),\n tap((imagePath: string | SafeUrl) => {\n this.latestValue = imagePath;\n this.cdr.markForCheck();\n }),\n )\n .subscribe();\n this.subscription.add(transformSubscription);\n }\n}\n","import { Component, computed, input, output } from '@angular/core';\nimport { CommonModule } from '@angular/common';\nimport { Button } from '@masterteam/components/button';\nimport { SecureImagePipe } from '../secure-image.pipe';\n\n@Component({\n selector: 'mt-upload-file-preview',\n standalone: true,\n imports: [CommonModule, SecureImagePipe, Button],\n templateUrl: './upload-file-preview.html',\n styleUrl: './upload-file-preview.scss',\n})\nexport class UploadFilePreview {\n value = input<any | null>(null);\n imgPath = input<any | undefined>();\n loading = input<boolean>(false);\n uploadProgress = input<number>(0);\n onUploadInputClicked = output<any>();\n ondDownloadFile = output<any>();\n onDeleteFile = output<any>();\n readonly disabled = input<boolean>(false);\n readonly size = input<string>();\n isImag = computed(() => {\n return this.value()?.fileType?.startsWith('image/');\n });\n}\n","<div class=\"flex items-center justify-between gap-2 w-full p-2\">\n <div class=\"flex gap-2 items-center\">\n <img\n [src]=\"\n isImag()\n ? imgPath()\n ? (imgPath() | secureImage)\n : './assets/images/default-img.png'\n : './assets/images/default-img.png'\n \"\n alt=\"image\"\n width=\"40\"\n height=\"40\"\n class=\"rounded-sm\"\n />\n <div class=\"w-[1/3]\">\n {{ value().name }}\n </div>\n </div>\n <div class=\"flex items-center justify-center\">\n @if (!disabled() && !!value() && !loading()) {\n <mt-button\n variant=\"text\"\n icon=\"general.download-01\"\n tooltip=\"Download\"\n (onClick)=\"ondDownloadFile.emit(value())\"\n (click)=\"$event.stopPropagation()\"\n >\n </mt-button>\n <mt-button\n variant=\"text\"\n icon=\"general.trash-01\"\n tooltip=\"Delete\"\n severity=\"danger\"\n (onClick)=\"onDeleteFile.emit(true)\"\n (click)=\"$event.stopPropagation()\"\n >\n </mt-button>\n }\n </div>\n</div>\n","import { SecureImagePipe } from '../secure-image.pipe';\nimport { Icon } from '@masterteam/icons';\nimport { FormsModule } from '@angular/forms';\nimport { Component, input, output } from '@angular/core';\nimport { CommonModule } from '@angular/common';\nimport { Button } from '@masterteam/components/button';\n\n@Component({\n selector: 'mt-upload-user-preview',\n standalone: true,\n imports: [CommonModule, FormsModule, Icon, SecureImagePipe, Button, Icon],\n templateUrl: './upload-user-preview.html',\n styleUrl: './upload-user-preview.css',\n})\nexport class UploadUserPreview {\n value = input<any | null>(null);\n imgPath = input<any | undefined>();\n loading = input<boolean>(false);\n uploadProgress = input<number>(0);\n isDragging = input<boolean>(false);\n onUploadInputClicked = output<any>();\n ondDownloadFile = output<any>();\n onDeleteFile = output<any>();\n onDragOver = output<any>();\n onDragLeave = output<any>();\n onDrop = output<any>();\n readonly disabled = input<boolean>(false);\n readonly size = input<string>();\n\n OnUploadInputClicked(): void {\n if (!this.imgPath() && !this.loading() && !this.disabled()) {\n this.onUploadInputClicked.emit(true);\n }\n }\n\n OnDragOver(event: DragEvent): void {\n this.onDragOver.emit(event);\n }\n OnDragLeave(event: DragEvent): void {\n this.onDragLeave.emit(event);\n }\n\n OnDrop(event: DragEvent): void {\n this.onDrop.emit(event);\n }\n}\n","<div\n class=\"rounded-full p-1 w-fit\"\n [style.background]=\"\n 'conic-gradient(var(--p-primary-300) ' +\n uploadProgress() +\n '%, transparent ' +\n uploadProgress() +\n '%)'\n \"\n>\n <div class=\"relative rounded-full w-fit\" [class.opacity-50]=\"isDragging()\">\n <img\n [src]=\"\n imgPath()\n ? (imgPath() | secureImage)\n : './assets/images/default-img.png'\n \"\n alt=\"image\"\n [width]=\"size()\"\n [height]=\"size()\"\n class=\"rounded-full\"\n />\n\n @if (!loading()) {\n <div\n class=\"absolute inset-0 flex items-center justify-center rounded-full bg-surface-400/50 opacity-0 hover:opacity-100 transition-opacity\"\n [class]=\"!imgPath() && !disabled() ? 'cursor-pointer' : ''\"\n (click)=\"OnUploadInputClicked()\"\n (dragover)=\"OnDragOver($event)\"\n (dragleave)=\"OnDragLeave($event)\"\n (drop)=\"OnDrop($event)\"\n >\n @if (!disabled() && !!imgPath()) {\n <mt-button\n variant=\"text\"\n icon=\"general.download-01\"\n tooltip=\"Download\"\n (onClick)=\"ondDownloadFile.emit(value())\"\n >\n </mt-button>\n <mt-button\n variant=\"text\"\n icon=\"general.trash-01\"\n tooltip=\"Delete\"\n severity=\"danger\"\n (onClick)=\"onDeleteFile.emit(true)\"\n >\n </mt-button>\n }\n @if (!imgPath() && !disabled()) {\n <mt-icon\n icon=\"general.upload-01\"\n class=\"text-primary-400 text-xl\"\n ></mt-icon>\n }\n </div>\n } @else if (loading()) {\n <div\n class=\"absolute inset-0 flex items-center justify-center rounded-full bg-surface-400/50\"\n >\n @if (uploadProgress() === 100) {\n <mt-icon\n icon=\"general.check\"\n class=\"text-primary-400 text-2xl\"\n ></mt-icon>\n } @else {\n <small class=\"text-primary-300 font-bold\">{{\n uploadProgress() + \"%\"\n }}</small>\n }\n </div>\n }\n </div>\n</div>\n","import { UploadFilePreview } from './upload-file-preview/upload-file-preview';\nimport { UploadUserPreview } from './upload-user-preview/upload-user-preview';\nimport { CommonModule } from '@angular/common';\nimport {\n Component,\n computed,\n inject,\n input,\n model,\n output,\n signal,\n} from '@angular/core';\nimport {\n ControlValueAccessor,\n FormsModule,\n NgControl,\n Validators,\n} from '@angular/forms';\nimport { ImageModule } from 'primeng/image';\nimport { HttpClient } from '@angular/common/http';\nimport { Icon } from '@masterteam/icons';\nimport { catchError, finalize, take, throwError } from 'rxjs';\nimport { FieldValidation } from '@masterteam/components/field-validation';\n\n@Component({\n selector: 'mt-upload-field',\n standalone: true,\n imports: [\n CommonModule,\n FormsModule,\n FormsModule,\n ImageModule,\n Icon,\n UploadUserPreview,\n UploadFilePreview,\n FieldValidation,\n ],\n templateUrl: './upload-field.html',\n})\nexport class UploadField implements ControlValueAccessor {\n readonly label = input<string>();\n readonly endPoint = input<string>('uploader');\n readonly size = input<string>('100');\n readonly isUserField = input<boolean>(false);\n readonly accept = input<string | undefined>('.pdf,.doc,.docx,image/*');\n readonly isDragging = model<boolean>(false);\n readonly fileSizeLimit = input<number | undefined>();\n onChange = output<any>();\n requiredValidator = Validators.required;\n value = signal<any | null>(null);\n disabled = signal<boolean>(false);\n uploadProgress = signal<number>(0);\n httpClient = inject(HttpClient);\n loading = signal<boolean>(false);\n onTouched: () => void = () => {};\n onModelChange: (value: any[]) => void = () => {};\n public ngControl = inject(NgControl, { self: true });\n imgPath = computed(() => {\n if (this.value()?.fileName) {\n return this.value()?.fileName\n ? this.endPoint() + '/' + this.value().fileName\n : '';\n } else {\n return undefined;\n }\n });\n\n constructor() {\n if (this.ngControl) {\n this.ngControl.valueAccessor = this;\n setTimeout(() => {\n console.log('this.ngControl', this.size());\n }, 3000);\n }\n }\n\n writeValue(value: any[]) {\n this.value.set(value);\n }\n\n registerOnChange(fn: any) {\n this.onModelChange = fn;\n }\n\n registerOnTouched(fn: any) {\n this.onTouched = fn;\n }\n\n setDisabledState(disabled: boolean) {\n this.disabled.set(disabled);\n }\n\n onAdd(item: any) {\n console.log('onAdd', item);\n if (!this.disabled()) {\n this.value.set(item);\n this.onModelChange(this.value() ?? null);\n this.onChange.emit(this.value());\n }\n }\n\n onDelete() {\n if (!this.disabled()) {\n console.log('onDelete');\n this.value.set(null);\n this.onModelChange(this.value() ?? null);\n }\n }\n\n onFileSelect(event: any) {\n console.log('event', event);\n if (event.target.files.length) {\n this.value.set(null);\n const files: FileList = event.target.files;\n this.prepareImage(files);\n }\n }\n\n prepareImage(files: FileList) {\n this.ngControl.control?.setErrors({ uploading: true });\n\n if (files.length) {\n if (this.isUserField() && !files[0]?.type.startsWith('image/')) {\n this.ngControl.control?.setErrors({ invalidFileType: true });\n return;\n }\n this.uploadFile(files[0]);\n }\n }\n\n uploadFile(file: File) {\n this.loading.set(true);\n this.uploadProgress.set(10);\n\n const formData = new FormData();\n formData.append('file', file);\n\n this.httpClient\n .post<any>(this.endPoint(), formData, {\n // 1. Crucial options to report upload progress\n reportProgress: true,\n observe: 'events',\n })\n .pipe(\n finalize(() => {\n setTimeout(() => {\n this.uploadProgress.set(0);\n this.loading.set(false);\n }, 1000);\n }),\n catchError(() => {\n this.uploadProgress.set(0); // Reset on error\n return throwError(() => new Error('Upload failed'));\n }),\n )\n .subscribe((event: any) => {\n console.log('event', event);\n\n if (!event?.body) {\n if (event.total) {\n const percentDone = Math.round((100 * event.loaded) / event.total);\n this.uploadProgress.set(percentDone);\n console.log(`Upload Progress: ${percentDone}%`);\n }\n } else {\n this.uploadProgress.set(100);\n this.handleUploadDone({ ...event.body?.data, size: file.size });\n console.log('Upload Complete', event.body);\n }\n });\n }\n\n handleUploadDone(file: any) {\n if (file) {\n this.onAdd(file);\n if (this.fileSizeLimit() && file.size > this.fileSizeLimit()!) {\n this.ngControl.control?.setErrors({ fileSizeLimited: true });\n } else {\n this.ngControl.control?.setErrors(null);\n }\n console.log('this.ngControl.control', this.ngControl.control);\n }\n\n console.log('handleUploadDone', this.value());\n }\n\n downloadFile(value: any) {\n const downloadFileName = value?.name;\n const mimeType = value?.contentType;\n const storedFileName = value?.fileName;\n\n if (!storedFileName || !mimeType || !downloadFileName) {\n console.error('File metadata is incomplete. Cannot download.');\n return;\n }\n\n this.httpClient\n .get(this.imgPath()!, {\n responseType: 'blob',\n })\n .pipe(take(1))\n .subscribe((res: Blob) => {\n const blob = new Blob([res], { type: mimeType });\n\n const data = window.URL.createObjectURL(blob);\n const link = document.createElement('a');\n link.href = data;\n\n link.download = downloadFileName;\n\n link.click();\n\n window.URL.revokeObjectURL(data);\n });\n }\n onDragOver(event: DragEvent): void {\n event.preventDefault();\n event.stopPropagation();\n if (!this.disabled()) {\n this.isDragging.set(true);\n }\n }\n onDragLeave(event: DragEvent): void {\n event.preventDefault();\n event.stopPropagation();\n this.isDragging.set(false);\n }\n\n onDrop(event: DragEvent): void {\n event.preventDefault();\n event.stopPropagation();\n this.isDragging.set(false);\n\n if (this.disabled()) {\n return;\n }\n\n const files = event.dataTransfer?.files;\n if (files && files.length > 0) {\n const fileEvent = {\n target: {\n files: files,\n },\n } as unknown as Event;\n this.onFileSelect(fileEvent);\n }\n }\n}\n","<input\n #uploadInput\n type=\"file\"\n name=\"file[]\"\n (change)=\"onFileSelect($event)\"\n style=\"display: none\"\n [accept]=\"isUserField() ? 'image/*' : accept()\"\n/>\n\n@if (isUserField()) {\n <div class=\"flex flex-col items-center gap-2 w-full\">\n <div class=\"flex\">\n <div class=\"flex flex-col items-center\">\n <mt-upload-user-preview\n [value]=\"value()\"\n [imgPath]=\"imgPath()\"\n [endPoint]=\"endPoint()\"\n [disabled]=\"disabled()\"\n [loading]=\"loading()\"\n [size]=\"size()\"\n [isDragging]=\"isDragging()\"\n [uploadProgress]=\"uploadProgress()\"\n (onUploadInputClicked)=\"uploadInput.click()\"\n (ondDownloadFile)=\"downloadFile($event)\"\n (onDeleteFile)=\"onDelete()\"\n (onDragOver)=\"onDragOver($event)\"\n (onDragLeave)=\"onDragLeave($event)\"\n (onDrop)=\"onDrop($event)\"\n ></mt-upload-user-preview>\n @if (label()) {\n <label\n [class.required]=\"\n ngControl?.control?.hasValidator(requiredValidator)\n \"\n [for]=\"ngControl?.name || label()\"\n >{{ label() }}</label\n >\n }\n </div>\n </div>\n </div>\n} @else {\n <div class=\"flex flex-col items-start gap-2 w-full\">\n @if (label()) {\n <label\n [class.required]=\"ngControl?.control?.hasValidator(requiredValidator)\"\n [for]=\"ngControl?.name || label()\"\n >{{ label() }}</label\n >\n }\n\n <div\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\"\n (click)=\"uploadInput.click()\"\n [class.border-blue-500]=\"isDragging()\"\n [class.bg-blue-50]=\"isDragging()\"\n (dragover)=\"onDragOver($event)\"\n (dragleave)=\"onDragLeave($event)\"\n (drop)=\"onDrop($event)\"\n >\n @if (value()) {\n <mt-upload-file-preview\n style=\"width: 100%\"\n [value]=\"value()\"\n [imgPath]=\"imgPath()\"\n [endPoint]=\"endPoint()\"\n [disabled]=\"disabled()\"\n [loading]=\"loading()\"\n [uploadProgress]=\"uploadProgress()\"\n (onUploadInputClicked)=\"uploadInput.click()\"\n (ondDownloadFile)=\"downloadFile($event)\"\n (onDeleteFile)=\"onDelete()\"\n />\n } @else {\n @if (loading()) {\n <div class=\"w-full flex gap-3 items-center justify-center p-3\">\n <p class=\"text-lg text-gray-500\">\n {{ \"Uploading...\" + uploadProgress() + \"%\" }}\n </p>\n </div>\n } @else {\n <div class=\"w-full flex gap-3 items-center justify-center p-3\">\n <mt-icon icon=\"general.upload-01\" />\n <p class=\"text-lg text-gray-500\">Click or drop a file to upload</p>\n </div>\n }\n }\n </div>\n </div>\n}\n<mt-field-validation [control]=\"ngControl?.control\"></mt-field-validation>\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":["finalize","catchError"],"mappings":"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"}
|
|
@@ -4,12 +4,11 @@ import * as i1 from '@angular/forms';
|
|
|
4
4
|
import { Validators, NgControl, FormsModule } from '@angular/forms';
|
|
5
5
|
import * as i2 from 'primeng/autocomplete';
|
|
6
6
|
import { AutoCompleteModule } from 'primeng/autocomplete';
|
|
7
|
-
import * as
|
|
7
|
+
import * as i4 from 'primeng/inputgroup';
|
|
8
8
|
import { InputGroupModule } from 'primeng/inputgroup';
|
|
9
|
-
import * as
|
|
9
|
+
import * as i5 from 'primeng/inputgroupaddon';
|
|
10
10
|
import { InputGroupAddonModule } from 'primeng/inputgroupaddon';
|
|
11
|
-
import
|
|
12
|
-
import { TooltipModule } from 'primeng/tooltip';
|
|
11
|
+
import { Tooltip } from '@masterteam/components/tooltip';
|
|
13
12
|
import { FieldValidation } from '@masterteam/components/field-validation';
|
|
14
13
|
import { isInvalid } from '@masterteam/components';
|
|
15
14
|
import { Icon } from '@masterteam/icons';
|
|
@@ -114,14 +113,14 @@ class UserSearchField {
|
|
|
114
113
|
this.disabled.set(disabled);
|
|
115
114
|
}
|
|
116
115
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: UserSearchField, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
117
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.3", type: UserSearchField, isStandalone: true, selector: "mt-user-search-field", inputs: { hint: { classPropertyName: "hint", publicName: "hint", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, class: { classPropertyName: "class", publicName: "class", isSignal: true, isRequired: false, transformFunction: null }, readonly: { classPropertyName: "readonly", publicName: "readonly", isSignal: true, isRequired: false, transformFunction: null }, required: { classPropertyName: "required", publicName: "required", isSignal: true, isRequired: false, transformFunction: null }, apiUrl: { classPropertyName: "apiUrl", publicName: "apiUrl", isSignal: true, isRequired: true, transformFunction: null }, dataKey: { classPropertyName: "dataKey", publicName: "dataKey", isSignal: true, isRequired: false, transformFunction: null }, paramName: { classPropertyName: "paramName", publicName: "paramName", isSignal: true, isRequired: false, transformFunction: null }, context: { classPropertyName: "context", publicName: "context", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class": "this.styleClass" }, classAttribute: "grid gap-1" }, ngImport: i0, template: "@if (label()) {\n <label\n [class.required]=\"ngControl?.control?.hasValidator(requiredValidator)\"\n [for]=\"ngControl?.name || label()\"\n >\n {{ label() }}\n </label>\n}\n<div class=\"relative\">\n <p-inputgroup>\n <p-autoComplete\n #autocomplete=\"\"\n [suggestions]=\"filteredUsers()\"\n (completeMethod)=\"search($event)\"\n (onSelect)=\"onSelect($event)\"\n (onClear)=\"onClear()\"\n (onBlur)=\"onTouched()\"\n [ngModel]=\"value()?.displayName\"\n [disabled]=\"disabled() || readonly()\"\n [id]=\"ngControl?.name || label()\"\n [invalid]=\"isInvalid(ngControl?.control)\"\n [placeholder]=\"placeholder()\"\n class=\"w-full\"\n appendTo=\"body\"\n styleClass=\"w-full\"\n [dropdown]=\"false\"\n [size]=\"size()\"\n >\n <ng-template let-user pTemplate=\"item\">\n <div class=\"flex items-center gap-2\">\n <mt-avatar size=\"small\" icon=\"user.user-01\" />\n <div class=\"flex align-items-center gap-3\">\n <span class=\"font-medium\">{{ user.displayName }}</span>\n <medium class=\"text-gray-500\">{{ \"@\" + user.userName }}</medium>\n </div>\n </div>\n </ng-template>\n\n <!-- <ng-template let-user #pTemplate=\"selecteditem\">\n <div class=\"flex items-center gap-2\">\n <mt-avatar size=\"small\" icon=\"user.user-01\" />\n <div class=\"flex align-items-center gap-3\">\n <span class=\"font-medium\">{{ user.displayName }}</span>\n <medium class=\"text-gray-500\">{{ \"@\" + user.userName }}</medium>\n </div>\n </div>\n </ng-template> -->\n </p-autoComplete>\n @if (hint()) {\n <p-inputgroup-addon [
|
|
116
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.3", type: UserSearchField, isStandalone: true, selector: "mt-user-search-field", inputs: { hint: { classPropertyName: "hint", publicName: "hint", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, class: { classPropertyName: "class", publicName: "class", isSignal: true, isRequired: false, transformFunction: null }, readonly: { classPropertyName: "readonly", publicName: "readonly", isSignal: true, isRequired: false, transformFunction: null }, required: { classPropertyName: "required", publicName: "required", isSignal: true, isRequired: false, transformFunction: null }, apiUrl: { classPropertyName: "apiUrl", publicName: "apiUrl", isSignal: true, isRequired: true, transformFunction: null }, dataKey: { classPropertyName: "dataKey", publicName: "dataKey", isSignal: true, isRequired: false, transformFunction: null }, paramName: { classPropertyName: "paramName", publicName: "paramName", isSignal: true, isRequired: false, transformFunction: null }, context: { classPropertyName: "context", publicName: "context", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class": "this.styleClass" }, classAttribute: "grid gap-1" }, ngImport: i0, template: "@if (label()) {\n <label\n [class.required]=\"ngControl?.control?.hasValidator(requiredValidator)\"\n [for]=\"ngControl?.name || label()\"\n >\n {{ label() }}\n </label>\n}\n<div class=\"relative\">\n <p-inputgroup>\n <p-autoComplete\n #autocomplete=\"\"\n [suggestions]=\"filteredUsers()\"\n (completeMethod)=\"search($event)\"\n (onSelect)=\"onSelect($event)\"\n (onClear)=\"onClear()\"\n (onBlur)=\"onTouched()\"\n [ngModel]=\"value()?.displayName\"\n [disabled]=\"disabled() || readonly()\"\n [id]=\"ngControl?.name || label()\"\n [invalid]=\"isInvalid(ngControl?.control)\"\n [placeholder]=\"placeholder()\"\n class=\"w-full\"\n appendTo=\"body\"\n styleClass=\"w-full\"\n [dropdown]=\"false\"\n [size]=\"size()\"\n >\n <ng-template let-user pTemplate=\"item\">\n <div class=\"flex items-center gap-2\">\n <mt-avatar size=\"small\" icon=\"user.user-01\" />\n <div class=\"flex align-items-center gap-3\">\n <span class=\"font-medium\">{{ user.displayName }}</span>\n <medium class=\"text-gray-500\">{{ \"@\" + user.userName }}</medium>\n </div>\n </div>\n </ng-template>\n\n <!-- <ng-template let-user #pTemplate=\"selecteditem\">\n <div class=\"flex items-center gap-2\">\n <mt-avatar size=\"small\" icon=\"user.user-01\" />\n <div class=\"flex align-items-center gap-3\">\n <span class=\"font-medium\">{{ user.displayName }}</span>\n <medium class=\"text-gray-500\">{{ \"@\" + user.userName }}</medium>\n </div>\n </div>\n </ng-template> -->\n </p-autoComplete>\n @if (hint()) {\n <p-inputgroup-addon [mtTooltip]=\"hint()\" tooltipPosition=\"top\">\n <mt-icon icon=\"general.help-circle\" />\n </p-inputgroup-addon>\n } @else {\n <p-inputgroup-addon tooltipPosition=\"top\">\n <mt-icon icon=\"user.user-03\" />\n </p-inputgroup-addon>\n }\n </p-inputgroup>\n\n @if (loading()) {\n <mt-icon\n icon=\"general.loading-01\"\n class=\"animate-spin absolute right-3 bg-white top-1/2 -translate-y-1/2\"\n />\n }\n</div>\n<mt-field-validation [control]=\"ngControl?.control\"></mt-field-validation>\n", styles: [""], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: AutoCompleteModule }, { kind: "component", type: i2.AutoComplete, selector: "p-autoComplete, p-autocomplete, p-auto-complete", inputs: ["minLength", "minQueryLength", "delay", "panelStyle", "styleClass", "panelStyleClass", "inputStyle", "inputId", "inputStyleClass", "placeholder", "readonly", "scrollHeight", "lazy", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "autoHighlight", "forceSelection", "type", "autoZIndex", "baseZIndex", "ariaLabel", "dropdownAriaLabel", "ariaLabelledBy", "dropdownIcon", "unique", "group", "completeOnFocus", "showClear", "dropdown", "showEmptyMessage", "dropdownMode", "multiple", "tabindex", "dataKey", "emptyMessage", "showTransitionOptions", "hideTransitionOptions", "autofocus", "autocomplete", "optionGroupChildren", "optionGroupLabel", "overlayOptions", "suggestions", "optionLabel", "optionValue", "id", "searchMessage", "emptySelectionMessage", "selectionMessage", "autoOptionFocus", "selectOnFocus", "searchLocale", "optionDisabled", "focusOnHover", "typeahead", "appendTo"], outputs: ["completeMethod", "onSelect", "onUnselect", "onFocus", "onBlur", "onDropdownClick", "onClear", "onKeyUp", "onShow", "onHide", "onLazyLoad"] }, { kind: "directive", type: i3.PrimeTemplate, selector: "[pTemplate]", inputs: ["type", "pTemplate"] }, { kind: "directive", type: Tooltip, selector: "[mtTooltip]" }, { kind: "ngmodule", type: InputGroupModule }, { kind: "component", type: i4.InputGroup, selector: "p-inputgroup, p-inputGroup, p-input-group", inputs: ["styleClass"] }, { kind: "ngmodule", type: InputGroupAddonModule }, { kind: "component", type: i5.InputGroupAddon, selector: "p-inputgroup-addon, p-inputGroupAddon", inputs: ["style", "styleClass"] }, { kind: "component", type: FieldValidation, selector: "mt-field-validation", inputs: ["control", "touched"] }, { kind: "component", type: Icon, selector: "mt-icon", inputs: ["icon"] }, { kind: "component", type: Avatar, selector: "mt-avatar", inputs: ["label", "icon", "image", "size", "shape", "badge", "badgeSize", "badgeSeverity"], outputs: ["onImageError"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
118
117
|
}
|
|
119
118
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: UserSearchField, decorators: [{
|
|
120
119
|
type: Component,
|
|
121
120
|
args: [{ selector: 'mt-user-search-field', standalone: true, imports: [
|
|
122
121
|
FormsModule,
|
|
123
122
|
AutoCompleteModule,
|
|
124
|
-
|
|
123
|
+
Tooltip,
|
|
125
124
|
InputGroupModule,
|
|
126
125
|
InputGroupAddonModule,
|
|
127
126
|
FieldValidation,
|
|
@@ -129,7 +128,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.3", ngImpor
|
|
|
129
128
|
Avatar,
|
|
130
129
|
], changeDetection: ChangeDetectionStrategy.OnPush, host: {
|
|
131
130
|
class: 'grid gap-1',
|
|
132
|
-
}, template: "@if (label()) {\n <label\n [class.required]=\"ngControl?.control?.hasValidator(requiredValidator)\"\n [for]=\"ngControl?.name || label()\"\n >\n {{ label() }}\n </label>\n}\n<div class=\"relative\">\n <p-inputgroup>\n <p-autoComplete\n #autocomplete=\"\"\n [suggestions]=\"filteredUsers()\"\n (completeMethod)=\"search($event)\"\n (onSelect)=\"onSelect($event)\"\n (onClear)=\"onClear()\"\n (onBlur)=\"onTouched()\"\n [ngModel]=\"value()?.displayName\"\n [disabled]=\"disabled() || readonly()\"\n [id]=\"ngControl?.name || label()\"\n [invalid]=\"isInvalid(ngControl?.control)\"\n [placeholder]=\"placeholder()\"\n class=\"w-full\"\n appendTo=\"body\"\n styleClass=\"w-full\"\n [dropdown]=\"false\"\n [size]=\"size()\"\n >\n <ng-template let-user pTemplate=\"item\">\n <div class=\"flex items-center gap-2\">\n <mt-avatar size=\"small\" icon=\"user.user-01\" />\n <div class=\"flex align-items-center gap-3\">\n <span class=\"font-medium\">{{ user.displayName }}</span>\n <medium class=\"text-gray-500\">{{ \"@\" + user.userName }}</medium>\n </div>\n </div>\n </ng-template>\n\n <!-- <ng-template let-user #pTemplate=\"selecteditem\">\n <div class=\"flex items-center gap-2\">\n <mt-avatar size=\"small\" icon=\"user.user-01\" />\n <div class=\"flex align-items-center gap-3\">\n <span class=\"font-medium\">{{ user.displayName }}</span>\n <medium class=\"text-gray-500\">{{ \"@\" + user.userName }}</medium>\n </div>\n </div>\n </ng-template> -->\n </p-autoComplete>\n @if (hint()) {\n <p-inputgroup-addon [
|
|
131
|
+
}, template: "@if (label()) {\n <label\n [class.required]=\"ngControl?.control?.hasValidator(requiredValidator)\"\n [for]=\"ngControl?.name || label()\"\n >\n {{ label() }}\n </label>\n}\n<div class=\"relative\">\n <p-inputgroup>\n <p-autoComplete\n #autocomplete=\"\"\n [suggestions]=\"filteredUsers()\"\n (completeMethod)=\"search($event)\"\n (onSelect)=\"onSelect($event)\"\n (onClear)=\"onClear()\"\n (onBlur)=\"onTouched()\"\n [ngModel]=\"value()?.displayName\"\n [disabled]=\"disabled() || readonly()\"\n [id]=\"ngControl?.name || label()\"\n [invalid]=\"isInvalid(ngControl?.control)\"\n [placeholder]=\"placeholder()\"\n class=\"w-full\"\n appendTo=\"body\"\n styleClass=\"w-full\"\n [dropdown]=\"false\"\n [size]=\"size()\"\n >\n <ng-template let-user pTemplate=\"item\">\n <div class=\"flex items-center gap-2\">\n <mt-avatar size=\"small\" icon=\"user.user-01\" />\n <div class=\"flex align-items-center gap-3\">\n <span class=\"font-medium\">{{ user.displayName }}</span>\n <medium class=\"text-gray-500\">{{ \"@\" + user.userName }}</medium>\n </div>\n </div>\n </ng-template>\n\n <!-- <ng-template let-user #pTemplate=\"selecteditem\">\n <div class=\"flex items-center gap-2\">\n <mt-avatar size=\"small\" icon=\"user.user-01\" />\n <div class=\"flex align-items-center gap-3\">\n <span class=\"font-medium\">{{ user.displayName }}</span>\n <medium class=\"text-gray-500\">{{ \"@\" + user.userName }}</medium>\n </div>\n </div>\n </ng-template> -->\n </p-autoComplete>\n @if (hint()) {\n <p-inputgroup-addon [mtTooltip]=\"hint()\" tooltipPosition=\"top\">\n <mt-icon icon=\"general.help-circle\" />\n </p-inputgroup-addon>\n } @else {\n <p-inputgroup-addon tooltipPosition=\"top\">\n <mt-icon icon=\"user.user-03\" />\n </p-inputgroup-addon>\n }\n </p-inputgroup>\n\n @if (loading()) {\n <mt-icon\n icon=\"general.loading-01\"\n class=\"animate-spin absolute right-3 bg-white top-1/2 -translate-y-1/2\"\n />\n }\n</div>\n<mt-field-validation [control]=\"ngControl?.control\"></mt-field-validation>\n" }]
|
|
133
132
|
}], ctorParameters: () => [], propDecorators: { styleClass: [{
|
|
134
133
|
type: HostBinding,
|
|
135
134
|
args: ['class']
|