@sd-angular/core 19.0.48 → 19.0.50
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/components/modal/src/modal.component.d.ts +10 -1
- package/fesm2022/sd-angular-core-components-form-generic.mjs +9 -9
- package/fesm2022/sd-angular-core-components-form-generic.mjs.map +1 -1
- package/fesm2022/sd-angular-core-components-import-excel.mjs +1 -1
- package/fesm2022/sd-angular-core-components-import-excel.mjs.map +1 -1
- package/fesm2022/sd-angular-core-components-modal.mjs +20 -3
- package/fesm2022/sd-angular-core-components-modal.mjs.map +1 -1
- package/fesm2022/sd-angular-core-components-table.mjs +30 -20
- package/fesm2022/sd-angular-core-components-table.mjs.map +1 -1
- package/fesm2022/sd-angular-core-components-upload-file.mjs +1 -1
- package/fesm2022/sd-angular-core-components-upload-file.mjs.map +1 -1
- package/fesm2022/sd-angular-core-directives.mjs +20 -3
- package/fesm2022/sd-angular-core-directives.mjs.map +1 -1
- package/fesm2022/sd-angular-core-forms-select.mjs +23 -4
- package/fesm2022/sd-angular-core-forms-select.mjs.map +1 -1
- package/fesm2022/sd-angular-core-pipes.mjs +11 -21
- package/fesm2022/sd-angular-core-pipes.mjs.map +1 -1
- package/fesm2022/sd-angular-core-services-confirm.mjs +114 -122
- package/fesm2022/sd-angular-core-services-confirm.mjs.map +1 -1
- package/package.json +144 -144
- package/services/confirm/src/lib/components/dialog-confirm/dialog-confirm.component.d.ts +4 -1
- package/services/confirm/src/lib/confirm.service.d.ts +24 -8
- package/services/confirm/src/public-api.d.ts +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sd-angular-core-pipes.mjs","sources":["../../../projects/sd-angular/pipes/src/format-number.pipe.ts","../../../projects/sd-angular/pipes/src/safe-html.pipe.ts","../../../projects/sd-angular/pipes/src/time-different.pipe.ts","../../../projects/sd-angular/pipes/src/empty.pipe.ts","../../../projects/sd-angular/pipes/sd-angular-core-pipes.ts"],"sourcesContent":["import { inject, Injectable, Pipe, PipeTransform } from '@angular/core';\nimport { ISdCoreConfiguration, SD_CORE_CONFIGURATION } from '@sd-angular/core/configurations';\nimport { NumberUtilities } from '@sd-angular/core/utilities/extensions';\n@Pipe({\n name: 'sdFormatNumber',\n standalone: true,\n})\n@Injectable({\n providedIn: 'root',\n})\nexport class SdFormatNumberPipe implements PipeTransform {\n private readonly coreConfiguration: ISdCoreConfiguration | null = inject(SD_CORE_CONFIGURATION, { optional: true });\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n transform(value: any, digits?: number, format?: '1,234,567.89' | '1.234.567,89') {\n const resolvedFormat = format ?? this.coreConfiguration?.format?.number;\n const fixedValue = NumberUtilities.isNumber(value) ? (+value).toFixed(digits ?? 2) : null;\n if (resolvedFormat === '1.234.567,89') {\n return NumberUtilities.toVN(fixedValue);\n }\n return NumberUtilities.toISO(fixedValue);\n }\n}\n","import { Injectable, Pipe, PipeTransform } from '@angular/core';\nimport { DomSanitizer } from '@angular/platform-browser';\n\n@Pipe({\n name: 'sdSafeHtml',\n standalone: true,\n})\n@Injectable({\n providedIn: 'root',\n})\nexport class SdSafeHtmlPipe implements PipeTransform {\n constructor(private sanitizer: DomSanitizer) {}\n transform(html: string | number | undefined | null) {\n if (typeof html === 'number') {\n return html;\n }\n if (!html) {\n return undefined;\n }\n return this.sanitizer.bypassSecurityTrustHtml(html);\n }\n}\n","/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { Pipe, PipeTransform } from '@angular/core';\nimport { ɵSD_LOCAL_DATE_TIME, ɵsdInjectDateTime } from '@sd-angular/core/services/date-time';\nimport { DateUtilities } from '@sd-angular/core/utilities/extensions';\nimport { interval, Observable, of } from 'rxjs';\nimport { map } from 'rxjs/operators';\n@Pipe({\n name: 'sdTimeDifferent',\n standalone: true,\n})\nexport class SdTimeDifferentPipe implements PipeTransform {\n // why: `new SdTimeDifferentPipe()` outside an injection context keeps the local behavior (no zone).\n readonly #dateTime = ɵsdInjectDateTime();\n\n private maxSecond = 60;\n private maxMinute = this.maxSecond * 60;\n private maxHour = this.maxMinute * 24;\n private maxDay = this.maxHour * 30;\n private maxMonth = this.maxHour * 365;\n transform(value: any, format: string, different: 'second' | 'minute' | 'hour' | 'day' | 'month'): Observable<string> {\n if (!DateUtilities.isDate(value)) {\n return of('');\n }\n if (!different) {\n return of(this.#format(value, format));\n }\n if (Math.round((new Date().getTime() - this.#instant(value)) / 1000) < 0) {\n return of(this.#format(value, format));\n }\n return interval(1000).pipe(\n map(() => {\n const timeDifferent = Math.round((new Date().getTime() - this.#instant(value)) / 1000);\n if (different === 'month' && timeDifferent < this.maxMonth) {\n return this.#relative(value);\n }\n if (different === 'day' && timeDifferent < this.maxDay) {\n return this.#relative(value);\n }\n if (different === 'hour' && timeDifferent < this.maxHour) {\n return this.#relative(value);\n }\n if (different === 'minute' && timeDifferent < this.maxMinute) {\n return this.#relative(value);\n }\n if (different === 'second' && timeDifferent < this.maxSecond) {\n return this.#relative(value);\n }\n return this.#format(value, format);\n })\n );\n }\n\n #format(value: any, format: string): string {\n return (this.#dateTime ?? ɵSD_LOCAL_DATE_TIME).toFormat(value, format);\n }\n\n // why: local mode keeps the native parse it always used; a zone reads zone-less values as wall clock in the zone.\n #instant(value: any): number {\n return this.#zoned() ? (this.#dateTime!.parse(value)?.getTime() ?? NaN) : new Date(value).getTime();\n }\n\n #relative(value: any): string {\n return this.#zoned() ? DateUtilities.timeDifference(new Date(this.#instant(value))) : DateUtilities.timeDifference(value);\n }\n\n #zoned(): boolean {\n return !!this.#dateTime && this.#dateTime.timeZone !== 'local';\n }\n}\n","/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { Pipe, PipeTransform } from '@angular/core';\nimport { EMPTY_STR } from '@sdcorejs/utils/constants';\n@Pipe({\n name: 'sdEmpty',\n standalone: true,\n})\nexport class SdEmptyPipe implements PipeTransform {\n transform(value: any): string {\n if (value === undefined || value === null || value === '') {\n return EMPTY_STR;\n }\n return value;\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":["ɵsdInjectDateTime","ɵSD_LOCAL_DATE_TIME"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"sd-angular-core-pipes.mjs","sources":["../../../projects/sd-angular/pipes/src/format-number.pipe.ts","../../../projects/sd-angular/pipes/src/safe-html.pipe.ts","../../../projects/sd-angular/pipes/src/time-different.pipe.ts","../../../projects/sd-angular/pipes/src/empty.pipe.ts","../../../projects/sd-angular/pipes/sd-angular-core-pipes.ts"],"sourcesContent":["import { inject, Injectable, Pipe, PipeTransform } from '@angular/core';\nimport { ISdCoreConfiguration, SD_CORE_CONFIGURATION } from '@sd-angular/core/configurations';\nimport { NumberUtilities } from '@sd-angular/core/utilities/extensions';\n@Pipe({\n name: 'sdFormatNumber',\n standalone: true,\n})\n@Injectable({\n providedIn: 'root',\n})\nexport class SdFormatNumberPipe implements PipeTransform {\n private readonly coreConfiguration: ISdCoreConfiguration | null = inject(SD_CORE_CONFIGURATION, { optional: true });\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n transform(value: any, digits?: number, format?: '1,234,567.89' | '1.234.567,89') {\n const resolvedFormat = format ?? this.coreConfiguration?.format?.number;\n const fixedValue = NumberUtilities.isNumber(value) ? (+value).toFixed(digits ?? 2) : null;\n if (resolvedFormat === '1.234.567,89') {\n return NumberUtilities.toVN(fixedValue);\n }\n return NumberUtilities.toISO(fixedValue);\n }\n}\n","import { Injectable, Pipe, PipeTransform } from '@angular/core';\nimport { DomSanitizer } from '@angular/platform-browser';\n\n@Pipe({\n name: 'sdSafeHtml',\n standalone: true,\n})\n@Injectable({\n providedIn: 'root',\n})\nexport class SdSafeHtmlPipe implements PipeTransform {\n constructor(private sanitizer: DomSanitizer) {}\n transform(html: string | number | undefined | null) {\n if (typeof html === 'number') {\n return html;\n }\n if (!html) {\n return undefined;\n }\n return this.sanitizer.bypassSecurityTrustHtml(html);\n }\n}\n","/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { Pipe, PipeTransform } from '@angular/core';\nimport { ɵSD_LOCAL_DATE_TIME, ɵsdInjectDateTime } from '@sd-angular/core/services/date-time';\nimport { DateUtilities } from '@sd-angular/core/utilities/extensions';\nimport { interval, Observable, of } from 'rxjs';\nimport { map, takeWhile } from 'rxjs/operators';\n@Pipe({\n name: 'sdTimeDifferent',\n standalone: true,\n})\nexport class SdTimeDifferentPipe implements PipeTransform {\n // why: `new SdTimeDifferentPipe()` outside an injection context keeps the local behavior (no zone).\n readonly #dateTime = ɵsdInjectDateTime();\n\n private maxSecond = 60;\n private maxMinute = this.maxSecond * 60;\n private maxHour = this.maxMinute * 24;\n private maxDay = this.maxHour * 30;\n private maxMonth = this.maxHour * 365;\n transform(value: any, format: string, different: 'second' | 'minute' | 'hour' | 'day' | 'month'): Observable<string> {\n if (!DateUtilities.isDate(value)) {\n return of('');\n }\n if (!different) {\n return of(this.#format(value, format));\n }\n const elapsedSeconds = () => Math.round((Date.now() - this.#instant(value)) / 1000);\n if (elapsedSeconds() < 0) {\n return of(this.#format(value, format));\n }\n const thresholds = { second: this.maxSecond, minute: this.maxMinute, hour: this.maxHour, day: this.maxDay, month: this.maxMonth };\n const threshold = thresholds[different];\n // why: ngày đã quá ngưỡng chỉ hiển thị chuỗi cố định, không cần một timer cho mỗi ô.\n if (elapsedSeconds() >= threshold) return of(this.#format(value, format));\n return interval(1000).pipe(\n map(elapsedSeconds),\n // why: phát giá trị ngày tuyệt đối lần cuối rồi dừng timer khi vượt ngưỡng tương đối.\n takeWhile(elapsed => elapsed < threshold, true),\n map(elapsed => (elapsed < threshold ? this.#relative(value) : this.#format(value, format)))\n );\n }\n\n #format(value: any, format: string): string {\n return (this.#dateTime ?? ɵSD_LOCAL_DATE_TIME).toFormat(value, format);\n }\n\n // why: local mode keeps the native parse it always used; a zone reads zone-less values as wall clock in the zone.\n #instant(value: any): number {\n return this.#zoned() ? (this.#dateTime!.parse(value)?.getTime() ?? NaN) : new Date(value).getTime();\n }\n\n #relative(value: any): string {\n return this.#zoned() ? DateUtilities.timeDifference(new Date(this.#instant(value))) : DateUtilities.timeDifference(value);\n }\n\n #zoned(): boolean {\n return !!this.#dateTime && this.#dateTime.timeZone !== 'local';\n }\n}\n","/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { Pipe, PipeTransform } from '@angular/core';\nimport { EMPTY_STR } from '@sdcorejs/utils/constants';\n@Pipe({\n name: 'sdEmpty',\n standalone: true,\n})\nexport class SdEmptyPipe implements PipeTransform {\n transform(value: any): string {\n if (value === undefined || value === null || value === '') {\n return EMPTY_STR;\n }\n return value;\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":["ɵsdInjectDateTime","ɵSD_LOCAL_DATE_TIME"],"mappings":"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"}
|
|
@@ -1,24 +1,33 @@
|
|
|
1
|
-
import { CommonModule } from '@angular/common';
|
|
2
1
|
import * as i0 from '@angular/core';
|
|
3
2
|
import { inject, Component, Injectable } from '@angular/core';
|
|
3
|
+
import { MatBottomSheetRef, MAT_BOTTOM_SHEET_DATA, MatBottomSheet } from '@angular/material/bottom-sheet';
|
|
4
|
+
import * as i1 from '@angular/common';
|
|
5
|
+
import { CommonModule } from '@angular/common';
|
|
4
6
|
import { FormsModule } from '@angular/forms';
|
|
5
|
-
import * as
|
|
7
|
+
import * as i2 from '@angular/material/dialog';
|
|
6
8
|
import { MatDialogRef, MAT_DIALOG_DATA, MatDialogModule } from '@angular/material/dialog';
|
|
7
|
-
import * as
|
|
9
|
+
import * as i3 from '@angular/material/icon';
|
|
8
10
|
import { MatIconModule } from '@angular/material/icon';
|
|
9
11
|
import { SdButton } from '@sd-angular/core/components/button';
|
|
10
12
|
import { SdDate } from '@sd-angular/core/forms/date';
|
|
11
13
|
import { SdRadio } from '@sd-angular/core/forms/radio';
|
|
12
14
|
import { SdTextarea } from '@sd-angular/core/forms/textarea';
|
|
13
|
-
import { Utilities } from '@sdcorejs/utils/fns';
|
|
15
|
+
import { Utilities, BrowserUtilities } from '@sdcorejs/utils/fns';
|
|
14
16
|
import { I18nService } from '@sd-angular/core/i18n';
|
|
15
17
|
|
|
16
18
|
class DialogConfirmComponent {
|
|
17
19
|
value;
|
|
18
20
|
required = false;
|
|
19
21
|
id = `I${Utilities.generateUuid()}`;
|
|
20
|
-
|
|
21
|
-
|
|
22
|
+
// why: cùng một component chạy trong MatDialog hoặc MatBottomSheet nên cả hai ref đều là tùy chọn. SdConfirmService
|
|
23
|
+
// quyết định kiểu hiển thị; component chỉ dùng ref đang có.
|
|
24
|
+
dialogRef = inject((MatDialogRef), { optional: true });
|
|
25
|
+
#bottomSheetRef = inject((MatBottomSheetRef), { optional: true });
|
|
26
|
+
/** `true` khi component được mở trong bottom sheet; dùng để chọn bố cục nút mobile. */
|
|
27
|
+
isBottomSheet = !!this.#bottomSheetRef;
|
|
28
|
+
data = (this.isBottomSheet
|
|
29
|
+
? inject(MAT_BOTTOM_SHEET_DATA, { optional: true })
|
|
30
|
+
: inject(MAT_DIALOG_DATA, { optional: true })) ?? {};
|
|
22
31
|
constructor() {
|
|
23
32
|
if (this.data?.input) {
|
|
24
33
|
this.value = this.data?.input?.defaultValue ?? '';
|
|
@@ -33,155 +42,137 @@ class DialogConfirmComponent {
|
|
|
33
42
|
this.required = this.data?.radio?.required || false;
|
|
34
43
|
}
|
|
35
44
|
}
|
|
45
|
+
#close(result) {
|
|
46
|
+
if (this.#bottomSheetRef) {
|
|
47
|
+
this.#bottomSheetRef.dismiss(result);
|
|
48
|
+
}
|
|
49
|
+
else {
|
|
50
|
+
this.dialogRef?.close(result);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
36
53
|
onCancel = () => {
|
|
37
|
-
this
|
|
54
|
+
this.#close({ action: 'CANCEL', value: null });
|
|
38
55
|
};
|
|
39
56
|
onAccept = () => {
|
|
40
57
|
// Always return an object with action and value for consistency
|
|
41
58
|
if (this.data?.radio || this.data?.input || this.data?.date) {
|
|
42
|
-
this
|
|
59
|
+
this.#close({ action: 'ACCEPT', value: this.value });
|
|
43
60
|
}
|
|
44
61
|
else {
|
|
45
|
-
this
|
|
62
|
+
this.#close({ action: 'ACCEPT', value: null });
|
|
46
63
|
}
|
|
47
64
|
};
|
|
48
65
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: DialogConfirmComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
49
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.21", type: DialogConfirmComponent, isStandalone: true, selector: "sd-dialog-confirm", ngImport: i0, template: "<div mat-dialog-title class=\"\">\n @if (data.icon) {\n <mat-icon>\n {{ data.icon }}\n </mat-icon>\n }\n <span class=\"T24M\" [innerHtml]=\"data.title || 'Confirm'\"></span>\n</div>\n<div mat-dialog-content>\n <div class=\"T14R mb-4\" [innerHtml]=\"data.message\"></div>\n @if (data.input) {\n <sd-textarea [placeholder]=\"data.input.placeholder\" [(model)]=\"value\" [rows]=\"5\" [maxlength]=\"data.input.maxlength!\" />\n }\n @if (data.date) {\n <sd-date [clearable]=\"true\"\n [placeholder]=\"data.date.placeholder\"\n [(model)]=\"value\"\n type=\"date\"\n [min]=\"data.date.min!\"\n [max]=\"data.date.max!\"\n [required]=\"data.date.required\">\n </sd-date>\n }\n @if (data.radio) {\n <sd-radio\n [items]=\"data.radio.items\"\n [valueField]=\"data.radio.valueField\"\n [displayField]=\"data.radio.displayField\"\n [display]=\"data.radio.display || 'column'\"\n [(model)]=\"value\"\n [required]=\"data.radio.required\">\n </sd-radio>\n }\n</div>\n<div mat-dialog-actions align=\"end\">\n @if (data.noTitle) {\n <sd-button [color]=\"data.noButtonColor || 'secondary'\" [title]=\"data.noTitle\" (click)=\"onCancel()\"></sd-button>\n }\n @if (data.yesTitle) {\n <sd-button\n class=\"ml-8\"\n type=\"fill\"\n [color]=\"data.yesButtonColor || 'primary'\"\n [disabled]=\"required && !value\"\n cdkFocusInitial\n [title]=\"data.yesTitle\"\n (click)=\"onAccept()\"></sd-button>\n }\n</div>\n", styles: [".text-primary{color:var(--sd-primary)!important}.bg-primary{background:var(--sd-primary)!important}.border-primary{border-color:var(--sd-primary)!important}.text-primary-light{color:var(--sd-primary-light)!important}.bg-primary-light{background:var(--sd-primary-light)!important}.border-primary-light{border-color:var(--sd-primary-light)!important}.text-primary-dark{color:var(--sd-primary-dark)!important}.bg-primary-dark{background:var(--sd-primary-dark)!important}.border-primary-dark{border-color:var(--sd-primary-dark)!important}.text-info{color:var(--sd-info)!important}.bg-info{background:var(--sd-info)!important}.border-info{border-color:var(--sd-info)!important}.text-info-light{color:var(--sd-info-light)!important}.bg-info-light{background:var(--sd-info-light)!important}.border-info-light{border-color:var(--sd-info-light)!important}.text-info-dark{color:var(--sd-info-dark)!important}.bg-info-dark{background:var(--sd-info-dark)!important}.border-info-dark{border-color:var(--sd-info-dark)!important}.text-success{color:var(--sd-success)!important}.bg-success{background:var(--sd-success)!important}.border-success{border-color:var(--sd-success)!important}.text-success-light{color:var(--sd-success-light)!important}.bg-success-light{background:var(--sd-success-light)!important}.border-success-light{border-color:var(--sd-success-light)!important}.text-success-dark{color:var(--sd-success-dark)!important}.bg-success-dark{background:var(--sd-success-dark)!important}.border-success-dark{border-color:var(--sd-success-dark)!important}.text-warning{color:var(--sd-warning)!important}.bg-warning{background:var(--sd-warning)!important}.border-warning{border-color:var(--sd-warning)!important}.text-warning-light{color:var(--sd-warning-light)!important}.bg-warning-light{background:var(--sd-warning-light)!important}.border-warning-light{border-color:var(--sd-warning-light)!important}.text-warning-dark{color:var(--sd-warning-dark)!important}.bg-warning-dark{background:var(--sd-warning-dark)!important}.border-warning-dark{border-color:var(--sd-warning-dark)!important}.text-error{color:var(--sd-error)!important}.bg-error{background:var(--sd-error)!important}.border-error{border-color:var(--sd-error)!important}.text-error-light{color:var(--sd-error-light)!important}.bg-error-light{background:var(--sd-error-light)!important}.border-error-light{border-color:var(--sd-error-light)!important}.text-error-dark{color:var(--sd-error-dark)!important}.bg-error-dark{background:var(--sd-error-dark)!important}.border-error-dark{border-color:var(--sd-error-dark)!important}.text-secondary{color:var(--sd-secondary)!important}.bg-secondary{background:var(--sd-secondary)!important}.border-secondary{border-color:var(--sd-secondary)!important}.text-secondary-light{color:var(--sd-secondary-light)!important}.bg-secondary-light{background:var(--sd-secondary-light)!important}.border-secondary-light{border-color:var(--sd-secondary-light)!important}.text-secondary-dark{color:var(--sd-secondary-dark)!important}.bg-secondary-dark{background:var(--sd-secondary-dark)!important}.border-secondary-dark{border-color:var(--sd-secondary-dark)!important}.text-light{color:var(--sd-light)!important}.bg-light{background:var(--sd-light)!important}.border-light{border-color:var(--sd-light)!important}.text-dark{color:var(--sd-dark)!important}.bg-dark{background:var(--sd-dark)!important}.border-dark{border-color:var(--sd-dark)!important}.text-black500{color:var(--sd-black500)!important}.bg-black500{background:var(--sd-black500)!important}.border-black500{border-color:var(--sd-black500)!important}.text-black400{color:var(--sd-black400)!important}.bg-black400{background:var(--sd-black400)!important}.border-black400{border-color:var(--sd-black400)!important}.text-black300{color:var(--sd-black300)!important}.bg-black300{background:var(--sd-black300)!important}.border-black300{border-color:var(--sd-black300)!important}.text-black200{color:var(--sd-black200)!important}.bg-black200{background:var(--sd-black200)!important}.border-black200{border-color:var(--sd-black200)!important}.text-black100{color:var(--sd-black100)!important}.bg-black100{background:var(--sd-black100)!important}.border-black100{border-color:var(--sd-black100)!important}.text-white{color:#fff!important}.bg-white{background:#fff!important}.border-white{border-color:#fff!important}.text-black{color:#000!important}.bg-black{background:#000!important}.border-black{border-color:#000!important}:host .mat-dialog-content{margin:0 -16px 16px!important}:host .mat-button{background-color:#f5f5f5}:host ::ng-deep .mat-dialog-title{display:flex;align-items:center;justify-content:flex-start}:host ::ng-deep .mat-dialog-title .mat-icon{margin-right:5px}:host{display:block}:host ::ng-deep .mat-dialog-title .mat-icon.info{color:var(--sd-info)}:host ::ng-deep .mat-dialog-title .mat-icon.warning{color:var(--sd-warning)}:host ::ng-deep .mat-dialog-title .mat-icon.success{color:var(--sd-success)}:host ::ng-deep .mat-dialog-title .mat-icon.error{color:var(--sd-error)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "ngmodule", type: MatDialogModule }, { kind: "directive", type: i1.MatDialogTitle, selector: "[mat-dialog-title], [matDialogTitle]", inputs: ["id"], exportAs: ["matDialogTitle"] }, { kind: "directive", type: i1.MatDialogActions, selector: "[mat-dialog-actions], mat-dialog-actions, [matDialogActions]", inputs: ["align"] }, { kind: "directive", type: i1.MatDialogContent, selector: "[mat-dialog-content], mat-dialog-content, [matDialogContent]" }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: SdButton, selector: "sd-button", inputs: ["autoId", "type", "color", "size", "fontSet", "title", "width", "tooltip", "prefixIcon", "suffixIcon", "disabled", "loading", "block", "htmlType"], outputs: ["click"] }, { kind: "component", type: SdDate, selector: "sd-date", inputs: ["autoId", "name", "size", "form", "label", "helperText", "placeholder", "hideInlineError", "required", "disabled", "viewed", "clearable", "inlineError", "hyperlink", "appearance", "floatLabel", "min", "minDate", "max", "maxDate", "model"], outputs: ["modelChange", "sdChange", "sdFocus"] }, { kind: "component", type: SdRadio, selector: "sd-radio", inputs: ["autoId", "name", "form", "label", "placeholder", "display", "items", "valueField", "displayField", "required", "inlineError", "disabled", "viewed", "color", "hyperlink", "model"], outputs: ["modelChange", "sdChange", "sdSelection"] }, { kind: "component", type: SdTextarea, selector: "sd-textarea", inputs: ["autoId", "name", "size", "form", "label", "helperText", "placeholder", "rows", "hideInlineError", "required", "disabled", "viewed", "autoHeight", "maxlength", "pattern", "validator", "inlineError", "appearance", "floatLabel", "model"], outputs: ["modelChange", "sdChange"] }] });
|
|
66
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.21", type: DialogConfirmComponent, isStandalone: true, selector: "sd-dialog-confirm", ngImport: i0, template: "<ng-template #fields>\n @if (data.input) {\n <sd-textarea [placeholder]=\"data.input.placeholder\" [(model)]=\"value\" [rows]=\"5\" [maxlength]=\"data.input.maxlength!\" />\n }\n @if (data.date) {\n <sd-date [clearable]=\"true\"\n [placeholder]=\"data.date.placeholder\"\n [(model)]=\"value\"\n type=\"date\"\n [min]=\"data.date.min!\"\n [max]=\"data.date.max!\"\n [required]=\"data.date.required\">\n </sd-date>\n }\n @if (data.radio) {\n <sd-radio\n [items]=\"data.radio.items\"\n [valueField]=\"data.radio.valueField\"\n [displayField]=\"data.radio.displayField\"\n [display]=\"data.radio.display || 'column'\"\n [(model)]=\"value\"\n [required]=\"data.radio.required\">\n </sd-radio>\n }\n</ng-template>\n\n@if (isBottomSheet) {\n <!-- why: trong bottom sheet kh\u00F4ng d\u00F9ng directive mat-dialog-* (ch\u00FAng g\u1EAFn v\u1EDBi MatDialogRef); n\u00FAt ch\u00EDnh \u0111\u1EE9ng tr\u00EAn, full-width. -->\n <div class=\"sd-confirm-sheet\">\n <div class=\"sd-confirm-sheet__title\">\n @if (data.icon) {\n <mat-icon>\n {{ data.icon }}\n </mat-icon>\n }\n <span class=\"T18M\" [innerHtml]=\"data.title || 'Confirm'\"></span>\n </div>\n <div class=\"sd-confirm-sheet__content\">\n <div class=\"T14R mb-4\" [innerHtml]=\"data.message\"></div>\n <ng-container [ngTemplateOutlet]=\"fields\" />\n </div>\n <div class=\"sd-confirm-sheet__actions\">\n @if (data.yesTitle) {\n <sd-button\n block\n size=\"lg\"\n type=\"fill\"\n [color]=\"data.yesButtonColor || 'primary'\"\n [disabled]=\"required && !value\"\n cdkFocusInitial\n [title]=\"data.yesTitle\"\n (click)=\"onAccept()\"></sd-button>\n }\n @if (data.noTitle) {\n <sd-button block size=\"lg\" [color]=\"data.noButtonColor || 'secondary'\" [title]=\"data.noTitle\" (click)=\"onCancel()\"></sd-button>\n }\n </div>\n </div>\n} @else {\n <div mat-dialog-title class=\"\">\n @if (data.icon) {\n <mat-icon>\n {{ data.icon }}\n </mat-icon>\n }\n <span class=\"T24M\" [innerHtml]=\"data.title || 'Confirm'\"></span>\n </div>\n <div mat-dialog-content>\n <div class=\"T14R mb-4\" [innerHtml]=\"data.message\"></div>\n <ng-container [ngTemplateOutlet]=\"fields\" />\n </div>\n <div mat-dialog-actions align=\"end\">\n @if (data.noTitle) {\n <sd-button [color]=\"data.noButtonColor || 'secondary'\" [title]=\"data.noTitle\" (click)=\"onCancel()\"></sd-button>\n }\n @if (data.yesTitle) {\n <sd-button\n class=\"ml-8\"\n type=\"fill\"\n [color]=\"data.yesButtonColor || 'primary'\"\n [disabled]=\"required && !value\"\n cdkFocusInitial\n [title]=\"data.yesTitle\"\n (click)=\"onAccept()\"></sd-button>\n }\n </div>\n}\n", styles: [".text-primary{color:var(--sd-primary)!important}.bg-primary{background:var(--sd-primary)!important}.border-primary{border-color:var(--sd-primary)!important}.text-primary-light{color:var(--sd-primary-light)!important}.bg-primary-light{background:var(--sd-primary-light)!important}.border-primary-light{border-color:var(--sd-primary-light)!important}.text-primary-dark{color:var(--sd-primary-dark)!important}.bg-primary-dark{background:var(--sd-primary-dark)!important}.border-primary-dark{border-color:var(--sd-primary-dark)!important}.text-info{color:var(--sd-info)!important}.bg-info{background:var(--sd-info)!important}.border-info{border-color:var(--sd-info)!important}.text-info-light{color:var(--sd-info-light)!important}.bg-info-light{background:var(--sd-info-light)!important}.border-info-light{border-color:var(--sd-info-light)!important}.text-info-dark{color:var(--sd-info-dark)!important}.bg-info-dark{background:var(--sd-info-dark)!important}.border-info-dark{border-color:var(--sd-info-dark)!important}.text-success{color:var(--sd-success)!important}.bg-success{background:var(--sd-success)!important}.border-success{border-color:var(--sd-success)!important}.text-success-light{color:var(--sd-success-light)!important}.bg-success-light{background:var(--sd-success-light)!important}.border-success-light{border-color:var(--sd-success-light)!important}.text-success-dark{color:var(--sd-success-dark)!important}.bg-success-dark{background:var(--sd-success-dark)!important}.border-success-dark{border-color:var(--sd-success-dark)!important}.text-warning{color:var(--sd-warning)!important}.bg-warning{background:var(--sd-warning)!important}.border-warning{border-color:var(--sd-warning)!important}.text-warning-light{color:var(--sd-warning-light)!important}.bg-warning-light{background:var(--sd-warning-light)!important}.border-warning-light{border-color:var(--sd-warning-light)!important}.text-warning-dark{color:var(--sd-warning-dark)!important}.bg-warning-dark{background:var(--sd-warning-dark)!important}.border-warning-dark{border-color:var(--sd-warning-dark)!important}.text-error{color:var(--sd-error)!important}.bg-error{background:var(--sd-error)!important}.border-error{border-color:var(--sd-error)!important}.text-error-light{color:var(--sd-error-light)!important}.bg-error-light{background:var(--sd-error-light)!important}.border-error-light{border-color:var(--sd-error-light)!important}.text-error-dark{color:var(--sd-error-dark)!important}.bg-error-dark{background:var(--sd-error-dark)!important}.border-error-dark{border-color:var(--sd-error-dark)!important}.text-secondary{color:var(--sd-secondary)!important}.bg-secondary{background:var(--sd-secondary)!important}.border-secondary{border-color:var(--sd-secondary)!important}.text-secondary-light{color:var(--sd-secondary-light)!important}.bg-secondary-light{background:var(--sd-secondary-light)!important}.border-secondary-light{border-color:var(--sd-secondary-light)!important}.text-secondary-dark{color:var(--sd-secondary-dark)!important}.bg-secondary-dark{background:var(--sd-secondary-dark)!important}.border-secondary-dark{border-color:var(--sd-secondary-dark)!important}.text-light{color:var(--sd-light)!important}.bg-light{background:var(--sd-light)!important}.border-light{border-color:var(--sd-light)!important}.text-dark{color:var(--sd-dark)!important}.bg-dark{background:var(--sd-dark)!important}.border-dark{border-color:var(--sd-dark)!important}.text-black500{color:var(--sd-black500)!important}.bg-black500{background:var(--sd-black500)!important}.border-black500{border-color:var(--sd-black500)!important}.text-black400{color:var(--sd-black400)!important}.bg-black400{background:var(--sd-black400)!important}.border-black400{border-color:var(--sd-black400)!important}.text-black300{color:var(--sd-black300)!important}.bg-black300{background:var(--sd-black300)!important}.border-black300{border-color:var(--sd-black300)!important}.text-black200{color:var(--sd-black200)!important}.bg-black200{background:var(--sd-black200)!important}.border-black200{border-color:var(--sd-black200)!important}.text-black100{color:var(--sd-black100)!important}.bg-black100{background:var(--sd-black100)!important}.border-black100{border-color:var(--sd-black100)!important}.text-white{color:#fff!important}.bg-white{background:#fff!important}.border-white{border-color:#fff!important}.text-black{color:#000!important}.bg-black{background:#000!important}.border-black{border-color:#000!important}:host .mat-dialog-content{margin:0 -16px 16px!important}:host .mat-button{background-color:#f5f5f5}:host ::ng-deep .mat-dialog-title{display:flex;align-items:center;justify-content:flex-start}:host ::ng-deep .mat-dialog-title .mat-icon{margin-right:5px}:host{display:block}:host ::ng-deep .mat-dialog-title .mat-icon.info{color:var(--sd-info)}:host ::ng-deep .mat-dialog-title .mat-icon.warning{color:var(--sd-warning)}:host ::ng-deep .mat-dialog-title .mat-icon.success{color:var(--sd-success)}:host ::ng-deep .mat-dialog-title .mat-icon.error{color:var(--sd-error)}.sd-confirm-sheet{display:flex;flex-direction:column;box-sizing:border-box;max-height:calc(80vh - 16px);padding:12px 0 calc(8px + env(safe-area-inset-bottom,0px))}.sd-confirm-sheet__title{display:flex;align-items:center;gap:8px;flex:0 0 auto;margin-bottom:8px;overflow-wrap:anywhere}.sd-confirm-sheet__content{flex:1 1 auto;min-height:0;overflow-y:auto;overflow-wrap:anywhere}.sd-confirm-sheet__actions{display:flex;flex-direction:column;gap:8px;flex:0 0 auto;margin-top:16px}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: FormsModule }, { kind: "ngmodule", type: MatDialogModule }, { kind: "directive", type: i2.MatDialogTitle, selector: "[mat-dialog-title], [matDialogTitle]", inputs: ["id"], exportAs: ["matDialogTitle"] }, { kind: "directive", type: i2.MatDialogActions, selector: "[mat-dialog-actions], mat-dialog-actions, [matDialogActions]", inputs: ["align"] }, { kind: "directive", type: i2.MatDialogContent, selector: "[mat-dialog-content], mat-dialog-content, [matDialogContent]" }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i3.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: SdButton, selector: "sd-button", inputs: ["autoId", "type", "color", "size", "fontSet", "title", "width", "tooltip", "prefixIcon", "suffixIcon", "disabled", "loading", "block", "htmlType"], outputs: ["click"] }, { kind: "component", type: SdDate, selector: "sd-date", inputs: ["autoId", "name", "size", "form", "label", "helperText", "placeholder", "hideInlineError", "required", "disabled", "viewed", "clearable", "inlineError", "hyperlink", "appearance", "floatLabel", "min", "minDate", "max", "maxDate", "model"], outputs: ["modelChange", "sdChange", "sdFocus"] }, { kind: "component", type: SdRadio, selector: "sd-radio", inputs: ["autoId", "name", "form", "label", "placeholder", "display", "items", "valueField", "displayField", "required", "inlineError", "disabled", "viewed", "color", "hyperlink", "model"], outputs: ["modelChange", "sdChange", "sdSelection"] }, { kind: "component", type: SdTextarea, selector: "sd-textarea", inputs: ["autoId", "name", "size", "form", "label", "helperText", "placeholder", "rows", "hideInlineError", "required", "disabled", "viewed", "autoHeight", "maxlength", "pattern", "validator", "inlineError", "appearance", "floatLabel", "model"], outputs: ["modelChange", "sdChange"] }] });
|
|
50
67
|
}
|
|
51
68
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: DialogConfirmComponent, decorators: [{
|
|
52
69
|
type: Component,
|
|
53
|
-
args: [{ selector: 'sd-dialog-confirm', imports: [CommonModule, FormsModule, MatDialogModule, MatIconModule, SdButton, SdDate, SdRadio, SdTextarea], template: "<
|
|
70
|
+
args: [{ selector: 'sd-dialog-confirm', imports: [CommonModule, FormsModule, MatDialogModule, MatIconModule, SdButton, SdDate, SdRadio, SdTextarea], template: "<ng-template #fields>\n @if (data.input) {\n <sd-textarea [placeholder]=\"data.input.placeholder\" [(model)]=\"value\" [rows]=\"5\" [maxlength]=\"data.input.maxlength!\" />\n }\n @if (data.date) {\n <sd-date [clearable]=\"true\"\n [placeholder]=\"data.date.placeholder\"\n [(model)]=\"value\"\n type=\"date\"\n [min]=\"data.date.min!\"\n [max]=\"data.date.max!\"\n [required]=\"data.date.required\">\n </sd-date>\n }\n @if (data.radio) {\n <sd-radio\n [items]=\"data.radio.items\"\n [valueField]=\"data.radio.valueField\"\n [displayField]=\"data.radio.displayField\"\n [display]=\"data.radio.display || 'column'\"\n [(model)]=\"value\"\n [required]=\"data.radio.required\">\n </sd-radio>\n }\n</ng-template>\n\n@if (isBottomSheet) {\n <!-- why: trong bottom sheet kh\u00F4ng d\u00F9ng directive mat-dialog-* (ch\u00FAng g\u1EAFn v\u1EDBi MatDialogRef); n\u00FAt ch\u00EDnh \u0111\u1EE9ng tr\u00EAn, full-width. -->\n <div class=\"sd-confirm-sheet\">\n <div class=\"sd-confirm-sheet__title\">\n @if (data.icon) {\n <mat-icon>\n {{ data.icon }}\n </mat-icon>\n }\n <span class=\"T18M\" [innerHtml]=\"data.title || 'Confirm'\"></span>\n </div>\n <div class=\"sd-confirm-sheet__content\">\n <div class=\"T14R mb-4\" [innerHtml]=\"data.message\"></div>\n <ng-container [ngTemplateOutlet]=\"fields\" />\n </div>\n <div class=\"sd-confirm-sheet__actions\">\n @if (data.yesTitle) {\n <sd-button\n block\n size=\"lg\"\n type=\"fill\"\n [color]=\"data.yesButtonColor || 'primary'\"\n [disabled]=\"required && !value\"\n cdkFocusInitial\n [title]=\"data.yesTitle\"\n (click)=\"onAccept()\"></sd-button>\n }\n @if (data.noTitle) {\n <sd-button block size=\"lg\" [color]=\"data.noButtonColor || 'secondary'\" [title]=\"data.noTitle\" (click)=\"onCancel()\"></sd-button>\n }\n </div>\n </div>\n} @else {\n <div mat-dialog-title class=\"\">\n @if (data.icon) {\n <mat-icon>\n {{ data.icon }}\n </mat-icon>\n }\n <span class=\"T24M\" [innerHtml]=\"data.title || 'Confirm'\"></span>\n </div>\n <div mat-dialog-content>\n <div class=\"T14R mb-4\" [innerHtml]=\"data.message\"></div>\n <ng-container [ngTemplateOutlet]=\"fields\" />\n </div>\n <div mat-dialog-actions align=\"end\">\n @if (data.noTitle) {\n <sd-button [color]=\"data.noButtonColor || 'secondary'\" [title]=\"data.noTitle\" (click)=\"onCancel()\"></sd-button>\n }\n @if (data.yesTitle) {\n <sd-button\n class=\"ml-8\"\n type=\"fill\"\n [color]=\"data.yesButtonColor || 'primary'\"\n [disabled]=\"required && !value\"\n cdkFocusInitial\n [title]=\"data.yesTitle\"\n (click)=\"onAccept()\"></sd-button>\n }\n </div>\n}\n", styles: [".text-primary{color:var(--sd-primary)!important}.bg-primary{background:var(--sd-primary)!important}.border-primary{border-color:var(--sd-primary)!important}.text-primary-light{color:var(--sd-primary-light)!important}.bg-primary-light{background:var(--sd-primary-light)!important}.border-primary-light{border-color:var(--sd-primary-light)!important}.text-primary-dark{color:var(--sd-primary-dark)!important}.bg-primary-dark{background:var(--sd-primary-dark)!important}.border-primary-dark{border-color:var(--sd-primary-dark)!important}.text-info{color:var(--sd-info)!important}.bg-info{background:var(--sd-info)!important}.border-info{border-color:var(--sd-info)!important}.text-info-light{color:var(--sd-info-light)!important}.bg-info-light{background:var(--sd-info-light)!important}.border-info-light{border-color:var(--sd-info-light)!important}.text-info-dark{color:var(--sd-info-dark)!important}.bg-info-dark{background:var(--sd-info-dark)!important}.border-info-dark{border-color:var(--sd-info-dark)!important}.text-success{color:var(--sd-success)!important}.bg-success{background:var(--sd-success)!important}.border-success{border-color:var(--sd-success)!important}.text-success-light{color:var(--sd-success-light)!important}.bg-success-light{background:var(--sd-success-light)!important}.border-success-light{border-color:var(--sd-success-light)!important}.text-success-dark{color:var(--sd-success-dark)!important}.bg-success-dark{background:var(--sd-success-dark)!important}.border-success-dark{border-color:var(--sd-success-dark)!important}.text-warning{color:var(--sd-warning)!important}.bg-warning{background:var(--sd-warning)!important}.border-warning{border-color:var(--sd-warning)!important}.text-warning-light{color:var(--sd-warning-light)!important}.bg-warning-light{background:var(--sd-warning-light)!important}.border-warning-light{border-color:var(--sd-warning-light)!important}.text-warning-dark{color:var(--sd-warning-dark)!important}.bg-warning-dark{background:var(--sd-warning-dark)!important}.border-warning-dark{border-color:var(--sd-warning-dark)!important}.text-error{color:var(--sd-error)!important}.bg-error{background:var(--sd-error)!important}.border-error{border-color:var(--sd-error)!important}.text-error-light{color:var(--sd-error-light)!important}.bg-error-light{background:var(--sd-error-light)!important}.border-error-light{border-color:var(--sd-error-light)!important}.text-error-dark{color:var(--sd-error-dark)!important}.bg-error-dark{background:var(--sd-error-dark)!important}.border-error-dark{border-color:var(--sd-error-dark)!important}.text-secondary{color:var(--sd-secondary)!important}.bg-secondary{background:var(--sd-secondary)!important}.border-secondary{border-color:var(--sd-secondary)!important}.text-secondary-light{color:var(--sd-secondary-light)!important}.bg-secondary-light{background:var(--sd-secondary-light)!important}.border-secondary-light{border-color:var(--sd-secondary-light)!important}.text-secondary-dark{color:var(--sd-secondary-dark)!important}.bg-secondary-dark{background:var(--sd-secondary-dark)!important}.border-secondary-dark{border-color:var(--sd-secondary-dark)!important}.text-light{color:var(--sd-light)!important}.bg-light{background:var(--sd-light)!important}.border-light{border-color:var(--sd-light)!important}.text-dark{color:var(--sd-dark)!important}.bg-dark{background:var(--sd-dark)!important}.border-dark{border-color:var(--sd-dark)!important}.text-black500{color:var(--sd-black500)!important}.bg-black500{background:var(--sd-black500)!important}.border-black500{border-color:var(--sd-black500)!important}.text-black400{color:var(--sd-black400)!important}.bg-black400{background:var(--sd-black400)!important}.border-black400{border-color:var(--sd-black400)!important}.text-black300{color:var(--sd-black300)!important}.bg-black300{background:var(--sd-black300)!important}.border-black300{border-color:var(--sd-black300)!important}.text-black200{color:var(--sd-black200)!important}.bg-black200{background:var(--sd-black200)!important}.border-black200{border-color:var(--sd-black200)!important}.text-black100{color:var(--sd-black100)!important}.bg-black100{background:var(--sd-black100)!important}.border-black100{border-color:var(--sd-black100)!important}.text-white{color:#fff!important}.bg-white{background:#fff!important}.border-white{border-color:#fff!important}.text-black{color:#000!important}.bg-black{background:#000!important}.border-black{border-color:#000!important}:host .mat-dialog-content{margin:0 -16px 16px!important}:host .mat-button{background-color:#f5f5f5}:host ::ng-deep .mat-dialog-title{display:flex;align-items:center;justify-content:flex-start}:host ::ng-deep .mat-dialog-title .mat-icon{margin-right:5px}:host{display:block}:host ::ng-deep .mat-dialog-title .mat-icon.info{color:var(--sd-info)}:host ::ng-deep .mat-dialog-title .mat-icon.warning{color:var(--sd-warning)}:host ::ng-deep .mat-dialog-title .mat-icon.success{color:var(--sd-success)}:host ::ng-deep .mat-dialog-title .mat-icon.error{color:var(--sd-error)}.sd-confirm-sheet{display:flex;flex-direction:column;box-sizing:border-box;max-height:calc(80vh - 16px);padding:12px 0 calc(8px + env(safe-area-inset-bottom,0px))}.sd-confirm-sheet__title{display:flex;align-items:center;gap:8px;flex:0 0 auto;margin-bottom:8px;overflow-wrap:anywhere}.sd-confirm-sheet__content{flex:1 1 auto;min-height:0;overflow-y:auto;overflow-wrap:anywhere}.sd-confirm-sheet__actions{display:flex;flex-direction:column;gap:8px;flex:0 0 auto;margin-top:16px}\n"] }]
|
|
54
71
|
}], ctorParameters: () => [] });
|
|
55
72
|
|
|
73
|
+
const DEFAULT_WIDTH = '400px';
|
|
74
|
+
const BOTTOM_SHEET_PANEL_CLASS = 'sd-confirm-bottom-sheet';
|
|
56
75
|
class SdConfirmService {
|
|
57
76
|
dialog;
|
|
58
77
|
#i18n = inject(I18nService);
|
|
78
|
+
#bottomSheet = inject(MatBottomSheet);
|
|
79
|
+
// why: đọc một lần, cùng nguồn nhận diện mobile với sd-modal để hai nơi chọn kiểu hiển thị giống nhau.
|
|
80
|
+
#isMobile = BrowserUtilities.isMobile();
|
|
59
81
|
constructor(dialog) {
|
|
60
82
|
this.dialog = dialog;
|
|
61
83
|
}
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
84
|
+
/**
|
|
85
|
+
* Đường mở duy nhất của mọi method: chọn kiểu hiển thị, tính quyền đóng bằng nền/Esc và biến kết quả đóng thành
|
|
86
|
+
* Promise LUÔN settle: `ACCEPT` thì resolve giá trị, mọi cách đóng khác (Hủy, nền, Esc, điều hướng) reject `'CANCEL'`.
|
|
87
|
+
*/
|
|
88
|
+
#open(data, option, width) {
|
|
89
|
+
const closeAllowed = option?.enableBackdropClose ?? option?.disableBackdropClose === false;
|
|
90
|
+
const disableClose = !closeAllowed;
|
|
91
|
+
const view = option?.view ?? (this.#isMobile ? 'bottom-sheet' : 'dialog');
|
|
92
|
+
const closed$ = view === 'bottom-sheet'
|
|
93
|
+
? this.#bottomSheet
|
|
94
|
+
.open(DialogConfirmComponent, {
|
|
95
|
+
data,
|
|
96
|
+
disableClose,
|
|
97
|
+
panelClass: BOTTOM_SHEET_PANEL_CLASS,
|
|
98
|
+
ariaLabel: this.#toPlainText(data.title),
|
|
99
|
+
})
|
|
100
|
+
.afterDismissed()
|
|
101
|
+
: this.dialog.open(DialogConfirmComponent, { width, disableClose, data }).afterClosed();
|
|
75
102
|
return new Promise((resolve, reject) => {
|
|
76
|
-
|
|
77
|
-
if (result) {
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
resolve(result.value);
|
|
83
|
-
}
|
|
103
|
+
closed$.subscribe(result => {
|
|
104
|
+
if (result?.action === 'ACCEPT') {
|
|
105
|
+
resolve(result.value);
|
|
106
|
+
}
|
|
107
|
+
else {
|
|
108
|
+
reject('CANCEL');
|
|
84
109
|
}
|
|
85
110
|
});
|
|
86
111
|
});
|
|
112
|
+
}
|
|
113
|
+
// why: tiêu đề cho phép HTML (innerHtml) nhưng tên cho trình đọc màn hình phải là text thuần.
|
|
114
|
+
#toPlainText(html) {
|
|
115
|
+
return (html ?? '').replace(/<[^>]*>/g, '').trim();
|
|
116
|
+
}
|
|
117
|
+
confirm = (message, option = {}) => {
|
|
118
|
+
return this.#open({
|
|
119
|
+
title: option?.title || this.#i18n.t('core.confirm.title'),
|
|
120
|
+
message,
|
|
121
|
+
yesTitle: option?.yesTitle || this.#i18n.t('core.confirm.yes'),
|
|
122
|
+
noTitle: option?.noTitle || this.#i18n.t('core.confirm.no'),
|
|
123
|
+
noButtonColor: option?.noButtonColor || 'secondary',
|
|
124
|
+
yesButtonColor: option?.yesButtonColor || 'primary',
|
|
125
|
+
}, option, option?.width || DEFAULT_WIDTH);
|
|
87
126
|
};
|
|
88
127
|
withInput = (message, option) => {
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
maxlength: option?.maxlength || 255,
|
|
101
|
-
required: option?.required,
|
|
102
|
-
defaultValue: option?.defaultValue || '',
|
|
103
|
-
},
|
|
128
|
+
return this.#open({
|
|
129
|
+
title: option?.title || this.#i18n.t('core.confirm.title'),
|
|
130
|
+
message,
|
|
131
|
+
yesTitle: option?.yesTitle || this.#i18n.t('core.confirm.yes-short'),
|
|
132
|
+
noTitle: option?.noTitle || this.#i18n.t('core.confirm.no-short'),
|
|
133
|
+
noButtonColor: option?.noButtonColor || 'secondary',
|
|
134
|
+
yesButtonColor: option?.yesButtonColor || 'primary',
|
|
135
|
+
input: {
|
|
136
|
+
maxlength: option?.maxlength || 255,
|
|
137
|
+
required: option?.required,
|
|
138
|
+
defaultValue: option?.defaultValue || '',
|
|
104
139
|
},
|
|
105
|
-
});
|
|
106
|
-
return new Promise((resolve, reject) => {
|
|
107
|
-
dialogRef.afterClosed().subscribe(result => {
|
|
108
|
-
if (result) {
|
|
109
|
-
if (result.action === 'CANCEL') {
|
|
110
|
-
reject(result.action);
|
|
111
|
-
}
|
|
112
|
-
else if (result.action === 'ACCEPT') {
|
|
113
|
-
resolve(result.value);
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
});
|
|
117
|
-
});
|
|
140
|
+
}, option, DEFAULT_WIDTH);
|
|
118
141
|
};
|
|
119
142
|
withRadio = (message, option) => {
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
display: option?.display || 'row',
|
|
135
|
-
required: option?.required,
|
|
136
|
-
defaultValue: option?.defaultValue,
|
|
137
|
-
},
|
|
143
|
+
return this.#open({
|
|
144
|
+
title: option?.title || this.#i18n.t('core.confirm.title'),
|
|
145
|
+
message,
|
|
146
|
+
yesTitle: option?.yesTitle || this.#i18n.t('core.confirm.yes-short'),
|
|
147
|
+
noTitle: option?.noTitle || this.#i18n.t('core.confirm.no-short'),
|
|
148
|
+
noButtonColor: option?.noButtonColor || 'secondary',
|
|
149
|
+
yesButtonColor: option?.yesButtonColor || 'primary',
|
|
150
|
+
radio: {
|
|
151
|
+
items: option?.items || [],
|
|
152
|
+
valueField: option?.valueField || 'value',
|
|
153
|
+
displayField: option?.displayField || 'label',
|
|
154
|
+
display: option?.display || 'row',
|
|
155
|
+
required: option?.required,
|
|
156
|
+
defaultValue: option?.defaultValue,
|
|
138
157
|
},
|
|
139
|
-
});
|
|
140
|
-
return new Promise((resolve, reject) => {
|
|
141
|
-
dialogRef.afterClosed().subscribe(result => {
|
|
142
|
-
if (result) {
|
|
143
|
-
if (result.action === 'CANCEL') {
|
|
144
|
-
reject(result.action);
|
|
145
|
-
}
|
|
146
|
-
else if (result.action === 'ACCEPT') {
|
|
147
|
-
resolve(result.value);
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
});
|
|
151
|
-
});
|
|
158
|
+
}, option, DEFAULT_WIDTH);
|
|
152
159
|
};
|
|
153
160
|
withDate = (message, option) => {
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
placeholder: option?.placeholder,
|
|
166
|
-
required: option?.required,
|
|
167
|
-
defaultValue: option?.defaultValue || '',
|
|
168
|
-
},
|
|
161
|
+
return this.#open({
|
|
162
|
+
title: option?.title || this.#i18n.t('core.confirm.title'),
|
|
163
|
+
message,
|
|
164
|
+
yesTitle: option?.yesTitle || this.#i18n.t('core.confirm.yes-short'),
|
|
165
|
+
noTitle: option?.noTitle || this.#i18n.t('core.confirm.no-short'),
|
|
166
|
+
noButtonColor: option?.noButtonColor || 'secondary',
|
|
167
|
+
yesButtonColor: option?.yesButtonColor || 'primary',
|
|
168
|
+
date: {
|
|
169
|
+
placeholder: option?.placeholder,
|
|
170
|
+
required: option?.required,
|
|
171
|
+
defaultValue: option?.defaultValue || '',
|
|
169
172
|
},
|
|
170
|
-
});
|
|
171
|
-
return new Promise((resolve, reject) => {
|
|
172
|
-
dialogRef.afterClosed().subscribe(result => {
|
|
173
|
-
if (result) {
|
|
174
|
-
if (result.action === 'CANCEL') {
|
|
175
|
-
reject(result.action);
|
|
176
|
-
}
|
|
177
|
-
else if (result.action === 'ACCEPT') {
|
|
178
|
-
resolve(result.value);
|
|
179
|
-
}
|
|
180
|
-
}
|
|
181
|
-
});
|
|
182
|
-
});
|
|
173
|
+
}, option, DEFAULT_WIDTH);
|
|
183
174
|
};
|
|
184
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: SdConfirmService, deps: [{ token:
|
|
175
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: SdConfirmService, deps: [{ token: i2.MatDialog }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
185
176
|
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: SdConfirmService, providedIn: 'root' });
|
|
186
177
|
}
|
|
187
178
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: SdConfirmService, decorators: [{
|
|
@@ -189,15 +180,16 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.21", ngImpo
|
|
|
189
180
|
args: [{
|
|
190
181
|
providedIn: 'root',
|
|
191
182
|
}]
|
|
192
|
-
}], ctorParameters: () => [{ type:
|
|
183
|
+
}], ctorParameters: () => [{ type: i2.MatDialog }] });
|
|
193
184
|
|
|
194
185
|
/*
|
|
195
186
|
* Public API Surface of superdev-angular-core
|
|
196
187
|
*/
|
|
188
|
+
// why: DialogConfirmComponent và DialogData là chi tiết nội bộ của SdConfirmService; consumer chỉ dùng service.
|
|
197
189
|
|
|
198
190
|
/**
|
|
199
191
|
* Generated bundle index. Do not edit.
|
|
200
192
|
*/
|
|
201
193
|
|
|
202
|
-
export {
|
|
194
|
+
export { SdConfirmService };
|
|
203
195
|
//# sourceMappingURL=sd-angular-core-services-confirm.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sd-angular-core-services-confirm.mjs","sources":["../../../projects/sd-angular/services/confirm/src/lib/components/dialog-confirm/dialog-confirm.component.ts","../../../projects/sd-angular/services/confirm/src/lib/components/dialog-confirm/dialog-confirm.component.html","../../../projects/sd-angular/services/confirm/src/lib/confirm.service.ts","../../../projects/sd-angular/services/confirm/src/public-api.ts","../../../projects/sd-angular/services/confirm/sd-angular-core-services-confirm.ts"],"sourcesContent":["import { CommonModule } from '@angular/common';\nimport { Component, inject } from '@angular/core';\nimport { FormsModule } from '@angular/forms';\nimport { MatDialogRef, MAT_DIALOG_DATA, MatDialogModule } from '@angular/material/dialog';\nimport { MatFormFieldModule } from '@angular/material/form-field';\nimport { MatIconModule } from '@angular/material/icon';\nimport { SdButton } from '@sd-angular/core/components/button';\nimport { SdDate } from '@sd-angular/core/forms/date';\nimport { SdRadio } from '@sd-angular/core/forms/radio';\nimport { SdTextarea } from '@sd-angular/core/forms/textarea';\nimport { Color } from '@sdcorejs/utils/models';\nimport { Utilities } from '@sdcorejs/utils/fns';\n\nexport interface DialogData {\n icon?: string;\n title?: string;\n message?: string;\n yesTitle?: string;\n noTitle?: string;\n yesButtonColor?: Color;\n noButtonColor?: Color;\n input?: {\n placeholder?: string;\n minlength?: number;\n maxlength?: number;\n required?: boolean;\n defaultValue?: string;\n };\n date?: {\n required?: boolean;\n placeholder?: string;\n defaultValue?: string | Date;\n min?: string | Date;\n max?: string | Date;\n };\n radio?: {\n required?: boolean;\n defaultValue?: string | number;\n items: any[];\n valueField: string;\n displayField: string;\n display?: 'row' | 'column';\n };\n}\n\n@Component({\n selector: 'sd-dialog-confirm',\n templateUrl: 'dialog-confirm.component.html',\n styleUrl: './dialog-confirm.component.scss',\n imports: [CommonModule, FormsModule, MatDialogModule, MatIconModule, SdButton, SdDate, SdRadio, SdTextarea],\n})\nexport class DialogConfirmComponent {\n value: any;\n required = false;\n id = `I${Utilities.generateUuid()}`;\n public readonly dialogRef = inject(MatDialogRef<DialogConfirmComponent>);\n public readonly data = inject<DialogData>(MAT_DIALOG_DATA);\n\n constructor() {\n if (this.data?.input) {\n this.value = this.data?.input?.defaultValue ?? '';\n this.required = this.data?.input?.required || false;\n }\n if (this.data?.date) {\n this.value = this.data?.date?.defaultValue ?? '';\n this.required = this.data?.date?.required || false;\n }\n if (this.data?.radio) {\n this.value = this.data?.radio?.defaultValue ?? '';\n this.required = this.data?.radio?.required || false;\n }\n }\n\n onCancel = () => {\n this.dialogRef.close({ action: 'CANCEL', value: null });\n };\n\n onAccept = () => {\n // Always return an object with action and value for consistency\n if (this.data?.radio || this.data?.input || this.data?.date) {\n this.dialogRef.close({ action: 'ACCEPT', value: this.value });\n } else {\n this.dialogRef.close({ action: 'ACCEPT', value: null });\n }\n };\n}\n","<div mat-dialog-title class=\"\">\n @if (data.icon) {\n <mat-icon>\n {{ data.icon }}\n </mat-icon>\n }\n <span class=\"T24M\" [innerHtml]=\"data.title || 'Confirm'\"></span>\n</div>\n<div mat-dialog-content>\n <div class=\"T14R mb-4\" [innerHtml]=\"data.message\"></div>\n @if (data.input) {\n <sd-textarea [placeholder]=\"data.input.placeholder\" [(model)]=\"value\" [rows]=\"5\" [maxlength]=\"data.input.maxlength!\" />\n }\n @if (data.date) {\n <sd-date [clearable]=\"true\"\n [placeholder]=\"data.date.placeholder\"\n [(model)]=\"value\"\n type=\"date\"\n [min]=\"data.date.min!\"\n [max]=\"data.date.max!\"\n [required]=\"data.date.required\">\n </sd-date>\n }\n @if (data.radio) {\n <sd-radio\n [items]=\"data.radio.items\"\n [valueField]=\"data.radio.valueField\"\n [displayField]=\"data.radio.displayField\"\n [display]=\"data.radio.display || 'column'\"\n [(model)]=\"value\"\n [required]=\"data.radio.required\">\n </sd-radio>\n }\n</div>\n<div mat-dialog-actions align=\"end\">\n @if (data.noTitle) {\n <sd-button [color]=\"data.noButtonColor || 'secondary'\" [title]=\"data.noTitle\" (click)=\"onCancel()\"></sd-button>\n }\n @if (data.yesTitle) {\n <sd-button\n class=\"ml-8\"\n type=\"fill\"\n [color]=\"data.yesButtonColor || 'primary'\"\n [disabled]=\"required && !value\"\n cdkFocusInitial\n [title]=\"data.yesTitle\"\n (click)=\"onAccept()\"></sd-button>\n }\n</div>\n","import { inject, Injectable } from '@angular/core';\nimport { MatDialog } from '@angular/material/dialog';\nimport { DialogConfirmComponent } from './components/dialog-confirm/dialog-confirm.component';\nimport { Color } from '@sdcorejs/utils/models';\nimport { I18nService } from '@sd-angular/core/i18n';\n\n@Injectable({\n providedIn: 'root',\n})\nexport class SdConfirmService {\n readonly #i18n = inject(I18nService);\n\n constructor(private dialog: MatDialog) {}\n\n confirm = (\n message: string,\n option: {\n title?: string;\n yesTitle?: string;\n noTitle?: string;\n yesButtonColor?: Color;\n noButtonColor?: Color;\n width?: string;\n disableBackdropClose?: boolean;\n } = {}\n ) => {\n const dialogRef = this.dialog.open(DialogConfirmComponent, {\n width: option?.width || '400px',\n disableClose: option?.disableBackdropClose ?? true,\n data: {\n title: option?.title || this.#i18n.t('core.confirm.title'),\n message,\n yesTitle: option?.yesTitle || this.#i18n.t('core.confirm.yes'),\n noTitle: option?.noTitle || this.#i18n.t('core.confirm.no'),\n noButtonColor: option?.noButtonColor || 'secondary',\n yesButtonColor: option?.yesButtonColor || 'primary',\n },\n });\n return new Promise((resolve, reject) => {\n dialogRef.afterClosed().subscribe(result => {\n if (result) {\n if (result.action === 'CANCEL') {\n reject(result.action);\n } else if (result.action === 'ACCEPT') {\n resolve(result.value);\n }\n }\n });\n });\n };\n\n withInput = (\n message?: string,\n option?: {\n title?: string;\n yesTitle?: string;\n noTitle?: string;\n required?: boolean;\n maxlength?: number;\n yesButtonColor?: Color;\n noButtonColor?: Color;\n defaultValue?: string;\n disableBackdropClose?: boolean;\n }\n ): Promise<string> => {\n const dialogRef = this.dialog.open(DialogConfirmComponent, {\n width: '400px',\n disableClose: option?.disableBackdropClose ?? true,\n data: {\n title: option?.title || this.#i18n.t('core.confirm.title'),\n message,\n yesTitle: option?.yesTitle || this.#i18n.t('core.confirm.yes-short'),\n noTitle: option?.noTitle || this.#i18n.t('core.confirm.no-short'),\n noButtonColor: option?.noButtonColor || 'secondary',\n yesButtonColor: option?.yesButtonColor || 'primary',\n input: {\n maxlength: option?.maxlength || 255,\n required: option?.required,\n defaultValue: option?.defaultValue || '',\n },\n },\n });\n return new Promise((resolve, reject) => {\n dialogRef.afterClosed().subscribe(result => {\n if (result) {\n if (result.action === 'CANCEL') {\n reject(result.action);\n } else if (result.action === 'ACCEPT') {\n resolve(result.value);\n }\n }\n });\n });\n };\n\n withRadio = (\n message?: string,\n option?: {\n title?: string;\n yesTitle?: string;\n noTitle?: string;\n required?: boolean;\n yesButtonColor?: Color;\n noButtonColor?: Color;\n defaultValue?: string | number;\n items: any[];\n valueField: string;\n displayField: string;\n display?: 'row' | 'column';\n disableBackdropClose?: boolean;\n }\n ): Promise<string> => {\n const dialogRef = this.dialog.open(DialogConfirmComponent, {\n width: '400px',\n disableClose: option?.disableBackdropClose ?? true,\n data: {\n title: option?.title || this.#i18n.t('core.confirm.title'),\n message,\n yesTitle: option?.yesTitle || this.#i18n.t('core.confirm.yes-short'),\n noTitle: option?.noTitle || this.#i18n.t('core.confirm.no-short'),\n noButtonColor: option?.noButtonColor || 'secondary',\n yesButtonColor: option?.yesButtonColor || 'primary',\n radio: {\n items: option?.items || [],\n valueField: option?.valueField || 'value',\n displayField: option?.displayField || 'label',\n display: option?.display || 'row',\n required: option?.required,\n defaultValue: option?.defaultValue,\n },\n },\n });\n return new Promise((resolve, reject) => {\n dialogRef.afterClosed().subscribe(result => {\n if (result) {\n if (result.action === 'CANCEL') {\n reject(result.action);\n } else if (result.action === 'ACCEPT') {\n resolve(result.value);\n }\n }\n });\n });\n };\n\n withDate = (\n message?: string,\n option?: {\n title?: string;\n\n yesTitle?: string;\n noTitle?: string;\n required?: boolean;\n yesButtonColor?: Color;\n noButtonColor?: Color;\n defaultValue?: string | Date;\n placeholder?: string;\n disableBackdropClose?: boolean;\n }\n ): Promise<string> => {\n const dialogRef = this.dialog.open(DialogConfirmComponent, {\n width: '400px',\n disableClose: option?.disableBackdropClose ?? true,\n data: {\n title: option?.title || this.#i18n.t('core.confirm.title'),\n message,\n yesTitle: option?.yesTitle || this.#i18n.t('core.confirm.yes-short'),\n noTitle: option?.noTitle || this.#i18n.t('core.confirm.no-short'),\n noButtonColor: option?.noButtonColor || 'secondary',\n yesButtonColor: option?.yesButtonColor || 'primary',\n date: {\n placeholder: option?.placeholder,\n required: option?.required,\n defaultValue: option?.defaultValue || '',\n },\n },\n });\n return new Promise((resolve, reject) => {\n dialogRef.afterClosed().subscribe(result => {\n if (result) {\n if (result.action === 'CANCEL') {\n reject(result.action);\n } else if (result.action === 'ACCEPT') {\n resolve(result.value);\n }\n }\n });\n });\n };\n}\n","/*\n * Public API Surface of superdev-angular-core\n */\n\nexport * from './lib/components/dialog-confirm/dialog-confirm.component';\nexport * from './lib/confirm.service';\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-services-confirm.mjs","sources":["../../../projects/sd-angular/services/confirm/src/lib/components/dialog-confirm/dialog-confirm.component.ts","../../../projects/sd-angular/services/confirm/src/lib/components/dialog-confirm/dialog-confirm.component.html","../../../projects/sd-angular/services/confirm/src/lib/confirm.service.ts","../../../projects/sd-angular/services/confirm/src/public-api.ts","../../../projects/sd-angular/services/confirm/sd-angular-core-services-confirm.ts"],"sourcesContent":["import { CommonModule } from '@angular/common';\nimport { Component, inject } from '@angular/core';\nimport { FormsModule } from '@angular/forms';\nimport { MatBottomSheetRef, MAT_BOTTOM_SHEET_DATA } from '@angular/material/bottom-sheet';\nimport { MatDialogRef, MAT_DIALOG_DATA, MatDialogModule } from '@angular/material/dialog';\nimport { MatFormFieldModule } from '@angular/material/form-field';\nimport { MatIconModule } from '@angular/material/icon';\nimport { SdButton } from '@sd-angular/core/components/button';\nimport { SdDate } from '@sd-angular/core/forms/date';\nimport { SdRadio } from '@sd-angular/core/forms/radio';\nimport { SdTextarea } from '@sd-angular/core/forms/textarea';\nimport { Color } from '@sdcorejs/utils/models';\nimport { Utilities } from '@sdcorejs/utils/fns';\n\nexport interface DialogData {\n icon?: string;\n title?: string;\n message?: string;\n yesTitle?: string;\n noTitle?: string;\n yesButtonColor?: Color;\n noButtonColor?: Color;\n input?: {\n placeholder?: string;\n minlength?: number;\n maxlength?: number;\n required?: boolean;\n defaultValue?: string;\n };\n date?: {\n required?: boolean;\n placeholder?: string;\n defaultValue?: string | Date;\n min?: string | Date;\n max?: string | Date;\n };\n radio?: {\n required?: boolean;\n defaultValue?: string | number;\n items: any[];\n valueField: string;\n displayField: string;\n display?: 'row' | 'column';\n };\n}\n\n@Component({\n selector: 'sd-dialog-confirm',\n templateUrl: 'dialog-confirm.component.html',\n styleUrl: './dialog-confirm.component.scss',\n imports: [CommonModule, FormsModule, MatDialogModule, MatIconModule, SdButton, SdDate, SdRadio, SdTextarea],\n})\nexport class DialogConfirmComponent {\n value: any;\n required = false;\n id = `I${Utilities.generateUuid()}`;\n // why: cùng một component chạy trong MatDialog hoặc MatBottomSheet nên cả hai ref đều là tùy chọn. SdConfirmService\n // quyết định kiểu hiển thị; component chỉ dùng ref đang có.\n public readonly dialogRef = inject(MatDialogRef<DialogConfirmComponent>, { optional: true });\n readonly #bottomSheetRef = inject(MatBottomSheetRef<DialogConfirmComponent>, { optional: true });\n /** `true` khi component được mở trong bottom sheet; dùng để chọn bố cục nút mobile. */\n public readonly isBottomSheet = !!this.#bottomSheetRef;\n public readonly data: DialogData =\n (this.isBottomSheet\n ? inject<DialogData>(MAT_BOTTOM_SHEET_DATA, { optional: true })\n : inject<DialogData>(MAT_DIALOG_DATA, { optional: true })) ?? {};\n\n constructor() {\n if (this.data?.input) {\n this.value = this.data?.input?.defaultValue ?? '';\n this.required = this.data?.input?.required || false;\n }\n if (this.data?.date) {\n this.value = this.data?.date?.defaultValue ?? '';\n this.required = this.data?.date?.required || false;\n }\n if (this.data?.radio) {\n this.value = this.data?.radio?.defaultValue ?? '';\n this.required = this.data?.radio?.required || false;\n }\n }\n\n #close(result: { action: 'ACCEPT' | 'CANCEL'; value: unknown }): void {\n if (this.#bottomSheetRef) {\n this.#bottomSheetRef.dismiss(result);\n } else {\n this.dialogRef?.close(result);\n }\n }\n\n onCancel = () => {\n this.#close({ action: 'CANCEL', value: null });\n };\n\n onAccept = () => {\n // Always return an object with action and value for consistency\n if (this.data?.radio || this.data?.input || this.data?.date) {\n this.#close({ action: 'ACCEPT', value: this.value });\n } else {\n this.#close({ action: 'ACCEPT', value: null });\n }\n };\n}\n","<ng-template #fields>\n @if (data.input) {\n <sd-textarea [placeholder]=\"data.input.placeholder\" [(model)]=\"value\" [rows]=\"5\" [maxlength]=\"data.input.maxlength!\" />\n }\n @if (data.date) {\n <sd-date [clearable]=\"true\"\n [placeholder]=\"data.date.placeholder\"\n [(model)]=\"value\"\n type=\"date\"\n [min]=\"data.date.min!\"\n [max]=\"data.date.max!\"\n [required]=\"data.date.required\">\n </sd-date>\n }\n @if (data.radio) {\n <sd-radio\n [items]=\"data.radio.items\"\n [valueField]=\"data.radio.valueField\"\n [displayField]=\"data.radio.displayField\"\n [display]=\"data.radio.display || 'column'\"\n [(model)]=\"value\"\n [required]=\"data.radio.required\">\n </sd-radio>\n }\n</ng-template>\n\n@if (isBottomSheet) {\n <!-- why: trong bottom sheet không dùng directive mat-dialog-* (chúng gắn với MatDialogRef); nút chính đứng trên, full-width. -->\n <div class=\"sd-confirm-sheet\">\n <div class=\"sd-confirm-sheet__title\">\n @if (data.icon) {\n <mat-icon>\n {{ data.icon }}\n </mat-icon>\n }\n <span class=\"T18M\" [innerHtml]=\"data.title || 'Confirm'\"></span>\n </div>\n <div class=\"sd-confirm-sheet__content\">\n <div class=\"T14R mb-4\" [innerHtml]=\"data.message\"></div>\n <ng-container [ngTemplateOutlet]=\"fields\" />\n </div>\n <div class=\"sd-confirm-sheet__actions\">\n @if (data.yesTitle) {\n <sd-button\n block\n size=\"lg\"\n type=\"fill\"\n [color]=\"data.yesButtonColor || 'primary'\"\n [disabled]=\"required && !value\"\n cdkFocusInitial\n [title]=\"data.yesTitle\"\n (click)=\"onAccept()\"></sd-button>\n }\n @if (data.noTitle) {\n <sd-button block size=\"lg\" [color]=\"data.noButtonColor || 'secondary'\" [title]=\"data.noTitle\" (click)=\"onCancel()\"></sd-button>\n }\n </div>\n </div>\n} @else {\n <div mat-dialog-title class=\"\">\n @if (data.icon) {\n <mat-icon>\n {{ data.icon }}\n </mat-icon>\n }\n <span class=\"T24M\" [innerHtml]=\"data.title || 'Confirm'\"></span>\n </div>\n <div mat-dialog-content>\n <div class=\"T14R mb-4\" [innerHtml]=\"data.message\"></div>\n <ng-container [ngTemplateOutlet]=\"fields\" />\n </div>\n <div mat-dialog-actions align=\"end\">\n @if (data.noTitle) {\n <sd-button [color]=\"data.noButtonColor || 'secondary'\" [title]=\"data.noTitle\" (click)=\"onCancel()\"></sd-button>\n }\n @if (data.yesTitle) {\n <sd-button\n class=\"ml-8\"\n type=\"fill\"\n [color]=\"data.yesButtonColor || 'primary'\"\n [disabled]=\"required && !value\"\n cdkFocusInitial\n [title]=\"data.yesTitle\"\n (click)=\"onAccept()\"></sd-button>\n }\n </div>\n}\n","import { inject, Injectable } from '@angular/core';\nimport { MatBottomSheet } from '@angular/material/bottom-sheet';\nimport { MatDialog } from '@angular/material/dialog';\nimport { DialogConfirmComponent, DialogData } from './components/dialog-confirm/dialog-confirm.component';\nimport { BrowserUtilities } from '@sdcorejs/utils/fns';\nimport { Color } from '@sdcorejs/utils/models';\nimport { I18nService } from '@sd-angular/core/i18n';\nimport { Observable } from 'rxjs';\n\n/** Option dùng chung cho mọi method của `SdConfirmService`. */\ninterface ConfirmDisplayOption {\n /**\n * Ép kiểu hiển thị. Không truyền: tự dùng `bottom-sheet` trên mobile và `dialog` trên desktop.\n */\n view?: 'dialog' | 'bottom-sheet';\n /**\n * Cho phép đóng bằng cách bấm nền hoặc phím Esc. Không truyền = `false`.\n * Khi được truyền, cờ này quyết định và `disableBackdropClose` bị bỏ qua.\n * Đóng theo cách này làm Promise reject `'CANCEL'`.\n */\n enableBackdropClose?: boolean;\n /**\n * Chặn đóng bằng nền và phím Esc. Mặc định `true`.\n * @deprecated Dùng `enableBackdropClose` (nghĩa ngược lại). Cờ này chỉ có hiệu lực khi không truyền `enableBackdropClose`.\n */\n disableBackdropClose?: boolean;\n}\n\ntype ConfirmCloseResult<TValue> = { action?: 'ACCEPT' | 'CANCEL'; value?: TValue } | undefined;\n\nconst DEFAULT_WIDTH = '400px';\nconst BOTTOM_SHEET_PANEL_CLASS = 'sd-confirm-bottom-sheet';\n\n@Injectable({\n providedIn: 'root',\n})\nexport class SdConfirmService {\n readonly #i18n = inject(I18nService);\n readonly #bottomSheet = inject(MatBottomSheet);\n // why: đọc một lần, cùng nguồn nhận diện mobile với sd-modal để hai nơi chọn kiểu hiển thị giống nhau.\n readonly #isMobile = BrowserUtilities.isMobile();\n\n constructor(private dialog: MatDialog) {}\n\n /**\n * Đường mở duy nhất của mọi method: chọn kiểu hiển thị, tính quyền đóng bằng nền/Esc và biến kết quả đóng thành\n * Promise LUÔN settle: `ACCEPT` thì resolve giá trị, mọi cách đóng khác (Hủy, nền, Esc, điều hướng) reject `'CANCEL'`.\n */\n #open<TValue>(data: DialogData, option: ConfirmDisplayOption | undefined, width: string): Promise<TValue> {\n const closeAllowed = option?.enableBackdropClose ?? option?.disableBackdropClose === false;\n const disableClose = !closeAllowed;\n const view = option?.view ?? (this.#isMobile ? 'bottom-sheet' : 'dialog');\n\n const closed$: Observable<ConfirmCloseResult<TValue>> =\n view === 'bottom-sheet'\n ? this.#bottomSheet\n .open(DialogConfirmComponent, {\n data,\n disableClose,\n panelClass: BOTTOM_SHEET_PANEL_CLASS,\n ariaLabel: this.#toPlainText(data.title),\n })\n .afterDismissed()\n : this.dialog.open(DialogConfirmComponent, { width, disableClose, data }).afterClosed();\n\n return new Promise<TValue>((resolve, reject) => {\n closed$.subscribe(result => {\n if (result?.action === 'ACCEPT') {\n resolve(result.value as TValue);\n } else {\n reject('CANCEL');\n }\n });\n });\n }\n\n // why: tiêu đề cho phép HTML (innerHtml) nhưng tên cho trình đọc màn hình phải là text thuần.\n #toPlainText(html: string | undefined): string {\n return (html ?? '').replace(/<[^>]*>/g, '').trim();\n }\n\n confirm = (\n message: string,\n option: ConfirmDisplayOption & {\n title?: string;\n yesTitle?: string;\n noTitle?: string;\n yesButtonColor?: Color;\n noButtonColor?: Color;\n /** Chiều rộng dialog. Không áp dụng cho bottom sheet (luôn full-width). */\n width?: string;\n } = {}\n ) => {\n return this.#open<unknown>(\n {\n title: option?.title || this.#i18n.t('core.confirm.title'),\n message,\n yesTitle: option?.yesTitle || this.#i18n.t('core.confirm.yes'),\n noTitle: option?.noTitle || this.#i18n.t('core.confirm.no'),\n noButtonColor: option?.noButtonColor || 'secondary',\n yesButtonColor: option?.yesButtonColor || 'primary',\n },\n option,\n option?.width || DEFAULT_WIDTH\n );\n };\n\n withInput = (\n message?: string,\n option?: ConfirmDisplayOption & {\n title?: string;\n yesTitle?: string;\n noTitle?: string;\n required?: boolean;\n maxlength?: number;\n yesButtonColor?: Color;\n noButtonColor?: Color;\n defaultValue?: string;\n }\n ): Promise<string> => {\n return this.#open<string>(\n {\n title: option?.title || this.#i18n.t('core.confirm.title'),\n message,\n yesTitle: option?.yesTitle || this.#i18n.t('core.confirm.yes-short'),\n noTitle: option?.noTitle || this.#i18n.t('core.confirm.no-short'),\n noButtonColor: option?.noButtonColor || 'secondary',\n yesButtonColor: option?.yesButtonColor || 'primary',\n input: {\n maxlength: option?.maxlength || 255,\n required: option?.required,\n defaultValue: option?.defaultValue || '',\n },\n },\n option,\n DEFAULT_WIDTH\n );\n };\n\n withRadio = (\n message?: string,\n option?: ConfirmDisplayOption & {\n title?: string;\n yesTitle?: string;\n noTitle?: string;\n required?: boolean;\n yesButtonColor?: Color;\n noButtonColor?: Color;\n defaultValue?: string | number;\n items: any[];\n valueField: string;\n displayField: string;\n display?: 'row' | 'column';\n }\n ): Promise<string> => {\n return this.#open<string>(\n {\n title: option?.title || this.#i18n.t('core.confirm.title'),\n message,\n yesTitle: option?.yesTitle || this.#i18n.t('core.confirm.yes-short'),\n noTitle: option?.noTitle || this.#i18n.t('core.confirm.no-short'),\n noButtonColor: option?.noButtonColor || 'secondary',\n yesButtonColor: option?.yesButtonColor || 'primary',\n radio: {\n items: option?.items || [],\n valueField: option?.valueField || 'value',\n displayField: option?.displayField || 'label',\n display: option?.display || 'row',\n required: option?.required,\n defaultValue: option?.defaultValue,\n },\n },\n option,\n DEFAULT_WIDTH\n );\n };\n\n withDate = (\n message?: string,\n option?: ConfirmDisplayOption & {\n title?: string;\n\n yesTitle?: string;\n noTitle?: string;\n required?: boolean;\n yesButtonColor?: Color;\n noButtonColor?: Color;\n defaultValue?: string | Date;\n placeholder?: string;\n }\n ): Promise<string> => {\n return this.#open<string>(\n {\n title: option?.title || this.#i18n.t('core.confirm.title'),\n message,\n yesTitle: option?.yesTitle || this.#i18n.t('core.confirm.yes-short'),\n noTitle: option?.noTitle || this.#i18n.t('core.confirm.no-short'),\n noButtonColor: option?.noButtonColor || 'secondary',\n yesButtonColor: option?.yesButtonColor || 'primary',\n date: {\n placeholder: option?.placeholder,\n required: option?.required,\n defaultValue: option?.defaultValue || '',\n },\n },\n option,\n DEFAULT_WIDTH\n );\n };\n}\n","/*\n * Public API Surface of superdev-angular-core\n */\n\n// why: DialogConfirmComponent và DialogData là chi tiết nội bộ của SdConfirmService; consumer chỉ dùng service.\nexport * from './lib/confirm.service';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":["i1"],"mappings":"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"}
|