@sd-angular/core 19.0.0-beta.71 → 19.0.0-beta.72

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. package/components/modal/src/modal.component.d.ts +1 -1
  2. package/components/upload-file/src/configurations/upload-file.configuration.d.ts +33 -0
  3. package/components/upload-file/src/upload-file.component.d.ts +5 -2
  4. package/fesm2022/sd-angular-core-components-table.mjs +7 -5
  5. package/fesm2022/sd-angular-core-components-table.mjs.map +1 -1
  6. package/fesm2022/sd-angular-core-components-upload-file.mjs +61 -9
  7. package/fesm2022/sd-angular-core-components-upload-file.mjs.map +1 -1
  8. package/fesm2022/sd-angular-core-components-workflow.mjs +2 -2
  9. package/fesm2022/sd-angular-core-components-workflow.mjs.map +1 -1
  10. package/fesm2022/sd-angular-core-modules-layout.mjs +2 -3
  11. package/fesm2022/sd-angular-core-modules-layout.mjs.map +1 -1
  12. package/fesm2022/sd-angular-core-modules-permission.mjs +160 -74
  13. package/fesm2022/sd-angular-core-modules-permission.mjs.map +1 -1
  14. package/fesm2022/sd-angular-core.mjs +0 -1
  15. package/fesm2022/sd-angular-core.mjs.map +1 -1
  16. package/modules/layout/services/menu/menu.model.d.ts +1 -0
  17. package/modules/permission/src/configurations/permission.configuration.d.ts +56 -2
  18. package/modules/permission/src/directives/permission.directive.d.ts +5 -8
  19. package/modules/permission/src/guards/permission.guard.d.ts +2 -1
  20. package/modules/permission/src/services/permission.service.d.ts +6 -9
  21. package/package.json +86 -94
  22. package/public-api.d.ts +0 -1
  23. package/sd-angular-core-19.0.0-beta.72.tgz +0 -0
  24. package/fesm2022/sd-angular-core-guards-permission.mjs +0 -155
  25. package/fesm2022/sd-angular-core-guards-permission.mjs.map +0 -1
  26. package/fesm2022/sd-angular-core-guards.mjs +0 -6
  27. package/fesm2022/sd-angular-core-guards.mjs.map +0 -1
  28. package/guards/index.d.ts +0 -1
  29. package/guards/permission/index.d.ts +0 -4
  30. package/guards/permission/src/configurations/index.d.ts +0 -1
  31. package/guards/permission/src/configurations/permission.configuration.d.ts +0 -8
  32. package/guards/permission/src/directives/index.d.ts +0 -1
  33. package/guards/permission/src/directives/permission.directive.d.ts +0 -12
  34. package/guards/permission/src/guards/index.d.ts +0 -1
  35. package/guards/permission/src/guards/permission.guard.d.ts +0 -13
  36. package/guards/permission/src/services/index.d.ts +0 -1
  37. package/guards/permission/src/services/permission.service.d.ts +0 -15
  38. package/sd-angular-core-19.0.0-beta.71.tgz +0 -0
