@sd-angular/core 19.0.0-beta.57 → 19.0.0-beta.59

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,15 +1,19 @@
1
- import { OnInit } from '@angular/core';
2
1
  import * as i0 from "@angular/core";
3
- export declare class SdAvatar implements OnInit {
2
+ export declare class SdAvatar {
4
3
  #private;
5
- src: string | undefined | null;
6
- size: number;
7
- name: string;
8
- isUrl: boolean;
9
- initials: string;
10
- bgColor: string;
11
- ngOnInit(): void;
4
+ /**
5
+ * The source string to be used for the avatar.
6
+ * - If it matches a URL pattern, an image is displayed.
7
+ * - If it is a string representing a name, initials and a colored background are generated.
8
+ * - If undefined, it falls back to a neutral ? initial.
9
+ */
10
+ readonly src: import("@angular/core").InputSignal<string | null | undefined>;
11
+ readonly size: import("@angular/core").InputSignal<number>;
12
+ constructor();
13
+ readonly isUrl: import("@angular/core").Signal<boolean>;
14
+ readonly bgColor: import("@angular/core").Signal<string>;
15
+ readonly initials: import("@angular/core").Signal<string>;
12
16
  handleError(): void;
13
17
  static ɵfac: i0.ɵɵFactoryDeclaration<SdAvatar, never>;
14
- static ɵcmp: i0.ɵɵComponentDeclaration<SdAvatar, "sd-avatar", never, { "src": { "alias": "src"; "required": true; }; "size": { "alias": "size"; "required": false; }; "name": { "alias": "name"; "required": false; }; }, {}, never, never, true, never>;
18
+ static ɵcmp: i0.ɵɵComponentDeclaration<SdAvatar, "sd-avatar", never, { "src": { "alias": "src"; "required": true; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
15
19
  }
@@ -4,7 +4,7 @@ export interface ISdUploadFileConfiguration<TArgs = any> {
4
4
  details: SdUploadFileFuncDetails<TArgs>;
5
5
  download?: SdUploadFileFuncDownload<TArgs>;
6
6
  }
7
- export declare const SD_UPLOAD_FILE_CONFIG: InjectionToken<ISdUploadFileConfiguration<any>>;
7
+ export declare const SD_UPLOAD_FILE_CONFIGURATION: InjectionToken<ISdUploadFileConfiguration<any>>;
8
8
  export type SdUploadFileFuncUpload<TArgs> = (files: File[], args?: TArgs) => Promise<string[]>;
9
9
  export type SdUploadFileFuncDetails<TArgs> = (idOrKey: (string | number)[], args?: TArgs) => Promise<SdUploadFileDetail[]>;
10
10
  export type SdUploadFileFuncDownload<TArgs> = (idOrKey: string | number, args?: TArgs) => Promise<void>;
@@ -1,7 +1,6 @@
1
1
  import * as i0 from "@angular/core";
2
2
  export declare class UploadFileService {
3
3
  #private;
4
- constructor();
5
4
  isHashedKey: (key: string) => boolean;
6
5
  get: (key: string) => File | null;
7
6
  add: (file: File) => string | null;
@@ -1,33 +1,55 @@
1
1
  import { CommonModule } from '@angular/common';
2
2
  import * as i0 from '@angular/core';
3
- import { Input, ChangeDetectionStrategy, Component } from '@angular/core';
3
+ import { input, signal, effect, computed, ChangeDetectionStrategy, Component } from '@angular/core';
4
4
 
5
5
  class SdAvatar {
6
- src;
7
- size = 32;
8
- name = '';
9
- isUrl = false;
10
- initials = '';
11
- bgColor = '#ccc';
12
- ngOnInit() {
13
- this.#init();
6
+ /**
7
+ * The source string to be used for the avatar.
8
+ * - If it matches a URL pattern, an image is displayed.
9
+ * - If it is a string representing a name, initials and a colored background are generated.
10
+ * - If undefined, it falls back to a neutral ? initial.
11
+ */
12
+ src = input.required();
13
+ size = input(32);
14
+ #imageError = signal(false);
15
+ constructor() {
16
+ // Reset image error state whenever src changes
17
+ effect(() => {
18
+ this.src();
19
+ this.#imageError.set(false);
20
+ });
14
21
  }
15
- #init = () => {
16
- // Kiểm tra xem src phải URL (http, https, data:image, hoặc path /)
22
+ isUrl = computed(() => {
23
+ // If image has failed to load, treat it as a non-url to fallback to initials using the literal URL text
24
+ if (this.#imageError()) {
25
+ return false;
26
+ }
27
+ const val = this.src() || '';
17
28
  const urlPattern = /^(http|https|data:image|\/)/;
18
- this.isUrl = urlPattern.test(this.src || '');
19
- if (this.name || !this.isUrl) {
20
- this.bgColor = this.#generateColor(this.name || this.src || '');
21
- this.initials = this.#getInitials(this.name || this.src || '');
29
+ return urlPattern.test(val);
30
+ });
31
+ bgColor = computed(() => {
32
+ if (this.isUrl()) {
33
+ return 'transparent';
22
34
  }
23
- else {
24
- this.bgColor = '#bdc3c7';
25
- this.initials = '?';
35
+ const val = this.src() || '';
36
+ if (!val) {
37
+ return '#bdc3c7';
26
38
  }
27
- };
39
+ return this.#generateColor(val);
40
+ });
41
+ initials = computed(() => {
42
+ if (this.isUrl()) {
43
+ return '';
44
+ }
45
+ const val = this.src() || '';
46
+ if (!val) {
47
+ return '?';
48
+ }
49
+ return this.#getInitials(val);
50
+ });
28
51
  handleError() {
29
- this.src = undefined; // Nếu ảnh lỗi, chuyển sang hiển thị initials
30
- this.#init();
52
+ this.#imageError.set(true);
31
53
  }
32
54
  #getInitials = (name) => {
33
55
  return (name
@@ -68,19 +90,12 @@ class SdAvatar {
68
90
  return colors[Math.abs(hash) % colors.length];
69
91
  };
70
92
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: SdAvatar, deps: [], target: i0.ɵɵFactoryTarget.Component });
71
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.17", type: SdAvatar, isStandalone: true, selector: "sd-avatar", inputs: { src: "src", size: "size", name: "name" }, ngImport: i0, template: "<div class=\"sd-avatar\" [style.width.px]=\"size\" [style.height.px]=\"size\" [style.line-height.px]=\"size\" [style.backgroundColor]=\"bgColor\">\r\n @if (isUrl) {\r\n <img [src]=\"src\" (error)=\"handleError()\" alt=\"avatar\" />\r\n } @else {\r\n <span class=\"sd-avatar-text\" [style.fontSize.px]=\"size / 2.5\">\r\n {{ initials }}\r\n </span>\r\n }\r\n</div>\r\n", styles: [".sd-avatar{display:inline-flex;align-items:center;justify-content:center;border-radius:50%;overflow:hidden;color:#fff;font-weight:500;-webkit-user-select:none;user-select:none;background-size:cover}.sd-avatar img{width:100%;height:100%;object-fit:cover}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
93
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.17", type: SdAvatar, isStandalone: true, selector: "sd-avatar", inputs: { src: { classPropertyName: "src", publicName: "src", isSignal: true, isRequired: true, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<div class=\"sd-avatar\" [style.width.px]=\"size()\" [style.height.px]=\"size()\" [style.line-height.px]=\"size()\" [style.backgroundColor]=\"bgColor()\">\n @if (isUrl()) {\n <img [src]=\"src()\" (error)=\"handleError()\" alt=\"avatar\" />\n } @else {\n <span class=\"sd-avatar-text\" [style.fontSize.px]=\"size() / 2.5\">\n {{ initials() }}\n </span>\n }\n</div>\n", styles: [".sd-avatar{display:inline-flex;align-items:center;justify-content:center;border-radius:50%;overflow:hidden;color:#fff;font-weight:500;-webkit-user-select:none;user-select:none;background-size:cover}.sd-avatar img{width:100%;height:100%;object-fit:cover}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
72
94
  }
73
95
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: SdAvatar, decorators: [{
74
96
  type: Component,
75
- args: [{ selector: 'sd-avatar', standalone: true, imports: [CommonModule], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"sd-avatar\" [style.width.px]=\"size\" [style.height.px]=\"size\" [style.line-height.px]=\"size\" [style.backgroundColor]=\"bgColor\">\r\n @if (isUrl) {\r\n <img [src]=\"src\" (error)=\"handleError()\" alt=\"avatar\" />\r\n } @else {\r\n <span class=\"sd-avatar-text\" [style.fontSize.px]=\"size / 2.5\">\r\n {{ initials }}\r\n </span>\r\n }\r\n</div>\r\n", styles: [".sd-avatar{display:inline-flex;align-items:center;justify-content:center;border-radius:50%;overflow:hidden;color:#fff;font-weight:500;-webkit-user-select:none;user-select:none;background-size:cover}.sd-avatar img{width:100%;height:100%;object-fit:cover}\n"] }]
76
- }], propDecorators: { src: [{
77
- type: Input,
78
- args: [{ required: true }]
79
- }], size: [{
80
- type: Input
81
- }], name: [{
82
- type: Input
83
- }] } });
97
+ args: [{ selector: 'sd-avatar', standalone: true, imports: [CommonModule], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"sd-avatar\" [style.width.px]=\"size()\" [style.height.px]=\"size()\" [style.line-height.px]=\"size()\" [style.backgroundColor]=\"bgColor()\">\n @if (isUrl()) {\n <img [src]=\"src()\" (error)=\"handleError()\" alt=\"avatar\" />\n } @else {\n <span class=\"sd-avatar-text\" [style.fontSize.px]=\"size() / 2.5\">\n {{ initials() }}\n </span>\n }\n</div>\n", styles: [".sd-avatar{display:inline-flex;align-items:center;justify-content:center;border-radius:50%;overflow:hidden;color:#fff;font-weight:500;-webkit-user-select:none;user-select:none;background-size:cover}.sd-avatar img{width:100%;height:100%;object-fit:cover}\n"] }]
98
+ }], ctorParameters: () => [] });
84
99
 
85
100
  /**
86
101
  * Generated bundle index. Do not edit.
@@ -1 +1 @@
1
- {"version":3,"file":"sd-angular-core-components-avatar.mjs","sources":["../../../projects/sd-angular/components/avatar/src/avatar.component.ts","../../../projects/sd-angular/components/avatar/src/avatar.component.html","../../../projects/sd-angular/components/avatar/sd-angular-core-components-avatar.ts"],"sourcesContent":["import { CommonModule } from '@angular/common';\r\nimport { ChangeDetectionStrategy, Component, Input, OnInit } from '@angular/core';\r\n\r\n@Component({\r\n selector: 'sd-avatar',\r\n standalone: true,\r\n imports: [CommonModule],\r\n templateUrl: './avatar.component.html',\r\n styleUrls: ['./avatar.component.scss'],\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n})\r\nexport class SdAvatar implements OnInit {\r\n @Input({ required: true }) src: string | undefined | null;\r\n @Input() size: number = 32;\r\n @Input() name: string = '';\r\n\r\n isUrl: boolean = false;\r\n initials: string = '';\r\n bgColor: string = '#ccc';\r\n\r\n ngOnInit(): void {\r\n this.#init();\r\n }\r\n\r\n #init = () => {\r\n // Kiểm tra xem src phải URL (http, https, data:image, hoặc path /)\r\n const urlPattern = /^(http|https|data:image|\\/)/;\r\n this.isUrl = urlPattern.test(this.src || '');\r\n if (this.name || !this.isUrl) {\r\n this.bgColor = this.#generateColor(this.name || this.src || '');\r\n this.initials = this.#getInitials(this.name || this.src || '');\r\n } else {\r\n this.bgColor = '#bdc3c7';\r\n this.initials = '?';\r\n }\r\n };\r\n\r\n handleError() {\r\n this.src = undefined; // Nếu ảnh lỗi, chuyển sang hiển thị initials\r\n this.#init();\r\n }\r\n\r\n #getInitials = (name: string): string => {\r\n return (\r\n name\r\n .trim()\r\n .split(' ')\r\n .filter(Boolean)\r\n .map(n => n[0])\r\n .join('')\r\n .toUpperCase()\r\n .substring(0, 2) || ''\r\n );\r\n };\r\n\r\n #generateColor = (name: string): string => {\r\n const colors = [\r\n '#1abc9c',\r\n '#2ecc71',\r\n '#3498db',\r\n '#9b59b6',\r\n '#34495e',\r\n '#16a085',\r\n '#27ae60',\r\n '#2980b9',\r\n '#8e44ad',\r\n '#2c3e50',\r\n '#f1c40f',\r\n '#e67e22',\r\n '#e74c3c',\r\n '#95a5a6',\r\n '#f39c12',\r\n '#d35400',\r\n '#c0392b',\r\n '#bdc3c7',\r\n '#7f8c8d',\r\n ];\r\n let hash = 0;\r\n for (let i = 0; i < name.length; i++) {\r\n hash = name.charCodeAt(i) + ((hash << 5) - hash);\r\n }\r\n return colors[Math.abs(hash) % colors.length];\r\n };\r\n}\r\n","<div class=\"sd-avatar\" [style.width.px]=\"size\" [style.height.px]=\"size\" [style.line-height.px]=\"size\" [style.backgroundColor]=\"bgColor\">\r\n @if (isUrl) {\r\n <img [src]=\"src\" (error)=\"handleError()\" alt=\"avatar\" />\r\n } @else {\r\n <span class=\"sd-avatar-text\" [style.fontSize.px]=\"size / 2.5\">\r\n {{ initials }}\r\n </span>\r\n }\r\n</div>\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"sd-angular-core-components-avatar.mjs","sources":["../../../projects/sd-angular/components/avatar/src/avatar.component.ts","../../../projects/sd-angular/components/avatar/src/avatar.component.html","../../../projects/sd-angular/components/avatar/sd-angular-core-components-avatar.ts"],"sourcesContent":["import { CommonModule } from '@angular/common';\nimport { ChangeDetectionStrategy, Component, computed, effect, input, signal } from '@angular/core';\n\n@Component({\n selector: 'sd-avatar',\n standalone: true,\n imports: [CommonModule],\n templateUrl: './avatar.component.html',\n styleUrls: ['./avatar.component.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class SdAvatar {\n /**\n * The source string to be used for the avatar.\n * - If it matches a URL pattern, an image is displayed.\n * - If it is a string representing a name, initials and a colored background are generated.\n * - If undefined, it falls back to a neutral ? initial.\n */\n readonly src = input.required<string | undefined | null>();\n readonly size = input<number>(32);\n\n readonly #imageError = signal<boolean>(false);\n\n constructor() {\n // Reset image error state whenever src changes\n effect(() => {\n this.src();\n this.#imageError.set(false);\n });\n }\n\n readonly isUrl = computed(() => {\n // If image has failed to load, treat it as a non-url to fallback to initials using the literal URL text\n if (this.#imageError()) {\n return false;\n }\n const val = this.src() || '';\n const urlPattern = /^(http|https|data:image|\\/)/;\n return urlPattern.test(val);\n });\n\n readonly bgColor = computed(() => {\n if (this.isUrl()) {\n return 'transparent';\n }\n const val = this.src() || '';\n if (!val) {\n return '#bdc3c7';\n }\n return this.#generateColor(val);\n });\n\n readonly initials = computed(() => {\n if (this.isUrl()) {\n return '';\n }\n const val = this.src() || '';\n if (!val) {\n return '?';\n }\n return this.#getInitials(val);\n });\n\n handleError() {\n this.#imageError.set(true);\n }\n\n #getInitials = (name: string): string => {\n return (\n name\n .trim()\n .split(' ')\n .filter(Boolean)\n .map(n => n[0])\n .join('')\n .toUpperCase()\n .substring(0, 2) || ''\n );\n };\n\n #generateColor = (name: string): string => {\n const colors = [\n '#1abc9c',\n '#2ecc71',\n '#3498db',\n '#9b59b6',\n '#34495e',\n '#16a085',\n '#27ae60',\n '#2980b9',\n '#8e44ad',\n '#2c3e50',\n '#f1c40f',\n '#e67e22',\n '#e74c3c',\n '#95a5a6',\n '#f39c12',\n '#d35400',\n '#c0392b',\n '#bdc3c7',\n '#7f8c8d',\n ];\n let hash = 0;\n for (let i = 0; i < name.length; i++) {\n hash = name.charCodeAt(i) + ((hash << 5) - hash);\n }\n return colors[Math.abs(hash) % colors.length];\n };\n}\n","<div class=\"sd-avatar\" [style.width.px]=\"size()\" [style.height.px]=\"size()\" [style.line-height.px]=\"size()\" [style.backgroundColor]=\"bgColor()\">\n @if (isUrl()) {\n <img [src]=\"src()\" (error)=\"handleError()\" alt=\"avatar\" />\n } @else {\n <span class=\"sd-avatar-text\" [style.fontSize.px]=\"size() / 2.5\">\n {{ initials() }}\n </span>\n }\n</div>\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":";;;;MAWa,QAAQ,CAAA;AACnB;;;;;AAKG;AACM,IAAA,GAAG,GAAG,KAAK,CAAC,QAAQ,EAA6B;AACjD,IAAA,IAAI,GAAG,KAAK,CAAS,EAAE,CAAC;AAExB,IAAA,WAAW,GAAG,MAAM,CAAU,KAAK,CAAC;AAE7C,IAAA,WAAA,GAAA;;QAEE,MAAM,CAAC,MAAK;YACV,IAAI,CAAC,GAAG,EAAE;AACV,YAAA,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,KAAK,CAAC;AAC7B,QAAA,CAAC,CAAC;IACJ;AAES,IAAA,KAAK,GAAG,QAAQ,CAAC,MAAK;;AAE7B,QAAA,IAAI,IAAI,CAAC,WAAW,EAAE,EAAE;AACtB,YAAA,OAAO,KAAK;QACd;QACA,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,IAAI,EAAE;QAC5B,MAAM,UAAU,GAAG,6BAA6B;AAChD,QAAA,OAAO,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC;AAC7B,IAAA,CAAC,CAAC;AAEO,IAAA,OAAO,GAAG,QAAQ,CAAC,MAAK;AAC/B,QAAA,IAAI,IAAI,CAAC,KAAK,EAAE,EAAE;AAChB,YAAA,OAAO,aAAa;QACtB;QACA,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,IAAI,EAAE;QAC5B,IAAI,CAAC,GAAG,EAAE;AACR,YAAA,OAAO,SAAS;QAClB;AACA,QAAA,OAAO,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC;AACjC,IAAA,CAAC,CAAC;AAEO,IAAA,QAAQ,GAAG,QAAQ,CAAC,MAAK;AAChC,QAAA,IAAI,IAAI,CAAC,KAAK,EAAE,EAAE;AAChB,YAAA,OAAO,EAAE;QACX;QACA,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,IAAI,EAAE;QAC5B,IAAI,CAAC,GAAG,EAAE;AACR,YAAA,OAAO,GAAG;QACZ;AACA,QAAA,OAAO,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC;AAC/B,IAAA,CAAC,CAAC;IAEF,WAAW,GAAA;AACT,QAAA,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC;IAC5B;AAEA,IAAA,YAAY,GAAG,CAAC,IAAY,KAAY;AACtC,QAAA,QACE;AACG,aAAA,IAAI;aACJ,KAAK,CAAC,GAAG;aACT,MAAM,CAAC,OAAO;aACd,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;aACb,IAAI,CAAC,EAAE;AACP,aAAA,WAAW;aACX,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,EAAE;AAE5B,IAAA,CAAC;AAED,IAAA,cAAc,GAAG,CAAC,IAAY,KAAY;AACxC,QAAA,MAAM,MAAM,GAAG;YACb,SAAS;YACT,SAAS;YACT,SAAS;YACT,SAAS;YACT,SAAS;YACT,SAAS;YACT,SAAS;YACT,SAAS;YACT,SAAS;YACT,SAAS;YACT,SAAS;YACT,SAAS;YACT,SAAS;YACT,SAAS;YACT,SAAS;YACT,SAAS;YACT,SAAS;YACT,SAAS;YACT,SAAS;SACV;QACD,IAAI,IAAI,GAAG,CAAC;AACZ,QAAA,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;AACpC,YAAA,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,IAAI,CAAC;QAClD;AACA,QAAA,OAAO,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,MAAM,CAAC;AAC/C,IAAA,CAAC;wGAhGU,QAAQ,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;4FAAR,QAAQ,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,WAAA,EAAA,MAAA,EAAA,EAAA,GAAA,EAAA,EAAA,iBAAA,EAAA,KAAA,EAAA,UAAA,EAAA,KAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,IAAA,EAAA,EAAA,iBAAA,EAAA,MAAA,EAAA,UAAA,EAAA,MAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,ECXrB,gYASA,EAAA,MAAA,EAAA,CAAA,iQAAA,CAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EDHY,YAAY,EAAA,CAAA,EAAA,eAAA,EAAA,EAAA,CAAA,uBAAA,CAAA,MAAA,EAAA,CAAA;;4FAKX,QAAQ,EAAA,UAAA,EAAA,CAAA;kBARpB,SAAS;+BACE,WAAW,EAAA,UAAA,EACT,IAAI,EAAA,OAAA,EACP,CAAC,YAAY,CAAC,EAAA,eAAA,EAGN,uBAAuB,CAAC,MAAM,EAAA,QAAA,EAAA,gYAAA,EAAA,MAAA,EAAA,CAAA,iQAAA,CAAA,EAAA;;;AETjD;;AAEG;;;;"}
@@ -4,7 +4,7 @@ import * as i4 from '@angular/cdk/drag-drop';
4
4
  import { moveItemInArray, DragDropModule } from '@angular/cdk/drag-drop';
5
5
  import * as i1 from '@angular/common';
6
6
  import { CommonModule } from '@angular/common';
7
- import { NgForm, FormGroup, Validators } from '@angular/forms';
7
+ import { NgForm, FormGroup } from '@angular/forms';
8
8
  import * as i2 from '@angular/material/button';
9
9
  import { MatButtonModule } from '@angular/material/button';
10
10
  import * as i3 from '@angular/material/icon';
@@ -21,7 +21,7 @@ import { SdButton } from '@sd-angular/core/components/button';
21
21
  import { SdModal } from '@sd-angular/core/components/modal';
22
22
  import { SdUtilities } from '@sd-angular/core/utilities';
23
23
 
24
- const SD_UPLOAD_FILE_CONFIG = new InjectionToken('sd.upload-file.configuration');
24
+ const SD_UPLOAD_FILE_CONFIGURATION = new InjectionToken('sd.upload-file.configuration');
25
25
 
26
26
  class PreviewComponent {
27
27
  cd;
@@ -123,11 +123,8 @@ const IsImage = (extension) => {
123
123
  return IMAGE_EXTENSIONS.includes(extension?.toLowerCase());
124
124
  };
125
125
 
126
- /* eslint-disable @typescript-eslint/no-explicit-any */
127
- // import { sha1 } from 'object-hash';
128
126
  class UploadFileService {
129
127
  #cache = {};
130
- constructor() { }
131
128
  #hash = (file) => {
132
129
  if (!file) {
133
130
  return null;
@@ -174,7 +171,7 @@ class UploadFileService {
174
171
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: UploadFileService, decorators: [{
175
172
  type: Injectable,
176
173
  args: [{ providedIn: 'root' }]
177
- }], ctorParameters: () => [] });
174
+ }] });
178
175
 