@@ -11,7 +11,7 @@ export declare class SdModal {
11
11
  width: import("@angular/core").InputSignalWithTransform<string, string | null | undefined>;
12
12
  height: import("@angular/core").InputSignalWithTransform<string, string | null | undefined>;
13
13
  view: import("@angular/core").InputSignalWithTransform<"dialog" | "bottom-sheet" | undefined, "dialog" | "bottom-sheet" | null | undefined>;
14
- modalClass: import("@angular/core").InputSignalWithTransform<string | Record<string, boolean> | string[], string | Record<string, boolean> | string[] | null | undefined>;
14
+ modalClass: import("@angular/core").InputSignalWithTransform<string | string[] | Record<string, boolean>, string | string[] | Record<string, boolean> | null | undefined>;
15
15
  lazyLoadContent: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
16
16
  sdClosed: import("@angular/core").OutputEmitterRef<void>;
17
17
  isOpened: import("@angular/core").WritableSignal<boolean>;
@@ -1,17 +1,50 @@
1
1
  import { InjectionToken } from '@angular/core';
2
+ /**
3
+ * Contract cấu hình cho cơ chế upload file của sd-angular.
4
+ *
5
+ * Cách dùng phổ biến:
6
+ * - Portal có thể provide cấu hình mặc định ở tầng global.
7
+ * - Mỗi module có thể provide thêm cấu hình riêng (thường với `multi: true`).
8
+ * - Khi có nhiều cấu hình cùng lúc, dùng `key` để chọn đúng provider.
9
+ *
10
+ * Luồng xử lý:
11
+ * 1) `upload`: upload file mới, trả về danh sách id/key.
12
+ * 2) `details`: lấy metadata để render danh sách file từ id/key.
13
+ * 3) `download` (optional): tải file theo id/key.
14
+ */
2
15
  export interface ISdUploadFileConfiguration<TArgs = any> {
16
+ /**
17
+ * Định danh cấu hình upload.
18
+ * Bắt buộc khi app có nhiều provider upload để tránh mapping nhầm.
19
+ */
20
+ key?: string;
21
+ /** Upload file và trả về danh sách id/key dùng cho lưu trữ. */
3
22
  upload: SdUploadFileFuncUpload<TArgs>;
23
+ /** Nhận danh sách id/key và trả về dữ liệu hiển thị file trong UI. */
4
24
  details: SdUploadFileFuncDetails<TArgs>;
25
+ /** Tùy chọn: tải file về theo id/key. */
5
26
  download?: SdUploadFileFuncDownload<TArgs>;
6
27
  }
28
+ /**
29
+ * Token DI cho upload configuration.
30
+ * Khuyến nghị provide dạng `multi: true` để hỗ trợ nhiều nguồn upload trong cùng app/module.
31
+ */
7
32
  export declare const SD_UPLOAD_FILE_CONFIGURATION: InjectionToken<ISdUploadFileConfiguration<any>>;
33
+ /** Hàm upload file và trả về danh sách id/key tương ứng. */
8
34
  export type SdUploadFileFuncUpload<TArgs> = (files: File[], args?: TArgs) => Promise<string[]>;
35
+ /** Hàm lấy thông tin file phục vụ hiển thị từ danh sách id/key. */
9
36
  export type SdUploadFileFuncDetails<TArgs> = (idOrKey: (string | number)[], args?: TArgs) => Promise<SdUploadFileDetail[]>;
37
+ /** Hàm tải file theo id/key. */
10
38
  export type SdUploadFileFuncDownload<TArgs> = (idOrKey: string | number, args?: TArgs) => Promise<void>;
11
39
  export interface SdUploadFileDetail {
40
+ /** Định danh file được backend trả về sau upload. */
12
41
  idOrKey: string;
42
+ /** URL truy cập file (CDN hoặc direct URL). */
13
43
  cdn: string;
44
+ /** Tên hiển thị file. */
14
45
  name?: string;
46
+ /** Đuôi file: png, jpg, pdf... */
15
47
  extension?: string;
48
+ /** Dung lượng file tính theo MB (nếu backend có trả về). */
16
49
  size?: number;
17
50
  }
@@ -4,7 +4,7 @@ import { FormGroup } from '@angular/forms';
4
4
  import { SdLabelDefDirective } from '@sd-angular/core/forms/directives';
5
5
  import { SdFormControl } from '@sd-angular/core/forms/models';
6
6
  import { PreviewComponent } from './components/preview/preview.component';
7
- import { SdUploadFileFuncDetails } from './configurations';
7
+ import { SdUploadFileFuncDownload, SdUploadFileFuncDetails, SdUploadFileFuncUpload } from './configurations';
8
8
  import { PreviewFile } from './services';
9
9
  import * as i0 from "@angular/core";
10
10
  export declare class SdUploadFile<TArgs = any> {
@@ -18,11 +18,14 @@ export declare class SdUploadFile<TArgs = any> {
18
18
  readonly sdLabelDef: import("@angular/core").Signal<SdLabelDefDirective | undefined>;
19
19
  readonly args: import("@angular/core").InputSignal<TArgs | undefined>;
20
20
  readonly label: import("@angular/core").InputSignal<string | undefined>;
21
+ readonly key: import("@angular/core").InputSignal<string | undefined>;
21
22
  readonly description: import("@angular/core").InputSignal<string | undefined>;
22
23
  readonly previewWidth: import("@angular/core").InputSignal<string>;
23
24
  readonly previewHeight: import("@angular/core").InputSignal<string>;
24
25
  readonly align: import("@angular/core").InputSignal<"left" | "center">;
26
+ readonly uploadInput: import("@angular/core").InputSignal<SdUploadFileFuncUpload<any> | undefined>;
25
27
  readonly details: import("@angular/core").InputSignal<SdUploadFileFuncDetails<any> | undefined>;
28
+ readonly downloadInput: import("@angular/core").InputSignal<SdUploadFileFuncDownload<any> | undefined>;
26
29
  readonly imageValidator: import("@angular/core").InputSignal<((image: HTMLImageElement) => string) | undefined>;
27
30
  readonly maxSize: import("@angular/core").InputSignal<number | undefined>;
28
31
  readonly maxWidth: import("@angular/core").InputSignal<number | undefined>;
@@ -72,5 +75,5 @@ export declare class SdUploadFile<TArgs = any> {
72
75
  onDownload: (previewFile: PreviewFile) => void;
73
76
  isLastVisibleOverlay(fileIndex: number): boolean;
74
77
  static ɵfac: i0.ɵɵFactoryDeclaration<SdUploadFile<any>, never>;
75
- static ɵcmp: i0.ɵɵComponentDeclaration<SdUploadFile<any>, "sd-upload-file", never, { "args": { "alias": "args"; "required": false; "isSignal": true; }; "label": { "alias": "label"; "required": false; "isSignal": true; }; "description": { "alias": "description"; "required": false; "isSignal": true; }; "previewWidth": { "alias": "previewWidth"; "required": false; "isSignal": true; }; "previewHeight": { "alias": "previewHeight"; "required": false; "isSignal": true; }; "align": { "alias": "align"; "required": false; "isSignal": true; }; "details": { "alias": "details"; "required": false; "isSignal": true; }; "imageValidator": { "alias": "imageValidator"; "required": false; "isSignal": true; }; "maxSize": { "alias": "maxSize"; "required": false; "isSignal": true; }; "maxWidth": { "alias": "maxWidth"; "required": false; "isSignal": true; }; "maxHeight": { "alias": "maxHeight"; "required": false; "isSignal": true; }; "scaleToPixel": { "alias": "scaleToPixel"; "required": false; "isSignal": true; }; "form": { "alias": "form"; "required": false; "isSignal": true; }; "nameInput": { "alias": "name"; "required": false; "isSignal": true; }; "required": { "alias": "required"; "required": false; "isSignal": true; }; "type": { "alias": "type"; "required": false; "isSignal": true; }; "helperText": { "alias": "helperText"; "required": false; "isSignal": true; }; "max": { "alias": "max"; "required": false; "isSignal": true; }; "maxOfImage": { "alias": "maxOfImage"; "required": false; "isSignal": true; }; "extensions": { "alias": "extensions"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "model": { "alias": "model"; "required": false; "isSignal": true; }; }, { "loaded": "loaded"; "filesChanged": "filesChanged"; "model": "modelChange"; }, ["sdLabelDef"], never, true, never>;
78
+ static ɵcmp: i0.ɵɵComponentDeclaration<SdUploadFile<any>, "sd-upload-file", never, { "args": { "alias": "args"; "required": false; "isSignal": true; }; "label": { "alias": "label"; "required": false; "isSignal": true; }; "key": { "alias": "key"; "required": false; "isSignal": true; }; "description": { "alias": "description"; "required": false; "isSignal": true; }; "previewWidth": { "alias": "previewWidth"; "required": false; "isSignal": true; }; "previewHeight": { "alias": "previewHeight"; "required": false; "isSignal": true; }; "align": { "alias": "align"; "required": false; "isSignal": true; }; "uploadInput": { "alias": "upload"; "required": false; "isSignal": true; }; "details": { "alias": "details"; "required": false; "isSignal": true; }; "downloadInput": { "alias": "download"; "required": false; "isSignal": true; }; "imageValidator": { "alias": "imageValidator"; "required": false; "isSignal": true; }; "maxSize": { "alias": "maxSize"; "required": false; "isSignal": true; }; "maxWidth": { "alias": "maxWidth"; "required": false; "isSignal": true; }; "maxHeight": { "alias": "maxHeight"; "required": false; "isSignal": true; }; "scaleToPixel": { "alias": "scaleToPixel"; "required": false; "isSignal": true; }; "form": { "alias": "form"; "required": false; "isSignal": true; }; "nameInput": { "alias": "name"; "required": false; "isSignal": true; }; "required": { "alias": "required"; "required": false; "isSignal": true; }; "type": { "alias": "type"; "required": false; "isSignal": true; }; "helperText": { "alias": "helperText"; "required": false; "isSignal": true; }; "max": { "alias": "max"; "required": false; "isSignal": true; }; "maxOfImage": { "alias": "maxOfImage"; "required": false; "isSignal": true; }; "extensions": { "alias": "extensions"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "model": { "alias": "model"; "required": false; "isSignal": true; }; }, { "loaded": "loaded"; "filesChanged": "filesChanged"; "model": "modelChange"; }, ["sdLabelDef"], never, true, never>;
76
79
  }
@@ -1,5 +1,5 @@
1
1
  import * as i0 from '@angular/core';
2
- import { Input, Directive, EventEmitter, isSignal, Output, ChangeDetectionStrategy, Component, Pipe, input, computed, InjectionToken, Inject, Optional, Injectable, HostListener, ViewChild, inject, ChangeDetectorRef, viewChild, signal, afterNextRender, ElementRef, DestroyRef, contentChild, contentChildren, effect, untracked } from '@angular/core';
2
+ import { Input, Directive, EventEmitter, isSignal, Output, ChangeDetectionStrategy, Component, Pipe, input, computed, InjectionToken, Inject, Optional, Injectable, HostListener, ViewChild, inject, ChangeDetectorRef, viewChild, signal, effect, ElementRef, DestroyRef, afterNextRender, contentChild, contentChildren, untracked } from '@angular/core';
3
3
  import { trigger, state, style, transition, animate } from '@angular/animations';
4
4
  import * as i4$2 from '@angular/material/paginator';
5
5
  import { MatPaginatorIntl, MatPaginator, MatPaginatorModule } from '@angular/material/paginator';
@@ -844,7 +844,8 @@ class SdDesktopCellView {
844
844
  return data?.id?.toString() || data?.code?.toString() || data?.value?.toString();
845
845
  });
846
846
  constructor() {
847
- afterNextRender(() => {
847
+ effect(() => {
848
+ this.charLimited();
848
849
  const container = this.contentContainer();
849
850
  if (container) {
850
851
  this.#checkOverflow(container.nativeElement);
@@ -865,11 +866,11 @@ class SdDesktopCellView {
865
866
  this.isCollapsed.update(current => !current);
866
867
  };
867
868
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: SdDesktopCellView, deps: [], target: i0.ɵɵFactoryTarget.Component });
868
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.17", type: SdDesktopCellView, isStandalone: true, selector: "sd-desktop-cell-view", inputs: { autoId: { classPropertyName: "autoId", publicName: "autoId", isSignal: true, isRequired: false, transformFunction: null }, column: { classPropertyName: "column", publicName: "column", isSignal: true, isRequired: true, transformFunction: null }, charLimited: { classPropertyName: "charLimited", publicName: "charLimited", isSignal: true, isRequired: false, transformFunction: null }, item: { classPropertyName: "item", publicName: "item", isSignal: true, isRequired: true, transformFunction: null } }, viewQueries: [{ propertyName: "contentContainer", first: true, predicate: ["contentContainer"], descendants: true, isSignal: true }], ngImport: i0, template: "@let view = item().meta.display[column().field];\r\n\r\n@let columnCharLimit = column()?.charLimited;\r\n@let isExpandByMore = isOverflowing() && columnCharLimit?.expandType === 'more';\r\n@let isExpandByTooltip = isOverflowing() && columnCharLimit?.expandType === 'tooltip';\r\n\r\n@if (view) {\r\n @if (view.isHtml) {\r\n @if (view.click) {\r\n <div\r\n [attr.data-autoId]=\"autoId()\"\r\n (click)=\"view.click()\"\r\n class=\"text-break cursor-pointer\"\r\n [sdTooltip]=\"view.tooltip || (isExpandByTooltip ? htmlClickTooltip : '')\"\r\n [style]=\"view.cellStyle\"\r\n [style.max-width]=\"charLimited()?.width\"\r\n [class.c-ellipsis-html]=\"columnCharLimit?.enable\"\r\n [innerHTML]=\"view.data | sdSafeHtml\"\r\n aria-hidden=\"true\"></div>\r\n\r\n <ng-template #htmlClickTooltip>\r\n <div\r\n class=\"c-tooltip-inner-content\"\r\n [style.max-width]=\"'calc(' + charLimited()?.width + ' * 1.5)'\"\r\n style=\"max-height: 200px; overflow-y: auto; scrollbar-width: thin\">\r\n <div [innerHTML]=\"view.data | sdSafeHtml\"></div>\r\n </div>\r\n </ng-template>\r\n } @else {\r\n <!-- N\u1EBFu column c\u00F3 b\u1EADt \"gi\u1EDBi h\u1EA1n k\u00FD t\u1EF1\" -->\r\n @if (columnCharLimit?.enable) {\r\n <div\r\n #contentContainer\r\n [style.max-width]=\"charLimited()?.width\"\r\n [class.c-ellipsis-html]=\"isCollapsed()\"\r\n [attr.data-autoId]=\"autoId()\"\r\n class=\"text-break\"\r\n [sdTooltip]=\"view.tooltip || (isExpandByTooltip ? htmlTooltip : '')\"\r\n containerClass=\"c-tooltip-html-d374bd93-f136-425c-bcc2-2d88cb163e44\"\r\n container=\"body\"\r\n placement=\"bottom\"\r\n [sdTooltipDelay]=\"100\"\r\n [style]=\"view.cellStyle\"\r\n [innerHTML]=\"view.data | sdSafeHtml\"></div>\r\n\r\n <ng-template #htmlTooltip>\r\n <div\r\n class=\"c-tooltip-inner-content\"\r\n [style.max-width]=\"'calc(' + charLimited()?.width + ' * 1.5)'\"\r\n style=\"max-height: 200px; overflow-y: auto; scrollbar-width: thin\">\r\n <div [innerHTML]=\"view.data | sdSafeHtml\"></div>\r\n </div>\r\n </ng-template>\r\n\r\n @if (isExpandByMore) {\r\n <button (click)=\"toggle()\" class=\"c-collapse\">{{ isCollapsed() ? 'Xem th\u00EAm' : 'Thu g\u1ECDn' }}</button>\r\n }\r\n } @else {\r\n <div\r\n [attr.data-autoId]=\"autoId()\"\r\n class=\"text-break\"\r\n [sdTooltip]=\"view.tooltip || ''\"\r\n [style]=\"view.cellStyle\"\r\n [innerHTML]=\"view.data | sdSafeHtml\"></div>\r\n }\r\n <!-- End -->\r\n }\r\n } @else {\r\n <!-- N\u1EBFu l\u00E0 gi\u00E1 tr\u1ECB l\u1EA5y hi\u1EC3n th\u1ECB l\u1EA5y tr\u1EF1c ti\u1EBFp t\u1EEB field -->\r\n @if (view.badge) {\r\n @if (view.data) {\r\n <sd-badge\r\n [attr.data-autoId]=\"autoId()\"\r\n [type]=\"view.badge.type\"\r\n [title]=\"view.data\"\r\n [color]=\"view.badge.color\"\r\n [icon]=\"view.badge.icon\"\r\n [sdTooltip]=\"view.tooltip || ''\"\r\n (click)=\"!!view.click && view.click()\">\r\n </sd-badge>\r\n }\r\n } @else {\r\n @if (view.click) {\r\n <div class=\"text-break\" [style]=\"view.cellStyle\" [sdTooltip]=\"view.tooltip || (isExpandByTooltip ? view.data : '') | asString\">\r\n <a\r\n href=\"javascript:;\"\r\n [attr.data-autoId]=\"autoId()\"\r\n [style.max-width]=\"charLimited()?.width\"\r\n [class.c-ellipsis]=\"columnCharLimit?.enable\"\r\n (click)=\"view.click()\">\r\n {{ view.data }}\r\n </a>\r\n </div>\r\n } @else {\r\n <!-- N\u1EBFu column c\u00F3 b\u1EADt \"gi\u1EDBi h\u1EA1n k\u00FD t\u1EF1\" -->\r\n @if (columnCharLimit?.enable) {\r\n <div\r\n #contentContainer\r\n [attr.data-autoId]=\"autoId()\"\r\n class=\"text-break\"\r\n [style]=\"view.cellStyle\"\r\n [style.max-width]=\"charLimited()?.width\"\r\n [class.c-ellipsis]=\"isCollapsed()\"\r\n [sdTooltip]=\"view.tooltip || (isExpandByTooltip ? view.data : '') | asString\">\r\n {{ view.data }}\r\n </div>\r\n\r\n <!-- N\u1EBFu option xem full th\u00F4ng tin l\u00E0 \"btn xem th\u00EAm\" -->\r\n @if (isExpandByMore) {\r\n <button (click)=\"toggle()\" class=\"c-collapse\">{{ isCollapsed() ? 'Xem th\u00EAm' : 'Thu g\u1ECDn' }}</button>\r\n }\r\n } @else {\r\n <div [attr.data-autoId]=\"autoId()\" class=\"text-break\" [style]=\"view.cellStyle\" [sdTooltip]=\"view.tooltip || ''\">\r\n {{ view.data }}\r\n </div>\r\n }\r\n <!-- End -->\r\n }\r\n }\r\n }\r\n}\r\n", styles: [".c-ellipsis{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.c-ellipsis-html{display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:1;line-clamp:1;text-overflow:ellipsis;overflow:hidden}.c-collapse{background:none;color:#00e;border:none;padding:0;font-size:12px;cursor:pointer;outline:none}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: SdBadge, selector: "sd-badge", inputs: ["type", "color", "primary", "secondary", "success", "info", "warning", "error", "fontSet", "title", "description", "tooltip", "icon", "size"], outputs: ["click"] }, { kind: "pipe", type: SdSafeHtmlPipe, name: "sdSafeHtml" }, { kind: "directive", type: SdTooltipDirective, selector: "[sdTooltip]", inputs: ["sdTooltip", "sdTooltipPosition", "sdTooltipDelay", "sdTooltipColor"] }, { kind: "pipe", type: ToStringPipe, name: "asString" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
869
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.17", type: SdDesktopCellView, isStandalone: true, selector: "sd-desktop-cell-view", inputs: { autoId: { classPropertyName: "autoId", publicName: "autoId", isSignal: true, isRequired: false, transformFunction: null }, column: { classPropertyName: "column", publicName: "column", isSignal: true, isRequired: true, transformFunction: null }, charLimited: { classPropertyName: "charLimited", publicName: "charLimited", isSignal: true, isRequired: false, transformFunction: null }, item: { classPropertyName: "item", publicName: "item", isSignal: true, isRequired: true, transformFunction: null } }, viewQueries: [{ propertyName: "contentContainer", first: true, predicate: ["contentContainer"], descendants: true, isSignal: true }], ngImport: i0, template: "@let view = item().meta.display[column().field];\r\n\r\n@let columnCharLimit = column()?.charLimited;\r\n@let isExpandByMore = isOverflowing() && columnCharLimit?.expandType === 'more';\r\n@let isExpandByTooltip = isOverflowing() && columnCharLimit?.expandType === 'tooltip';\r\n\r\n@if (view) {\r\n @if (view.isHtml) {\r\n @if (view.click) {\r\n <div\r\n #contentContainer\r\n [attr.data-autoId]=\"autoId()\"\r\n (click)=\"view.click()\"\r\n class=\"text-break cursor-pointer\"\r\n [sdTooltip]=\"view.tooltip || (isExpandByTooltip ? htmlClickTooltip : '')\"\r\n [style]=\"view.cellStyle\"\r\n [style.max-width]=\"charLimited()?.width\"\r\n [class.c-ellipsis-html]=\"columnCharLimit?.enable\"\r\n [innerHTML]=\"view.data | sdSafeHtml\"\r\n aria-hidden=\"true\"></div>\r\n\r\n <ng-template #htmlClickTooltip>\r\n <div\r\n class=\"c-tooltip-inner-content\"\r\n [style.max-width]=\"'calc(' + charLimited()?.width + ' * 1.5)'\"\r\n style=\"max-height: 200px; overflow-y: auto; scrollbar-width: thin\">\r\n <div [innerHTML]=\"view.data | sdSafeHtml\"></div>\r\n </div>\r\n </ng-template>\r\n } @else {\r\n <!-- N\u1EBFu column c\u00F3 b\u1EADt \"gi\u1EDBi h\u1EA1n k\u00FD t\u1EF1\" -->\r\n @if (columnCharLimit?.enable) {\r\n <div\r\n #contentContainer\r\n [style.max-width]=\"charLimited()?.width\"\r\n [class.c-ellipsis-html]=\"isCollapsed()\"\r\n [attr.data-autoId]=\"autoId()\"\r\n class=\"text-break\"\r\n [sdTooltip]=\"view.tooltip || (isExpandByTooltip ? htmlTooltip : '')\"\r\n containerClass=\"c-tooltip-html-d374bd93-f136-425c-bcc2-2d88cb163e44\"\r\n container=\"body\"\r\n placement=\"bottom\"\r\n [sdTooltipDelay]=\"100\"\r\n [style]=\"view.cellStyle\"\r\n [innerHTML]=\"view.data | sdSafeHtml\"></div>\r\n\r\n <ng-template #htmlTooltip>\r\n <div\r\n class=\"c-tooltip-inner-content\"\r\n [style.max-width]=\"'calc(' + charLimited()?.width + ' * 1.5)'\"\r\n style=\"max-height: 200px; overflow-y: auto; scrollbar-width: thin\">\r\n <div [innerHTML]=\"view.data | sdSafeHtml\"></div>\r\n </div>\r\n </ng-template>\r\n\r\n @if (isExpandByMore) {\r\n <button (click)=\"toggle()\" class=\"c-collapse\">{{ isCollapsed() ? 'Xem th\u00EAm' : 'Thu g\u1ECDn' }}</button>\r\n }\r\n } @else {\r\n <div\r\n [attr.data-autoId]=\"autoId()\"\r\n class=\"text-break\"\r\n [sdTooltip]=\"view.tooltip || ''\"\r\n [style]=\"view.cellStyle\"\r\n [innerHTML]=\"view.data | sdSafeHtml\"></div>\r\n }\r\n <!-- End -->\r\n }\r\n } @else {\r\n <!-- N\u1EBFu l\u00E0 gi\u00E1 tr\u1ECB l\u1EA5y hi\u1EC3n th\u1ECB l\u1EA5y tr\u1EF1c ti\u1EBFp t\u1EEB field -->\r\n @if (view.badge) {\r\n @if (view.data) {\r\n <sd-badge\r\n [attr.data-autoId]=\"autoId()\"\r\n [type]=\"view.badge.type\"\r\n [title]=\"view.data\"\r\n [color]=\"view.badge.color\"\r\n [icon]=\"view.badge.icon\"\r\n [sdTooltip]=\"view.tooltip || ''\"\r\n (click)=\"!!view.click && view.click()\">\r\n </sd-badge>\r\n }\r\n } @else {\r\n @if (view.click) {\r\n <div\r\n #contentContainer\r\n class=\"text-break\"\r\n [style]=\"view.cellStyle\"\r\n [style.max-width]=\"charLimited()?.width\"\r\n [class.c-ellipsis]=\"columnCharLimit?.enable\"\r\n [sdTooltip]=\"view.tooltip || (isExpandByTooltip ? view.data : '') | asString\">\r\n <a [attr.data-autoId]=\"autoId\" href=\"javascript:;\" (click)=\"view.click()\">\r\n {{ view.data }}\r\n </a>\r\n </div>\r\n } @else {\r\n <!-- N\u1EBFu column c\u00F3 b\u1EADt \"gi\u1EDBi h\u1EA1n k\u00FD t\u1EF1\" -->\r\n @if (columnCharLimit?.enable) {\r\n <div\r\n #contentContainer\r\n [attr.data-autoId]=\"autoId()\"\r\n class=\"text-break\"\r\n [style]=\"view.cellStyle\"\r\n [style.max-width]=\"charLimited()?.width\"\r\n [class.c-ellipsis]=\"isCollapsed()\"\r\n [sdTooltip]=\"view.tooltip || (isExpandByTooltip ? view.data : '') | asString\">\r\n {{ view.data }}\r\n </div>\r\n\r\n <!-- N\u1EBFu option xem full th\u00F4ng tin l\u00E0 \"btn xem th\u00EAm\" -->\r\n @if (isExpandByMore) {\r\n <button (click)=\"toggle()\" class=\"c-collapse\">{{ isCollapsed() ? 'Xem th\u00EAm' : 'Thu g\u1ECDn' }}</button>\r\n }\r\n } @else {\r\n <div [attr.data-autoId]=\"autoId()\" class=\"text-break\" [style]=\"view.cellStyle\" [sdTooltip]=\"view.tooltip || ''\">\r\n {{ view.data }}\r\n </div>\r\n }\r\n <!-- End -->\r\n }\r\n }\r\n }\r\n}\r\n", styles: [".c-ellipsis{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.c-ellipsis-html{display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:1;line-clamp:1;text-overflow:ellipsis;overflow:hidden}.c-collapse{background:none;color:#00e;border:none;padding:0;font-size:12px;cursor:pointer;outline:none}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: SdBadge, selector: "sd-badge", inputs: ["type", "color", "primary", "secondary", "success", "info", "warning", "error", "fontSet", "title", "description", "tooltip", "icon", "size"], outputs: ["click"] }, { kind: "pipe", type: SdSafeHtmlPipe, name: "sdSafeHtml" }, { kind: "directive", type: SdTooltipDirective, selector: "[sdTooltip]", inputs: ["sdTooltip", "sdTooltipPosition", "sdTooltipDelay", "sdTooltipColor"] }, { kind: "pipe", type: ToStringPipe, name: "asString" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
869
870
  }
870
871
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: SdDesktopCellView, decorators: [{
871
872
  type: Component,
872
- args: [{ selector: 'sd-desktop-cell-view', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [CommonModule, SdBadge, SdSafeHtmlPipe, SdTooltipDirective, ToStringPipe], template: "@let view = item().meta.display[column().field];\r\n\r\n@let columnCharLimit = column()?.charLimited;\r\n@let isExpandByMore = isOverflowing() && columnCharLimit?.expandType === 'more';\r\n@let isExpandByTooltip = isOverflowing() && columnCharLimit?.expandType === 'tooltip';\r\n\r\n@if (view) {\r\n @if (view.isHtml) {\r\n @if (view.click) {\r\n <div\r\n [attr.data-autoId]=\"autoId()\"\r\n (click)=\"view.click()\"\r\n class=\"text-break cursor-pointer\"\r\n [sdTooltip]=\"view.tooltip || (isExpandByTooltip ? htmlClickTooltip : '')\"\r\n [style]=\"view.cellStyle\"\r\n [style.max-width]=\"charLimited()?.width\"\r\n [class.c-ellipsis-html]=\"columnCharLimit?.enable\"\r\n [innerHTML]=\"view.data | sdSafeHtml\"\r\n aria-hidden=\"true\"></div>\r\n\r\n <ng-template #htmlClickTooltip>\r\n <div\r\n class=\"c-tooltip-inner-content\"\r\n [style.max-width]=\"'calc(' + charLimited()?.width + ' * 1.5)'\"\r\n style=\"max-height: 200px; overflow-y: auto; scrollbar-width: thin\">\r\n <div [innerHTML]=\"view.data | sdSafeHtml\"></div>\r\n </div>\r\n </ng-template>\r\n } @else {\r\n <!-- N\u1EBFu column c\u00F3 b\u1EADt \"gi\u1EDBi h\u1EA1n k\u00FD t\u1EF1\" -->\r\n @if (columnCharLimit?.enable) {\r\n <div\r\n #contentContainer\r\n [style.max-width]=\"charLimited()?.width\"\r\n [class.c-ellipsis-html]=\"isCollapsed()\"\r\n [attr.data-autoId]=\"autoId()\"\r\n class=\"text-break\"\r\n [sdTooltip]=\"view.tooltip || (isExpandByTooltip ? htmlTooltip : '')\"\r\n containerClass=\"c-tooltip-html-d374bd93-f136-425c-bcc2-2d88cb163e44\"\r\n container=\"body\"\r\n placement=\"bottom\"\r\n [sdTooltipDelay]=\"100\"\r\n [style]=\"view.cellStyle\"\r\n [innerHTML]=\"view.data | sdSafeHtml\"></div>\r\n\r\n <ng-template #htmlTooltip>\r\n <div\r\n class=\"c-tooltip-inner-content\"\r\n [style.max-width]=\"'calc(' + charLimited()?.width + ' * 1.5)'\"\r\n style=\"max-height: 200px; overflow-y: auto; scrollbar-width: thin\">\r\n <div [innerHTML]=\"view.data | sdSafeHtml\"></div>\r\n </div>\r\n </ng-template>\r\n\r\n @if (isExpandByMore) {\r\n <button (click)=\"toggle()\" class=\"c-collapse\">{{ isCollapsed() ? 'Xem th\u00EAm' : 'Thu g\u1ECDn' }}</button>\r\n }\r\n } @else {\r\n <div\r\n [attr.data-autoId]=\"autoId()\"\r\n class=\"text-break\"\r\n [sdTooltip]=\"view.tooltip || ''\"\r\n [style]=\"view.cellStyle\"\r\n [innerHTML]=\"view.data | sdSafeHtml\"></div>\r\n }\r\n <!-- End -->\r\n }\r\n } @else {\r\n <!-- N\u1EBFu l\u00E0 gi\u00E1 tr\u1ECB l\u1EA5y hi\u1EC3n th\u1ECB l\u1EA5y tr\u1EF1c ti\u1EBFp t\u1EEB field -->\r\n @if (view.badge) {\r\n @if (view.data) {\r\n <sd-badge\r\n [attr.data-autoId]=\"autoId()\"\r\n [type]=\"view.badge.type\"\r\n [title]=\"view.data\"\r\n [color]=\"view.badge.color\"\r\n [icon]=\"view.badge.icon\"\r\n [sdTooltip]=\"view.tooltip || ''\"\r\n (click)=\"!!view.click && view.click()\">\r\n </sd-badge>\r\n }\r\n } @else {\r\n @if (view.click) {\r\n <div class=\"text-break\" [style]=\"view.cellStyle\" [sdTooltip]=\"view.tooltip || (isExpandByTooltip ? view.data : '') | asString\">\r\n <a\r\n href=\"javascript:;\"\r\n [attr.data-autoId]=\"autoId()\"\r\n [style.max-width]=\"charLimited()?.width\"\r\n [class.c-ellipsis]=\"columnCharLimit?.enable\"\r\n (click)=\"view.click()\">\r\n {{ view.data }}\r\n </a>\r\n </div>\r\n } @else {\r\n <!-- N\u1EBFu column c\u00F3 b\u1EADt \"gi\u1EDBi h\u1EA1n k\u00FD t\u1EF1\" -->\r\n @if (columnCharLimit?.enable) {\r\n <div\r\n #contentContainer\r\n [attr.data-autoId]=\"autoId()\"\r\n class=\"text-break\"\r\n [style]=\"view.cellStyle\"\r\n [style.max-width]=\"charLimited()?.width\"\r\n [class.c-ellipsis]=\"isCollapsed()\"\r\n [sdTooltip]=\"view.tooltip || (isExpandByTooltip ? view.data : '') | asString\">\r\n {{ view.data }}\r\n </div>\r\n\r\n <!-- N\u1EBFu option xem full th\u00F4ng tin l\u00E0 \"btn xem th\u00EAm\" -->\r\n @if (isExpandByMore) {\r\n <button (click)=\"toggle()\" class=\"c-collapse\">{{ isCollapsed() ? 'Xem th\u00EAm' : 'Thu g\u1ECDn' }}</button>\r\n }\r\n } @else {\r\n <div [attr.data-autoId]=\"autoId()\" class=\"text-break\" [style]=\"view.cellStyle\" [sdTooltip]=\"view.tooltip || ''\">\r\n {{ view.data }}\r\n </div>\r\n }\r\n <!-- End -->\r\n }\r\n }\r\n }\r\n}\r\n", styles: [".c-ellipsis{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.c-ellipsis-html{display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:1;line-clamp:1;text-overflow:ellipsis;overflow:hidden}.c-collapse{background:none;color:#00e;border:none;padding:0;font-size:12px;cursor:pointer;outline:none}\n"] }]
873
+ args: [{ selector: 'sd-desktop-cell-view', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [CommonModule, SdBadge, SdSafeHtmlPipe, SdTooltipDirective, ToStringPipe], template: "@let view = item().meta.display[column().field];\r\n\r\n@let columnCharLimit = column()?.charLimited;\r\n@let isExpandByMore = isOverflowing() && columnCharLimit?.expandType === 'more';\r\n@let isExpandByTooltip = isOverflowing() && columnCharLimit?.expandType === 'tooltip';\r\n\r\n@if (view) {\r\n @if (view.isHtml) {\r\n @if (view.click) {\r\n <div\r\n #contentContainer\r\n [attr.data-autoId]=\"autoId()\"\r\n (click)=\"view.click()\"\r\n class=\"text-break cursor-pointer\"\r\n [sdTooltip]=\"view.tooltip || (isExpandByTooltip ? htmlClickTooltip : '')\"\r\n [style]=\"view.cellStyle\"\r\n [style.max-width]=\"charLimited()?.width\"\r\n [class.c-ellipsis-html]=\"columnCharLimit?.enable\"\r\n [innerHTML]=\"view.data | sdSafeHtml\"\r\n aria-hidden=\"true\"></div>\r\n\r\n <ng-template #htmlClickTooltip>\r\n <div\r\n class=\"c-tooltip-inner-content\"\r\n [style.max-width]=\"'calc(' + charLimited()?.width + ' * 1.5)'\"\r\n style=\"max-height: 200px; overflow-y: auto; scrollbar-width: thin\">\r\n <div [innerHTML]=\"view.data | sdSafeHtml\"></div>\r\n </div>\r\n </ng-template>\r\n } @else {\r\n <!-- N\u1EBFu column c\u00F3 b\u1EADt \"gi\u1EDBi h\u1EA1n k\u00FD t\u1EF1\" -->\r\n @if (columnCharLimit?.enable) {\r\n <div\r\n #contentContainer\r\n [style.max-width]=\"charLimited()?.width\"\r\n [class.c-ellipsis-html]=\"isCollapsed()\"\r\n [attr.data-autoId]=\"autoId()\"\r\n class=\"text-break\"\r\n [sdTooltip]=\"view.tooltip || (isExpandByTooltip ? htmlTooltip : '')\"\r\n containerClass=\"c-tooltip-html-d374bd93-f136-425c-bcc2-2d88cb163e44\"\r\n container=\"body\"\r\n placement=\"bottom\"\r\n [sdTooltipDelay]=\"100\"\r\n [style]=\"view.cellStyle\"\r\n [innerHTML]=\"view.data | sdSafeHtml\"></div>\r\n\r\n <ng-template #htmlTooltip>\r\n <div\r\n class=\"c-tooltip-inner-content\"\r\n [style.max-width]=\"'calc(' + charLimited()?.width + ' * 1.5)'\"\r\n style=\"max-height: 200px; overflow-y: auto; scrollbar-width: thin\">\r\n <div [innerHTML]=\"view.data | sdSafeHtml\"></div>\r\n </div>\r\n </ng-template>\r\n\r\n @if (isExpandByMore) {\r\n <button (click)=\"toggle()\" class=\"c-collapse\">{{ isCollapsed() ? 'Xem th\u00EAm' : 'Thu g\u1ECDn' }}</button>\r\n }\r\n } @else {\r\n <div\r\n [attr.data-autoId]=\"autoId()\"\r\n class=\"text-break\"\r\n [sdTooltip]=\"view.tooltip || ''\"\r\n [style]=\"view.cellStyle\"\r\n [innerHTML]=\"view.data | sdSafeHtml\"></div>\r\n }\r\n <!-- End -->\r\n }\r\n } @else {\r\n <!-- N\u1EBFu l\u00E0 gi\u00E1 tr\u1ECB l\u1EA5y hi\u1EC3n th\u1ECB l\u1EA5y tr\u1EF1c ti\u1EBFp t\u1EEB field -->\r\n @if (view.badge) {\r\n @if (view.data) {\r\n <sd-badge\r\n [attr.data-autoId]=\"autoId()\"\r\n [type]=\"view.badge.type\"\r\n [title]=\"view.data\"\r\n [color]=\"view.badge.color\"\r\n [icon]=\"view.badge.icon\"\r\n [sdTooltip]=\"view.tooltip || ''\"\r\n (click)=\"!!view.click && view.click()\">\r\n </sd-badge>\r\n }\r\n } @else {\r\n @if (view.click) {\r\n <div\r\n #contentContainer\r\n class=\"text-break\"\r\n [style]=\"view.cellStyle\"\r\n [style.max-width]=\"charLimited()?.width\"\r\n [class.c-ellipsis]=\"columnCharLimit?.enable\"\r\n [sdTooltip]=\"view.tooltip || (isExpandByTooltip ? view.data : '') | asString\">\r\n <a [attr.data-autoId]=\"autoId\" href=\"javascript:;\" (click)=\"view.click()\">\r\n {{ view.data }}\r\n </a>\r\n </div>\r\n } @else {\r\n <!-- N\u1EBFu column c\u00F3 b\u1EADt \"gi\u1EDBi h\u1EA1n k\u00FD t\u1EF1\" -->\r\n @if (columnCharLimit?.enable) {\r\n <div\r\n #contentContainer\r\n [attr.data-autoId]=\"autoId()\"\r\n class=\"text-break\"\r\n [style]=\"view.cellStyle\"\r\n [style.max-width]=\"charLimited()?.width\"\r\n [class.c-ellipsis]=\"isCollapsed()\"\r\n [sdTooltip]=\"view.tooltip || (isExpandByTooltip ? view.data : '') | asString\">\r\n {{ view.data }}\r\n </div>\r\n\r\n <!-- N\u1EBFu option xem full th\u00F4ng tin l\u00E0 \"btn xem th\u00EAm\" -->\r\n @if (isExpandByMore) {\r\n <button (click)=\"toggle()\" class=\"c-collapse\">{{ isCollapsed() ? 'Xem th\u00EAm' : 'Thu g\u1ECDn' }}</button>\r\n }\r\n } @else {\r\n <div [attr.data-autoId]=\"autoId()\" class=\"text-break\" [style]=\"view.cellStyle\" [sdTooltip]=\"view.tooltip || ''\">\r\n {{ view.data }}\r\n </div>\r\n }\r\n <!-- End -->\r\n }\r\n }\r\n }\r\n}\r\n", styles: [".c-ellipsis{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.c-ellipsis-html{display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:1;line-clamp:1;text-overflow:ellipsis;overflow:hidden}.c-collapse{background:none;color:#00e;border:none;padding:0;font-size:12px;cursor:pointer;outline:none}\n"] }]
873
874
  }], ctorParameters: () => [] });
874
875
 
875
876
  class SdDesktopCell {
@@ -895,7 +896,8 @@ class SdDesktopCell {
895
896
  isCollapsed = signal(true);
896
897
  isOverflowing = signal(false);
897
898
  constructor() {
898
- afterNextRender(() => {
899
+ effect(() => {
900
+ this.charLimited();
899
901
  const container = this.contentContainer();
900
902
  if (container) {
901
903
  this.#checkOverflow(container.nativeElement);