179
176
  /* eslint-disable @angular-eslint/no-input-rename */
180
177
  /* eslint-disable @typescript-eslint/no-explicit-any */
@@ -183,7 +180,7 @@ class SdUploadFile {
183
180
  // ─── Injected Services ────────────────────────────────────────────────
184
181
  #notifyService = inject(SdNotifyService);
185
182
  #confirmService = inject(SdConfirmService);
186
- #uploadFileConfig = inject(SD_UPLOAD_FILE_CONFIG);
183
+ #uploadFileConfig = inject(SD_UPLOAD_FILE_CONFIGURATION, { optional: true });
187
184
  #uploadFileService = inject(UploadFileService);
188
185
  #destroyRef = inject(DestroyRef);
189
186
  // ─── Internal State ───────────────────────────────────────────────────
@@ -193,7 +190,6 @@ class SdUploadFile {
193
190
  #canvas2 = `C${uuid.v4()}`;
194
191
  #name = uuid.v4();
195
192
  #formGroup;
196
- #currentDropContainer;
197
193
  formControl = new SdFormControl();
198
194
  // ─── Signals (state) ──────────────────────────────────────────────────
199
195
  previewFiles = signal([]);
@@ -336,7 +332,6 @@ class SdUploadFile {
336
332
  }
337
333
  }
338
334
  #bindDropEvents(dropContainer) {
339
- this.#currentDropContainer = dropContainer;
340
335
  dropContainer.addEventListener('dragover', (evt) => {
341
336
  evt.preventDefault();
342
337
  dropContainer.style.opacity = 0.9;
@@ -365,18 +360,18 @@ class SdUploadFile {
365
360
  this.formControl.markAsTouched();
366
361
  this.formControl.setValue(this.model() || []);
367
362
  };
368
- #updateValidator = () => {
369
- this.formControl.clearValidators();
370
- this.formControl.clearAsyncValidators();
371
- const validators = [];
372
- const asyncValidators = [];
373
- if (this.required()) {
374
- validators.push(Validators.required);
375
- }
376
- this.formControl.setValidators(validators);
377
- this.formControl.setAsyncValidators(asyncValidators);
378
- this.formControl.updateValueAndValidity();
379
- };
363
+ // #updateValidator = () => {
364
+ // this.formControl.clearValidators();
365
+ // this.formControl.clearAsyncValidators();
366
+ // const validators: ValidatorFn[] = [];
367
+ // const asyncValidators: AsyncValidatorFn[] = [];
368
+ // if (this.required()) {
369
+ // validators.push(Validators.required);
370
+ // }
371
+ // this.formControl.setValidators(validators);
372
+ // this.formControl.setAsyncValidators(asyncValidators);
373
+ // this.formControl.updateValueAndValidity();
374
+ // };
380
375
  #validate = async (file) => {
381
376
  if (this.type() === 'image') {
382
377
  if (file.type.split('/')[0] !== 'image') {
@@ -616,12 +611,17 @@ class SdUploadFile {
616
611
  const uploadedFiles = items.map(e => e?.file).filter(file => !!file);
617
612
  let idOrKeys = [];
618
613
  if (uploadedFiles.length) {
619
- idOrKeys = await this.#uploadFileConfig.upload(uploadedFiles, this.args()).then(results => {
620
- for (const uploadedFile of uploadedFiles) {
621
- this.#uploadFileService.remove(uploadedFile);
622
- }
623
- return results;
624
- });
614
+ if (this.#uploadFileConfig) {
615
+ idOrKeys = await this.#uploadFileConfig.upload(uploadedFiles, this.args()).then(results => {
616
+ for (const uploadedFile of uploadedFiles) {
617
+ this.#uploadFileService.remove(uploadedFile);
618
+ }
619
+ return results;
620
+ });
621
+ }
622
+ else {
623
+ this.#notifyService.error(`Vui lòng inject SD_UPLOAD_FILE_CONFIGURATION`);
624
+ }
625
625
  }
626
626
  let idx = 0;
627
627
  for (const item of items) {
@@ -679,20 +679,12 @@ class SdUploadFile {
679
679
  }
680
680
  const idOrKeys = keys.filter(key => !!key && !this.#isCdn(key) && !this.#isHashedKey(key));
681
681
  let detailsList = [];
682
- const detailsFn = this.details();
683
- if (idOrKeys.length) {
684
- if (detailsFn) {
685
- detailsList = await detailsFn(idOrKeys, this.args()).catch(error => {
686
- console.error(error);
687
- return [];
688
- });
689
- }
690
- else if (this.#uploadFileConfig.details) {
691
- detailsList = await this.#uploadFileConfig.details(idOrKeys, this.args()).catch(error => {
692
- console.error(error);
693
- return [];
694
- });
695
- }
682
+ const details = this.details() || this.#uploadFileConfig?.details;
683
+ if (idOrKeys.length && details) {
684
+ detailsList = await details(idOrKeys, this.args()).catch(error => {
685
+ console.error(error);
686
+ return [];
687
+ });
696
688
  }
697
689
  const results = [];
698
690
  for (const key of keys.filter(val => !!val)) {
@@ -808,5 +800,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.17", ngImpo
808
800
  * Generated bundle index. Do not edit.
809
801
  */
810
802
 
811
- export { SD_UPLOAD_FILE_CONFIG, SdUploadFile };
803
+ export { SD_UPLOAD_FILE_CONFIGURATION, SdUploadFile };
812
804
  //# sourceMappingURL=sd-angular-core-components-upload-file.mjs.map