@sdcorejs/angular 20.0.1 → 21.0.0
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/README.md +15 -14
- package/fesm2022/sdcorejs-angular-components-anchor.mjs +28 -28
- package/fesm2022/sdcorejs-angular-components-anchor.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-components-autoid-inspector.mjs +34 -34
- package/fesm2022/sdcorejs-angular-components-autoid-inspector.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-components-avatar.mjs +9 -9
- package/fesm2022/sdcorejs-angular-components-avatar.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-components-badge.mjs +25 -33
- package/fesm2022/sdcorejs-angular-components-badge.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-components-base.mjs +3 -3
- package/fesm2022/sdcorejs-angular-components-button.mjs +19 -29
- package/fesm2022/sdcorejs-angular-components-button.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-components-chart.mjs +28 -28
- package/fesm2022/sdcorejs-angular-components-chart.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-components-ckeditor-styles.mjs +4 -4
- package/fesm2022/sdcorejs-angular-components-ckeditor-styles.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-components-code-editor.mjs +11 -11
- package/fesm2022/sdcorejs-angular-components-code-editor.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-components-document-builder.mjs +6 -6
- package/fesm2022/sdcorejs-angular-components-editor.mjs +36 -48
- package/fesm2022/sdcorejs-angular-components-editor.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-components-form-generic.mjs +212 -212
- package/fesm2022/sdcorejs-angular-components-form-generic.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-components-history.mjs +8 -8
- package/fesm2022/sdcorejs-angular-components-history.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-components-import-excel.mjs +10 -10
- package/fesm2022/sdcorejs-angular-components-inform.mjs +35 -39
- package/fesm2022/sdcorejs-angular-components-inform.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-components-mini-editor.mjs +3 -3
- package/fesm2022/sdcorejs-angular-components-modal.mjs +20 -20
- package/fesm2022/sdcorejs-angular-components-modal.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-components-operator.mjs +11 -11
- package/fesm2022/sdcorejs-angular-components-operator.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-components-preview.mjs +119 -119
- package/fesm2022/sdcorejs-angular-components-preview.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-components-query-bar.mjs +132 -141
- package/fesm2022/sdcorejs-angular-components-query-bar.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-components-query-builder.mjs +3 -3
- package/fesm2022/sdcorejs-angular-components-quick-action.mjs +4 -4
- package/fesm2022/sdcorejs-angular-components-quick-action.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-components-section.mjs +18 -22
- package/fesm2022/sdcorejs-angular-components-section.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-components-side-drawer.mjs +14 -14
- package/fesm2022/sdcorejs-angular-components-side-drawer.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-components-splitter.mjs +36 -38
- package/fesm2022/sdcorejs-angular-components-splitter.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-components-stepper.mjs +24 -24
- package/fesm2022/sdcorejs-angular-components-stepper.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-components-tab-router.mjs +23 -23
- package/fesm2022/sdcorejs-angular-components-tab-router.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-components-tab.mjs +23 -23
- package/fesm2022/sdcorejs-angular-components-tab.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-components-table.mjs +225 -225
- package/fesm2022/sdcorejs-angular-components-table.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-components-upload-file.mjs +70 -106
- package/fesm2022/sdcorejs-angular-components-upload-file.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-components-view.mjs +14 -14
- package/fesm2022/sdcorejs-angular-components-view.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-directives.mjs +30 -30
- package/fesm2022/sdcorejs-angular-directives.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-forms-autocomplete.mjs +61 -76
- package/fesm2022/sdcorejs-angular-forms-autocomplete.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-forms-checkbox.mjs +26 -49
- package/fesm2022/sdcorejs-angular-forms-checkbox.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-forms-chip-calendar.mjs +48 -83
- package/fesm2022/sdcorejs-angular-forms-chip-calendar.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-forms-chip.mjs +47 -82
- package/fesm2022/sdcorejs-angular-forms-chip.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-forms-date-range.mjs +46 -61
- package/fesm2022/sdcorejs-angular-forms-date-range.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-forms-date.mjs +53 -68
- package/fesm2022/sdcorejs-angular-forms-date.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-forms-datetime.mjs +74 -89
- package/fesm2022/sdcorejs-angular-forms-datetime.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-forms-directives.mjs +12 -12
- package/fesm2022/sdcorejs-angular-forms-input-color.mjs +19 -19
- package/fesm2022/sdcorejs-angular-forms-input-color.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-forms-input-number.mjs +56 -71
- package/fesm2022/sdcorejs-angular-forms-input-number.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-forms-input.mjs +58 -73
- package/fesm2022/sdcorejs-angular-forms-input.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-forms-label.mjs +3 -3
- package/fesm2022/sdcorejs-angular-forms-models.mjs +2 -2
- package/fesm2022/sdcorejs-angular-forms-models.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-forms-radio.mjs +39 -70
- package/fesm2022/sdcorejs-angular-forms-radio.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-forms-select.mjs +69 -86
- package/fesm2022/sdcorejs-angular-forms-select.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-forms-switch.mjs +28 -49
- package/fesm2022/sdcorejs-angular-forms-switch.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-forms-textarea.mjs +50 -77
- package/fesm2022/sdcorejs-angular-forms-textarea.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-forms.mjs +4 -4
- package/fesm2022/sdcorejs-angular-handlers.mjs +3 -3
- package/fesm2022/sdcorejs-angular-i18n.mjs +9 -9
- package/fesm2022/sdcorejs-angular-i18n.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-interceptors.mjs +6 -6
- package/fesm2022/sdcorejs-angular-modules-auth.mjs +10 -10
- package/fesm2022/sdcorejs-angular-modules-auth.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-modules-authom.mjs +10 -10
- package/fesm2022/sdcorejs-angular-modules-authom.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-modules-keycloak.mjs +7 -7
- package/fesm2022/sdcorejs-angular-modules-layout.mjs +131 -131
- package/fesm2022/sdcorejs-angular-modules-layout.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-modules-permission.mjs +11 -11
- package/fesm2022/sdcorejs-angular-modules-permission.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-pipes.mjs +14 -14
- package/fesm2022/sdcorejs-angular-services-api.mjs +10 -10
- package/fesm2022/sdcorejs-angular-services-cache.mjs +3 -3
- package/fesm2022/sdcorejs-angular-services-confirm.mjs +6 -6
- package/fesm2022/sdcorejs-angular-services-docx.mjs +3 -3
- package/fesm2022/sdcorejs-angular-services-excel.mjs +3 -3
- package/fesm2022/sdcorejs-angular-services-license.mjs +3 -3
- package/fesm2022/sdcorejs-angular-services-loading.mjs +3 -3
- package/fesm2022/sdcorejs-angular-services-notify.mjs +12 -12
- package/fesm2022/sdcorejs-angular-services-notify.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-services-storage.mjs +3 -3
- package/package.json +82 -82
- package/{forms/select/index.d.ts → types/sdcorejs-angular-forms-select.d.ts} +3 -3
- /package/{components/anchor/index.d.ts → types/sdcorejs-angular-components-anchor.d.ts} +0 -0
- /package/{components/autoid-inspector/index.d.ts → types/sdcorejs-angular-components-autoid-inspector.d.ts} +0 -0
- /package/{components/avatar/index.d.ts → types/sdcorejs-angular-components-avatar.d.ts} +0 -0
- /package/{components/badge/index.d.ts → types/sdcorejs-angular-components-badge.d.ts} +0 -0
- /package/{components/base/index.d.ts → types/sdcorejs-angular-components-base.d.ts} +0 -0
- /package/{components/button/index.d.ts → types/sdcorejs-angular-components-button.d.ts} +0 -0
- /package/{components/chart/index.d.ts → types/sdcorejs-angular-components-chart.d.ts} +0 -0
- /package/{components/ckeditor-styles/index.d.ts → types/sdcorejs-angular-components-ckeditor-styles.d.ts} +0 -0
- /package/{components/code-editor/index.d.ts → types/sdcorejs-angular-components-code-editor.d.ts} +0 -0
- /package/{components/document-builder/index.d.ts → types/sdcorejs-angular-components-document-builder.d.ts} +0 -0
- /package/{components/editor/index.d.ts → types/sdcorejs-angular-components-editor.d.ts} +0 -0
- /package/{components/form-generic/index.d.ts → types/sdcorejs-angular-components-form-generic.d.ts} +0 -0
- /package/{components/history/index.d.ts → types/sdcorejs-angular-components-history.d.ts} +0 -0
- /package/{components/import-excel/index.d.ts → types/sdcorejs-angular-components-import-excel.d.ts} +0 -0
- /package/{components/inform/index.d.ts → types/sdcorejs-angular-components-inform.d.ts} +0 -0
- /package/{components/mini-editor/index.d.ts → types/sdcorejs-angular-components-mini-editor.d.ts} +0 -0
- /package/{components/modal/index.d.ts → types/sdcorejs-angular-components-modal.d.ts} +0 -0
- /package/{components/operator/index.d.ts → types/sdcorejs-angular-components-operator.d.ts} +0 -0
- /package/{components/preview/index.d.ts → types/sdcorejs-angular-components-preview.d.ts} +0 -0
- /package/{components/query-bar/index.d.ts → types/sdcorejs-angular-components-query-bar.d.ts} +0 -0
- /package/{components/query-builder/index.d.ts → types/sdcorejs-angular-components-query-builder.d.ts} +0 -0
- /package/{components/quick-action/index.d.ts → types/sdcorejs-angular-components-quick-action.d.ts} +0 -0
- /package/{components/section/index.d.ts → types/sdcorejs-angular-components-section.d.ts} +0 -0
- /package/{components/side-drawer/index.d.ts → types/sdcorejs-angular-components-side-drawer.d.ts} +0 -0
- /package/{components/splitter/index.d.ts → types/sdcorejs-angular-components-splitter.d.ts} +0 -0
- /package/{components/stepper/index.d.ts → types/sdcorejs-angular-components-stepper.d.ts} +0 -0
- /package/{components/tab-router/index.d.ts → types/sdcorejs-angular-components-tab-router.d.ts} +0 -0
- /package/{components/tab/index.d.ts → types/sdcorejs-angular-components-tab.d.ts} +0 -0
- /package/{components/table/index.d.ts → types/sdcorejs-angular-components-table.d.ts} +0 -0
- /package/{components/upload-file/index.d.ts → types/sdcorejs-angular-components-upload-file.d.ts} +0 -0
- /package/{components/view/index.d.ts → types/sdcorejs-angular-components-view.d.ts} +0 -0
- /package/{components/index.d.ts → types/sdcorejs-angular-components.d.ts} +0 -0
- /package/{configurations/index.d.ts → types/sdcorejs-angular-configurations.d.ts} +0 -0
- /package/{directives/index.d.ts → types/sdcorejs-angular-directives.d.ts} +0 -0
- /package/{forms/autocomplete/index.d.ts → types/sdcorejs-angular-forms-autocomplete.d.ts} +0 -0
- /package/{forms/checkbox/index.d.ts → types/sdcorejs-angular-forms-checkbox.d.ts} +0 -0
- /package/{forms/chip-calendar/index.d.ts → types/sdcorejs-angular-forms-chip-calendar.d.ts} +0 -0
- /package/{forms/chip/index.d.ts → types/sdcorejs-angular-forms-chip.d.ts} +0 -0
- /package/{forms/date-range/index.d.ts → types/sdcorejs-angular-forms-date-range.d.ts} +0 -0
- /package/{forms/date/index.d.ts → types/sdcorejs-angular-forms-date.d.ts} +0 -0
- /package/{forms/datetime/index.d.ts → types/sdcorejs-angular-forms-datetime.d.ts} +0 -0
- /package/{forms/directives/index.d.ts → types/sdcorejs-angular-forms-directives.d.ts} +0 -0
- /package/{forms/input-color/index.d.ts → types/sdcorejs-angular-forms-input-color.d.ts} +0 -0
- /package/{forms/input-number/index.d.ts → types/sdcorejs-angular-forms-input-number.d.ts} +0 -0
- /package/{forms/input/index.d.ts → types/sdcorejs-angular-forms-input.d.ts} +0 -0
- /package/{forms/label/index.d.ts → types/sdcorejs-angular-forms-label.d.ts} +0 -0
- /package/{forms/models/index.d.ts → types/sdcorejs-angular-forms-models.d.ts} +0 -0
- /package/{forms/radio/index.d.ts → types/sdcorejs-angular-forms-radio.d.ts} +0 -0
- /package/{forms/switch/index.d.ts → types/sdcorejs-angular-forms-switch.d.ts} +0 -0
- /package/{forms/textarea/index.d.ts → types/sdcorejs-angular-forms-textarea.d.ts} +0 -0
- /package/{forms/index.d.ts → types/sdcorejs-angular-forms.d.ts} +0 -0
- /package/{handlers/index.d.ts → types/sdcorejs-angular-handlers.d.ts} +0 -0
- /package/{i18n/index.d.ts → types/sdcorejs-angular-i18n.d.ts} +0 -0
- /package/{interceptors/index.d.ts → types/sdcorejs-angular-interceptors.d.ts} +0 -0
- /package/{models/index.d.ts → types/sdcorejs-angular-models.d.ts} +0 -0
- /package/{modules/auth/index.d.ts → types/sdcorejs-angular-modules-auth.d.ts} +0 -0
- /package/{modules/authom/index.d.ts → types/sdcorejs-angular-modules-authom.d.ts} +0 -0
- /package/{modules/keycloak/index.d.ts → types/sdcorejs-angular-modules-keycloak.d.ts} +0 -0
- /package/{modules/layout/index.d.ts → types/sdcorejs-angular-modules-layout.d.ts} +0 -0
- /package/{modules/permission/index.d.ts → types/sdcorejs-angular-modules-permission.d.ts} +0 -0
- /package/{modules/index.d.ts → types/sdcorejs-angular-modules.d.ts} +0 -0
- /package/{pipes/index.d.ts → types/sdcorejs-angular-pipes.d.ts} +0 -0
- /package/{services/api/index.d.ts → types/sdcorejs-angular-services-api.d.ts} +0 -0
- /package/{services/cache/index.d.ts → types/sdcorejs-angular-services-cache.d.ts} +0 -0
- /package/{services/confirm/index.d.ts → types/sdcorejs-angular-services-confirm.d.ts} +0 -0
- /package/{services/docx/index.d.ts → types/sdcorejs-angular-services-docx.d.ts} +0 -0
- /package/{services/excel/index.d.ts → types/sdcorejs-angular-services-excel.d.ts} +0 -0
- /package/{services/license/index.d.ts → types/sdcorejs-angular-services-license.d.ts} +0 -0
- /package/{services/loading/index.d.ts → types/sdcorejs-angular-services-loading.d.ts} +0 -0
- /package/{services/notify/index.d.ts → types/sdcorejs-angular-services-notify.d.ts} +0 -0
- /package/{services/storage/index.d.ts → types/sdcorejs-angular-services-storage.d.ts} +0 -0
- /package/{services/index.d.ts → types/sdcorejs-angular-services.d.ts} +0 -0
- /package/{utilities/data-state/index.d.ts → types/sdcorejs-angular-utilities-data-state.d.ts} +0 -0
- /package/{utilities/extensions/index.d.ts → types/sdcorejs-angular-utilities-extensions.d.ts} +0 -0
- /package/{utilities/models/index.d.ts → types/sdcorejs-angular-utilities-models.d.ts} +0 -0
- /package/{utilities/index.d.ts → types/sdcorejs-angular-utilities.d.ts} +0 -0
- /package/{index.d.ts → types/sdcorejs-angular.d.ts} +0 -0
|
@@ -135,10 +135,10 @@ class SdAutoidScannerService {
|
|
|
135
135
|
return input.value;
|
|
136
136
|
return (node.textContent ?? '').trim().slice(0, 80);
|
|
137
137
|
}
|
|
138
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
139
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "
|
|
138
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.15", ngImport: i0, type: SdAutoidScannerService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
139
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.15", ngImport: i0, type: SdAutoidScannerService, providedIn: 'root' });
|
|
140
140
|
}
|
|
141
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
141
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.15", ngImport: i0, type: SdAutoidScannerService, decorators: [{
|
|
142
142
|
type: Injectable,
|
|
143
143
|
args: [{ providedIn: 'root' }]
|
|
144
144
|
}] });
|
|
@@ -221,10 +221,10 @@ class SdAutoidAuditService {
|
|
|
221
221
|
?? node.getAttribute('title')
|
|
222
222
|
?? '';
|
|
223
223
|
}
|
|
224
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
225
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "
|
|
224
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.15", ngImport: i0, type: SdAutoidAuditService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
225
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.15", ngImport: i0, type: SdAutoidAuditService, providedIn: 'root' });
|
|
226
226
|
}
|
|
227
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
227
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.15", ngImport: i0, type: SdAutoidAuditService, decorators: [{
|
|
228
228
|
type: Injectable,
|
|
229
229
|
args: [{ providedIn: 'root' }]
|
|
230
230
|
}] });
|
|
@@ -325,10 +325,10 @@ class SdAutoidHighlightService {
|
|
|
325
325
|
}
|
|
326
326
|
node.setAttribute(ATTR, marker);
|
|
327
327
|
}
|
|
328
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
329
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "
|
|
328
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.15", ngImport: i0, type: SdAutoidHighlightService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
329
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.15", ngImport: i0, type: SdAutoidHighlightService, providedIn: 'root' });
|
|
330
330
|
}
|
|
331
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
331
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.15", ngImport: i0, type: SdAutoidHighlightService, decorators: [{
|
|
332
332
|
type: Injectable,
|
|
333
333
|
args: [{ providedIn: 'root' }]
|
|
334
334
|
}] });
|
|
@@ -502,10 +502,10 @@ class SdAutoidExportService {
|
|
|
502
502
|
.map(p => p[0].toUpperCase() + p.slice(1))
|
|
503
503
|
.join('');
|
|
504
504
|
}
|
|
505
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
506
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "
|
|
505
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.15", ngImport: i0, type: SdAutoidExportService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
506
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.15", ngImport: i0, type: SdAutoidExportService, providedIn: 'root' });
|
|
507
507
|
}
|
|
508
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
508
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.15", ngImport: i0, type: SdAutoidExportService, decorators: [{
|
|
509
509
|
type: Injectable,
|
|
510
510
|
args: [{ providedIn: 'root' }]
|
|
511
511
|
}] });
|
|
@@ -514,22 +514,22 @@ class SdAutoidInspector {
|
|
|
514
514
|
// ==========================================
|
|
515
515
|
// INPUTS
|
|
516
516
|
// ==========================================
|
|
517
|
-
enabled = input(true, ...(ngDevMode ?
|
|
518
|
-
config = input(undefined, ...(ngDevMode ? [{ debugName: "config" }] : []));
|
|
517
|
+
enabled = input(true, { ...(ngDevMode ? { debugName: "enabled" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
518
|
+
config = input(undefined, ...(ngDevMode ? [{ debugName: "config" }] : /* istanbul ignore next */ []));
|
|
519
519
|
// ==========================================
|
|
520
520
|
// STATE
|
|
521
521
|
// ==========================================
|
|
522
|
-
open = signal(false, ...(ngDevMode ? [{ debugName: "open" }] : []));
|
|
523
|
-
segment = signal('audit', ...(ngDevMode ? [{ debugName: "segment" }] : []));
|
|
524
|
-
filter = signal('', ...(ngDevMode ? [{ debugName: "filter" }] : []));
|
|
525
|
-
elements = signal([], ...(ngDevMode ? [{ debugName: "elements" }] : []));
|
|
526
|
-
audit = signal(null, ...(ngDevMode ? [{ debugName: "audit" }] : []));
|
|
527
|
-
copyOk = signal(false, ...(ngDevMode ? [{ debugName: "copyOk" }] : []));
|
|
522
|
+
open = signal(false, ...(ngDevMode ? [{ debugName: "open" }] : /* istanbul ignore next */ []));
|
|
523
|
+
segment = signal('audit', ...(ngDevMode ? [{ debugName: "segment" }] : /* istanbul ignore next */ []));
|
|
524
|
+
filter = signal('', ...(ngDevMode ? [{ debugName: "filter" }] : /* istanbul ignore next */ []));
|
|
525
|
+
elements = signal([], ...(ngDevMode ? [{ debugName: "elements" }] : /* istanbul ignore next */ []));
|
|
526
|
+
audit = signal(null, ...(ngDevMode ? [{ debugName: "audit" }] : /* istanbul ignore next */ []));
|
|
527
|
+
copyOk = signal(false, ...(ngDevMode ? [{ debugName: "copyOk" }] : /* istanbul ignore next */ []));
|
|
528
528
|
// Default true để mở panel lần đầu là có highlight ngay. Đóng panel KHÔNG
|
|
529
529
|
// tự tắt — user toggle qua nút trong tab Audit khi muốn nhìn DOM gốc.
|
|
530
|
-
highlightOn = signal(true, ...(ngDevMode ? [{ debugName: "highlightOn" }] : []));
|
|
530
|
+
highlightOn = signal(true, ...(ngDevMode ? [{ debugName: "highlightOn" }] : /* istanbul ignore next */ []));
|
|
531
531
|
// Ẩn tạm FAB — chỉ in-memory, reload trang sẽ hiện lại (theo thiết kế).
|
|
532
|
-
dismissed = signal(false, ...(ngDevMode ? [{ debugName: "dismissed" }] : []));
|
|
532
|
+
dismissed = signal(false, ...(ngDevMode ? [{ debugName: "dismissed" }] : /* istanbul ignore next */ []));
|
|
533
533
|
filteredElements = computed(() => {
|
|
534
534
|
const q = this.filter().trim().toLowerCase();
|
|
535
535
|
if (!q)
|
|
@@ -537,11 +537,11 @@ class SdAutoidInspector {
|
|
|
537
537
|
return this.elements().filter(el => el.autoid.toLowerCase().includes(q) ||
|
|
538
538
|
el.name.toLowerCase().includes(q) ||
|
|
539
539
|
el.tag.toLowerCase().includes(q));
|
|
540
|
-
}, ...(ngDevMode ? [{ debugName: "filteredElements" }] : []));
|
|
540
|
+
}, ...(ngDevMode ? [{ debugName: "filteredElements" }] : /* istanbul ignore next */ []));
|
|
541
541
|
/**
|
|
542
542
|
* Elements not inside any sd-table — rendered in the main "Top-level" section.
|
|
543
543
|
*/
|
|
544
|
-
topLevelElements = computed(() => this.filteredElements().filter(el => !el.tableScope), ...(ngDevMode ? [{ debugName: "topLevelElements" }] : []));
|
|
544
|
+
topLevelElements = computed(() => this.filteredElements().filter(el => !el.tableScope), ...(ngDevMode ? [{ debugName: "topLevelElements" }] : /* istanbul ignore next */ []));
|
|
545
545
|
/**
|
|
546
546
|
* Map of `sd-table` autoid → its inner autoid elements. Tables themselves
|
|
547
547
|
* stay in `topLevelElements` (the table's own autoid is top-level).
|
|
@@ -559,16 +559,16 @@ class SdAutoidInspector {
|
|
|
559
559
|
return [...groups.entries()]
|
|
560
560
|
.sort(([a], [b]) => a.localeCompare(b))
|
|
561
561
|
.map(([scope, items]) => ({ scope, items }));
|
|
562
|
-
}, ...(ngDevMode ? [{ debugName: "tableGroups" }] : []));
|
|
562
|
+
}, ...(ngDevMode ? [{ debugName: "tableGroups" }] : /* istanbul ignore next */ []));
|
|
563
563
|
// ==========================================
|
|
564
564
|
// DATA-* ATTRIBUTE COMPUTEDS (for E2E selectors)
|
|
565
565
|
// ==========================================
|
|
566
|
-
dataOpened = computed(() => (this.open() ? 'true' : 'false'), ...(ngDevMode ? [{ debugName: "dataOpened" }] : []));
|
|
567
|
-
dataHighlightOn = computed(() => (this.highlightOn() ? 'true' : 'false'), ...(ngDevMode ? [{ debugName: "dataHighlightOn" }] : []));
|
|
568
|
-
dataSegment = computed(() => this.segment(), ...(ngDevMode ? [{ debugName: "dataSegment" }] : []));
|
|
569
|
-
dataElementCount = computed(() => String(this.elements().length), ...(ngDevMode ? [{ debugName: "dataElementCount" }] : []));
|
|
570
|
-
dataMissingCount = computed(() => String(this.audit()?.missingCount ?? 0), ...(ngDevMode ? [{ debugName: "dataMissingCount" }] : []));
|
|
571
|
-
dataDuplicateCount = computed(() => String(this.audit()?.duplicateCount ?? 0), ...(ngDevMode ? [{ debugName: "dataDuplicateCount" }] : []));
|
|
566
|
+
dataOpened = computed(() => (this.open() ? 'true' : 'false'), ...(ngDevMode ? [{ debugName: "dataOpened" }] : /* istanbul ignore next */ []));
|
|
567
|
+
dataHighlightOn = computed(() => (this.highlightOn() ? 'true' : 'false'), ...(ngDevMode ? [{ debugName: "dataHighlightOn" }] : /* istanbul ignore next */ []));
|
|
568
|
+
dataSegment = computed(() => this.segment(), ...(ngDevMode ? [{ debugName: "dataSegment" }] : /* istanbul ignore next */ []));
|
|
569
|
+
dataElementCount = computed(() => String(this.elements().length), ...(ngDevMode ? [{ debugName: "dataElementCount" }] : /* istanbul ignore next */ []));
|
|
570
|
+
dataMissingCount = computed(() => String(this.audit()?.missingCount ?? 0), ...(ngDevMode ? [{ debugName: "dataMissingCount" }] : /* istanbul ignore next */ []));
|
|
571
|
+
dataDuplicateCount = computed(() => String(this.audit()?.duplicateCount ?? 0), ...(ngDevMode ? [{ debugName: "dataDuplicateCount" }] : /* istanbul ignore next */ []));
|
|
572
572
|
// ==========================================
|
|
573
573
|
// SERVICES
|
|
574
574
|
// ==========================================
|
|
@@ -704,10 +704,10 @@ class SdAutoidInspector {
|
|
|
704
704
|
this.copyOk.set(true);
|
|
705
705
|
setTimeout(() => this.copyOk.set(false), 1200);
|
|
706
706
|
}
|
|
707
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
708
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.23", type: SdAutoidInspector, isStandalone: true, selector: "sd-autoid-inspector", inputs: { enabled: { classPropertyName: "enabled", publicName: "enabled", isSignal: true, isRequired: false, transformFunction: null }, config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: false, transformFunction: null } }, host: { listeners: { "document:keydown.escape": "onEscape()" } }, ngImport: i0, template: "@if (enabled() && !dismissed()) {\n <div class=\"sd-autoid-inspector__fab-wrap\">\n <button\n type=\"button\"\n class=\"sd-autoid-inspector__fab\"\n data-autoid=\"sd-autoid-inspector-fab\"\n [attr.data-opened]=\"dataOpened()\"\n [matTooltip]=\"open() ? '\u0110\u00F3ng AutoId Inspector' : 'M\u1EDF AutoId Inspector'\"\n matTooltipPosition=\"left\"\n (click)=\"togglePanel()\">\n <mat-icon>{{ open() ? 'close' : 'tag' }}</mat-icon>\n </button>\n <button\n type=\"button\"\n class=\"sd-autoid-inspector__fab-dismiss\"\n matTooltip=\"\u1EA8n t\u1EA1m \u2014 reload trang \u0111\u1EC3 hi\u1EC7n l\u1EA1i\"\n matTooltipPosition=\"left\"\n aria-label=\"\u1EA8n t\u1EA1m FAB\"\n (click)=\"dismissFab($event)\">\n <mat-icon>close</mat-icon>\n </button>\n </div>\n\n}\n\n@if (enabled() && open()) {\n <div class=\"sd-autoid-inspector__backdrop\" (click)=\"closePanel()\"></div>\n <section class=\"sd-autoid-inspector__panel\"\n role=\"dialog\"\n aria-label=\"AutoId Inspector\"\n data-autoid=\"sd-autoid-inspector-panel\"\n [attr.data-segment]=\"dataSegment()\"\n [attr.data-highlight-on]=\"dataHighlightOn()\"\n [attr.data-element-count]=\"dataElementCount()\"\n [attr.data-missing-count]=\"dataMissingCount()\"\n [attr.data-duplicate-count]=\"dataDuplicateCount()\">\n <header class=\"sd-autoid-inspector__header\">\n <div class=\"sd-autoid-inspector__segments\">\n <button\n type=\"button\"\n [class.is-active]=\"segment() === 'audit'\"\n (click)=\"setSegment('audit')\">\n Audit\n @if (audit(); as a) {\n <span class=\"sd-autoid-inspector__badge\" [class.is-warn]=\"a.missingCount + a.duplicateCount > 0\">\n {{ a.missingCount + a.duplicateCount }}\n </span>\n }\n </button>\n <button\n type=\"button\"\n [class.is-active]=\"segment() === 'elements'\"\n (click)=\"setSegment('elements')\">\n Elements\n <span class=\"sd-autoid-inspector__badge\">{{ elements().length }}</span>\n </button>\n <button\n type=\"button\"\n [class.is-active]=\"segment() === 'export'\"\n (click)=\"setSegment('export')\">\n Export\n </button>\n </div>\n <div class=\"sd-autoid-inspector__actions\">\n <button\n type=\"button\"\n class=\"sd-autoid-inspector__icon-btn\"\n matTooltip=\"Qu\u00E9t l\u1EA1i\"\n (click)=\"refresh()\">\n <mat-icon>refresh</mat-icon>\n </button>\n <button\n type=\"button\"\n class=\"sd-autoid-inspector__close-btn\"\n matTooltip=\"\u0110\u00F3ng\"\n aria-label=\"\u0110\u00F3ng panel\"\n (click)=\"closePanel()\">\n <mat-icon>close</mat-icon>\n </button>\n </div>\n </header>\n\n @if (copyOk()) {\n <div class=\"sd-autoid-inspector__toast\">\u0110\u00E3 copy \u2713</div>\n }\n\n <div class=\"sd-autoid-inspector__body\">\n @switch (segment()) {\n @case ('audit') {\n <ng-container *ngTemplateOutlet=\"auditTpl\"></ng-container>\n }\n @case ('elements') {\n <ng-container *ngTemplateOutlet=\"elementsTpl\"></ng-container>\n }\n @case ('export') {\n <ng-container *ngTemplateOutlet=\"exportTpl\"></ng-container>\n }\n }\n </div>\n </section>\n\n <ng-template #auditTpl>\n @if (audit(); as a) {\n <div class=\"sd-autoid-inspector__audit-toolbar\">\n <button\n type=\"button\"\n class=\"sd-autoid-inspector__toggle\"\n [class.is-on]=\"highlightOn()\"\n (click)=\"toggleHighlight()\">\n <mat-icon>{{ highlightOn() ? 'visibility' : 'visibility_off' }}</mat-icon>\n <span>Highlight DOM</span>\n <span class=\"sd-autoid-inspector__toggle-state\">{{ highlightOn() ? 'ON' : 'OFF' }}</span>\n </button>\n </div>\n <div class=\"sd-autoid-inspector__summary\">\n <div class=\"sd-autoid-inspector__stat is-info\">\n <div class=\"sd-autoid-inspector__stat-value\">{{ a.total }}</div>\n <div class=\"sd-autoid-inspector__stat-label\">T\u1ED5ng autoid</div>\n </div>\n <div class=\"sd-autoid-inspector__stat\" [class.is-error]=\"a.duplicateCount > 0\" [class.is-success]=\"a.duplicateCount === 0\">\n <div class=\"sd-autoid-inspector__stat-value\">{{ a.duplicateCount }}</div>\n <div class=\"sd-autoid-inspector__stat-label\">Tr\u00F9ng</div>\n </div>\n <div class=\"sd-autoid-inspector__stat\" [class.is-warning]=\"a.missingCount > 0\" [class.is-success]=\"a.missingCount === 0\">\n <div class=\"sd-autoid-inspector__stat-value\">{{ a.missingCount }}</div>\n <div class=\"sd-autoid-inspector__stat-label\">Thi\u1EBFu</div>\n </div>\n </div>\n\n @if (a.duplicateCount > 0) {\n <h4 class=\"sd-autoid-inspector__section-title\">\n <mat-icon class=\"is-error\">error_outline</mat-icon>\n Autoid b\u1ECB tr\u00F9ng\n </h4>\n <div class=\"sd-autoid-inspector__table-wrap\">\n <table class=\"sd-autoid-inspector__table\">\n <thead>\n <tr><th>Autoid</th><th>S\u1ED1 l\u1EA7n</th></tr>\n </thead>\n <tbody>\n @for (entry of a.duplicates | keyvalue; track entry.key) {\n <tr class=\"is-error\">\n <td><code>{{ entry.key }}</code></td>\n <td>{{ entry.value }}</td>\n </tr>\n }\n </tbody>\n </table>\n </div>\n }\n\n @if (a.missingCount > 0) {\n <h4 class=\"sd-autoid-inspector__section-title\">\n <mat-icon class=\"is-warning\">warning_amber</mat-icon>\n Element thi\u1EBFu autoid\n </h4>\n <div class=\"sd-autoid-inspector__table-wrap\">\n <table class=\"sd-autoid-inspector__table\">\n <thead>\n <tr><th>Tag</th><th>Name hint</th><th>Selector</th></tr>\n </thead>\n <tbody>\n @for (m of a.missing; track $index) {\n <tr class=\"is-warning\">\n <td><code>{{ m.tag }}</code></td>\n <td>{{ m.nameHint }}</td>\n <td><code>{{ m.selector }}</code></td>\n </tr>\n }\n </tbody>\n </table>\n </div>\n }\n\n @if (a.duplicateCount === 0 && a.missingCount === 0) {\n <div class=\"sd-autoid-inspector__success-card\">\n <mat-icon>check_circle</mat-icon>\n <div>\n <strong>Kh\u00F4ng c\u00F3 element thi\u1EBFu ho\u1EB7c tr\u00F9ng autoid.</strong>\n <small>Trang \u0111\u00E3 \u0111\u1EA1t chu\u1EA9n convention autoid.</small>\n </div>\n </div>\n }\n }\n </ng-template>\n\n <ng-template #elementsTpl>\n <div class=\"sd-autoid-inspector__filter\">\n <mat-icon>search</mat-icon>\n <input\n type=\"text\"\n placeholder=\"L\u1ECDc theo autoid / name / tag\"\n [ngModel]=\"filter()\"\n (ngModelChange)=\"filter.set($event)\"/>\n @if (filter()) {\n <button\n type=\"button\"\n class=\"sd-autoid-inspector__icon-btn\"\n matTooltip=\"Xo\u00E1 filter\"\n (click)=\"filter.set('')\">\n <mat-icon>close</mat-icon>\n </button>\n }\n </div>\n\n <!-- Top-level elements (not inside any sd-table) -->\n <h4 class=\"sd-autoid-inspector__section-title\">\n Top-level elements\n <span class=\"sd-autoid-inspector__badge\">{{ topLevelElements().length }}</span>\n </h4>\n <div class=\"sd-autoid-inspector__table-wrap\">\n <table class=\"sd-autoid-inspector__table\">\n <thead>\n <tr>\n <th class=\"is-num\">STT</th>\n <th>Name</th>\n <th>Autoid</th>\n <th>Tag</th>\n <th>State</th>\n <th>Value</th>\n </tr>\n </thead>\n <tbody>\n @for (el of topLevelElements(); track el.autoid + $index) {\n <tr [class.is-error]=\"el.duplicate\">\n <td class=\"is-num\">{{ el.stt }}</td>\n <td>{{ el.name || '\u2014' }}</td>\n <td>\n <div class=\"sd-autoid-inspector__autoid-cell\">\n <code>{{ el.autoid }}</code>\n <button\n type=\"button\"\n class=\"sd-autoid-inspector__icon-btn is-primary\"\n matTooltip=\"Copy xpath\"\n (click)=\"copyXpath(el.autoid)\">\n <mat-icon>content_copy</mat-icon>\n </button>\n </div>\n </td>\n <td><span class=\"sd-autoid-inspector__tag-chip\">{{ el.tag }}</span></td>\n <td class=\"sd-autoid-inspector__state-cell\">\n @if (el.state.disabled !== undefined) {\n <span class=\"sd-autoid-inspector__state-chip\"\n [class.is-error]=\"el.state.disabled === 'true'\">\n disabled={{ el.state.disabled }}\n </span>\n }\n @if (el.state.loading !== undefined) {\n <span class=\"sd-autoid-inspector__state-chip\"\n [class.is-warning]=\"el.state.loading === 'true'\">\n loading={{ el.state.loading }}\n </span>\n }\n @if (el.state.empty !== undefined) {\n <span class=\"sd-autoid-inspector__state-chip\"\n [class.is-info]=\"el.state.empty === 'true'\">\n empty={{ el.state.empty }}\n </span>\n }\n @if (el.state.invalid !== undefined) {\n <span class=\"sd-autoid-inspector__state-chip\"\n [class.is-error]=\"el.state.invalid === 'true'\">\n invalid={{ el.state.invalid }}\n </span>\n }\n @if (el.state.opened !== undefined) {\n <span class=\"sd-autoid-inspector__state-chip\"\n [class.is-info]=\"el.state.opened === 'true'\">\n opened={{ el.state.opened }}\n </span>\n }\n @if (el.state.count !== undefined) {\n <span class=\"sd-autoid-inspector__state-chip is-info\">\n count={{ el.state.count }}\n </span>\n }\n @if (el.state.required !== undefined) {\n <span class=\"sd-autoid-inspector__state-chip\"\n [class.is-warning]=\"el.state.required === 'true'\">\n required={{ el.state.required }}\n </span>\n }\n @if (el.state.maxlength !== undefined) {\n <span class=\"sd-autoid-inspector__state-chip is-info\">\n maxlength={{ el.state.maxlength }}\n </span>\n }\n @if (el.state.minlength !== undefined) {\n <span class=\"sd-autoid-inspector__state-chip is-info\">\n minlength={{ el.state.minlength }}\n </span>\n }\n @if (el.state.pattern !== undefined) {\n <span class=\"sd-autoid-inspector__state-chip is-info\">\n pattern={{ el.state.pattern }}\n </span>\n }\n @if (el.state.errorMessage !== undefined) {\n <span class=\"sd-autoid-inspector__state-chip is-error\">\n error: {{ el.state.errorMessage }}\n </span>\n }\n </td>\n <td class=\"sd-autoid-inspector__value\" [matTooltip]=\"el.state.dataValue || el.text || ''\">\n {{ el.state.dataValue || el.text || '\u2014' }}\n </td>\n </tr>\n } @empty {\n <tr><td colspan=\"6\" class=\"sd-autoid-inspector__empty\">Kh\u00F4ng c\u00F3 k\u1EBFt qu\u1EA3.</td></tr>\n }\n </tbody>\n </table>\n </div>\n\n <!-- One section per sd-table group -->\n @for (group of tableGroups(); track group.scope) {\n <h4 class=\"sd-autoid-inspector__section-title\">\n <mat-icon class=\"is-info\">table_chart</mat-icon>\n Inside <code>{{ group.scope }}</code>\n <span class=\"sd-autoid-inspector__badge\">{{ group.items.length }}</span>\n </h4>\n <div class=\"sd-autoid-inspector__table-wrap\">\n <table class=\"sd-autoid-inspector__table\">\n <thead>\n <tr>\n <th class=\"is-num\">STT</th>\n <th>Name</th>\n <th>Autoid</th>\n <th>Tag</th>\n <th>State</th>\n <th>Value</th>\n </tr>\n </thead>\n <tbody>\n @for (el of group.items; track el.autoid + $index) {\n <tr [class.is-error]=\"el.duplicate\">\n <td class=\"is-num\">{{ el.stt }}</td>\n <td>{{ el.name || '\u2014' }}</td>\n <td>\n <div class=\"sd-autoid-inspector__autoid-cell\">\n <code>{{ el.autoid }}</code>\n <button\n type=\"button\"\n class=\"sd-autoid-inspector__icon-btn is-primary\"\n matTooltip=\"Copy xpath\"\n (click)=\"copyXpath(el.autoid)\">\n <mat-icon>content_copy</mat-icon>\n </button>\n </div>\n </td>\n <td><span class=\"sd-autoid-inspector__tag-chip\">{{ el.tag }}</span></td>\n <td class=\"sd-autoid-inspector__state-cell\">\n @if (el.state.disabled !== undefined) {\n <span class=\"sd-autoid-inspector__state-chip\"\n [class.is-error]=\"el.state.disabled === 'true'\">\n disabled={{ el.state.disabled }}\n </span>\n }\n @if (el.state.loading !== undefined) {\n <span class=\"sd-autoid-inspector__state-chip\"\n [class.is-warning]=\"el.state.loading === 'true'\">\n loading={{ el.state.loading }}\n </span>\n }\n @if (el.state.empty !== undefined) {\n <span class=\"sd-autoid-inspector__state-chip\"\n [class.is-info]=\"el.state.empty === 'true'\">\n empty={{ el.state.empty }}\n </span>\n }\n @if (el.state.invalid !== undefined) {\n <span class=\"sd-autoid-inspector__state-chip\"\n [class.is-error]=\"el.state.invalid === 'true'\">\n invalid={{ el.state.invalid }}\n </span>\n }\n @if (el.state.opened !== undefined) {\n <span class=\"sd-autoid-inspector__state-chip\"\n [class.is-info]=\"el.state.opened === 'true'\">\n opened={{ el.state.opened }}\n </span>\n }\n @if (el.state.count !== undefined) {\n <span class=\"sd-autoid-inspector__state-chip is-info\">\n count={{ el.state.count }}\n </span>\n }\n @if (el.state.required !== undefined) {\n <span class=\"sd-autoid-inspector__state-chip\"\n [class.is-warning]=\"el.state.required === 'true'\">\n required={{ el.state.required }}\n </span>\n }\n @if (el.state.maxlength !== undefined) {\n <span class=\"sd-autoid-inspector__state-chip is-info\">\n maxlength={{ el.state.maxlength }}\n </span>\n }\n @if (el.state.minlength !== undefined) {\n <span class=\"sd-autoid-inspector__state-chip is-info\">\n minlength={{ el.state.minlength }}\n </span>\n }\n @if (el.state.pattern !== undefined) {\n <span class=\"sd-autoid-inspector__state-chip is-info\">\n pattern={{ el.state.pattern }}\n </span>\n }\n @if (el.state.errorMessage !== undefined) {\n <span class=\"sd-autoid-inspector__state-chip is-error\">\n error: {{ el.state.errorMessage }}\n </span>\n }\n </td>\n <td class=\"sd-autoid-inspector__value\" [matTooltip]=\"el.state.dataValue || el.text || ''\">\n {{ el.state.dataValue || el.text || '\u2014' }}\n </td>\n </tr>\n }\n </tbody>\n </table>\n </div>\n }\n </ng-template>\n\n <ng-template #exportTpl>\n <div class=\"sd-autoid-inspector__export-grid\">\n <button type=\"button\" matTooltip=\"Copy JSON v\u00E0o clipboard\" (click)=\"copyJson()\">\n <mat-icon>content_copy</mat-icon>\n <span>Copy JSON</span>\n <small>clipboard</small>\n </button>\n <button type=\"button\" matTooltip=\"T\u1EA3i file JSON\" (click)=\"exportJson()\">\n <mat-icon>download</mat-icon>\n <span>JSON</span>\n <small>.json</small>\n </button>\n <button type=\"button\" matTooltip=\"T\u1EA3i file CSV\" (click)=\"exportCsv()\">\n <mat-icon>table_view</mat-icon>\n <span>CSV</span>\n <small>.csv</small>\n </button>\n <button type=\"button\" matTooltip=\"T\u1EA3i MD POM skeleton \u2014 cho AI vi\u1EBFt auto-test\" (click)=\"exportMdPom()\">\n <mat-icon>code</mat-icon>\n <span>MD POM</span>\n <small>AI test</small>\n </button>\n <button type=\"button\" matTooltip=\"T\u1EA3i MD reference table \u2014 group theo tag sd-*\" (click)=\"exportMdTable()\">\n <mat-icon>view_list</mat-icon>\n <span>MD Table</span>\n <small>reference</small>\n </button>\n </div>\n </ng-template>\n}\n", styles: [":host{position:fixed;inset:auto 0 0 auto;z-index:100000;font-family:system-ui,-apple-system,Segoe UI,Roboto,sans-serif;font-size:13px;color:var(--sd-black500, #212121)}.sd-autoid-inspector__fab-wrap{position:fixed;right:16px;bottom:16px;z-index:100000}.sd-autoid-inspector__fab-wrap:hover .sd-autoid-inspector__fab-dismiss{opacity:1;transform:scale(1);pointer-events:auto}.sd-autoid-inspector__fab{width:36px;height:36px;border-radius:50%;border:none;background:var(--sd-primary, #2A66F4);color:#fff;cursor:pointer;box-shadow:0 3px 10px #00000038;display:inline-flex;align-items:center;justify-content:center;transition:transform .15s ease,background .15s ease,box-shadow .15s ease}.sd-autoid-inspector__fab:hover{background:var(--sd-primary-dark, #1C4AD9);transform:scale(1.08);box-shadow:0 5px 14px #00000047}.sd-autoid-inspector__fab mat-icon{font-size:18px;width:18px;height:18px}.sd-autoid-inspector__fab-dismiss{position:absolute;top:-6px;right:-6px;width:18px;height:18px;border-radius:50%;border:1px solid var(--sd-black200, #E6E6E6);background:#fff;color:var(--sd-black400, #757575);cursor:pointer;display:inline-flex;align-items:center;justify-content:center;padding:0;opacity:0;transform:scale(.7);pointer-events:none;transition:opacity .12s ease,transform .12s ease,color .12s ease,background .12s ease;box-shadow:0 1px 4px #00000026}.sd-autoid-inspector__fab-dismiss:hover{background:var(--sd-error-light, #FED5D0);color:var(--sd-error-dark, #BA200E);border-color:var(--sd-error, #F82C13)}.sd-autoid-inspector__fab-dismiss mat-icon{font-size:12px;width:12px;height:12px;line-height:12px}.sd-autoid-inspector__backdrop{position:fixed;inset:0;background:#00000052;z-index:100001;-webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px)}.sd-autoid-inspector__panel{position:fixed;right:20px;bottom:80px;width:min(860px,100vw - 40px);max-height:calc(100vh - 110px);background:#fff;border-radius:12px;box-shadow:0 16px 48px #00000038;display:flex;flex-direction:column;z-index:100002;overflow:hidden;border:1px solid var(--sd-black200, #E6E6E6)}.sd-autoid-inspector__header{display:flex;align-items:center;gap:8px;padding:8px 10px;border-bottom:1px solid var(--sd-black200, #E6E6E6);background:var(--sd-black100, #F2F2F2);flex-shrink:0}.sd-autoid-inspector__segments{display:inline-flex;border:1px solid var(--sd-black200, #E6E6E6);border-radius:8px;background:#fff;overflow:hidden}.sd-autoid-inspector__segments button{border:none;background:transparent;padding:5px 12px;cursor:pointer;font-size:12px;font-weight:500;color:var(--sd-black400, #757575);display:inline-flex;align-items:center;gap:6px;border-right:1px solid var(--sd-black200, #E6E6E6);transition:background .12s ease,color .12s ease}.sd-autoid-inspector__segments button:last-child{border-right:none}.sd-autoid-inspector__segments button:hover:not(.is-active){background:var(--sd-black100, #F2F2F2);color:var(--sd-black500, #212121)}.sd-autoid-inspector__segments button.is-active{background:var(--sd-primary, #2A66F4);color:#fff}.sd-autoid-inspector__badge{background:var(--sd-black200, #E6E6E6);color:var(--sd-black500, #212121);border-radius:10px;padding:0 7px;font-size:11px;font-weight:600;line-height:16px}.is-active .sd-autoid-inspector__badge{background:#ffffff40;color:#fff}.sd-autoid-inspector__badge.is-warn{background:var(--sd-error, #F82C13);color:#fff}.sd-autoid-inspector__actions{display:inline-flex;gap:4px;margin-left:auto}.sd-autoid-inspector__icon-btn{border:none;background:transparent;cursor:pointer;padding:4px;border-radius:6px;color:var(--sd-black400, #757575);display:inline-flex;align-items:center;justify-content:center;transition:background .12s ease,color .12s ease}.sd-autoid-inspector__icon-btn:hover{background:var(--sd-black100, #F2F2F2);color:var(--sd-black500, #212121)}.sd-autoid-inspector__icon-btn.is-primary{color:var(--sd-primary, #2A66F4)}.sd-autoid-inspector__icon-btn.is-primary:hover{background:var(--sd-primary-light, #EAF1FF);color:var(--sd-primary-dark, #1C4AD9)}.sd-autoid-inspector__icon-btn mat-icon{font-size:18px;width:18px;height:18px}.sd-autoid-inspector__close-btn{border:none;cursor:pointer;padding:4px;border-radius:50%;width:28px;height:28px;background:transparent;color:var(--sd-black400, #757575);display:inline-flex;align-items:center;justify-content:center;transition:background .12s ease,color .12s ease}.sd-autoid-inspector__close-btn:hover{background:var(--sd-error-light, #FED5D0);color:var(--sd-error-dark, #BA200E)}.sd-autoid-inspector__close-btn mat-icon{font-size:18px;width:18px;height:18px}.sd-autoid-inspector__body{padding:14px;overflow:auto;flex:1;background:#fff}.sd-autoid-inspector__toast{position:absolute;top:56px;right:14px;background:var(--sd-success, #4CAF50);color:#fff;padding:6px 12px;border-radius:6px;font-size:12px;z-index:2;box-shadow:0 4px 12px #0000002e}.sd-autoid-inspector__audit-toolbar{display:flex;justify-content:flex-end;margin-bottom:12px}.sd-autoid-inspector__toggle{display:inline-flex;align-items:center;gap:8px;border:1px solid var(--sd-black200, #E6E6E6);background:#fff;border-radius:999px;padding:5px 12px 5px 10px;cursor:pointer;font-size:12px;font-weight:500;color:var(--sd-black400, #757575);transition:all .15s ease}.sd-autoid-inspector__toggle:hover{border-color:var(--sd-primary, #2A66F4);color:var(--sd-primary, #2A66F4)}.sd-autoid-inspector__toggle.is-on{border-color:var(--sd-primary, #2A66F4);color:var(--sd-primary, #2A66F4);background:var(--sd-primary-light, #EAF1FF)}.sd-autoid-inspector__toggle mat-icon{font-size:16px;width:16px;height:16px}.sd-autoid-inspector__toggle-state{font-size:10px;font-weight:700;padding:1px 7px;border-radius:999px;background:var(--sd-black200, #E6E6E6);color:var(--sd-black400, #757575)}.is-on .sd-autoid-inspector__toggle-state{background:var(--sd-primary, #2A66F4);color:#fff}.sd-autoid-inspector__summary{display:grid;grid-template-columns:repeat(3,1fr);gap:10px;margin-bottom:16px}.sd-autoid-inspector__stat{background:var(--sd-black100, #F2F2F2);border-radius:10px;padding:12px;text-align:center;border:1px solid transparent}.sd-autoid-inspector__stat.is-info{background:var(--sd-info-light, #E7E9FF);border-color:var(--sd-info, #2962FF)}.sd-autoid-inspector__stat.is-info .sd-autoid-inspector__stat-value{color:var(--sd-info, #2962FF)}.sd-autoid-inspector__stat.is-success{background:var(--sd-success-light, #DBEFDC);border-color:var(--sd-success, #4CAF50)}.sd-autoid-inspector__stat.is-success .sd-autoid-inspector__stat-value{color:var(--sd-success-dark, #39833C)}.sd-autoid-inspector__stat.is-warning{background:var(--sd-warning-light, #FFEACC);border-color:var(--sd-warning, #FF9600)}.sd-autoid-inspector__stat.is-warning .sd-autoid-inspector__stat-value{color:var(--sd-warning-dark, #BF7000)}.sd-autoid-inspector__stat.is-error{background:var(--sd-error-light, #FED5D0);border-color:var(--sd-error, #F82C13)}.sd-autoid-inspector__stat.is-error .sd-autoid-inspector__stat-value{color:var(--sd-error-dark, #BA200E)}.sd-autoid-inspector__stat-value{font-size:22px;font-weight:700;line-height:1;margin-bottom:4px}.sd-autoid-inspector__stat-label{font-size:11px;color:var(--sd-black400, #757575);text-transform:uppercase;letter-spacing:.4px;font-weight:600}.sd-autoid-inspector__section-title{display:flex;align-items:center;gap:6px;margin:14px 0 8px;font-size:13px;font-weight:600;color:var(--sd-black500, #212121)}.sd-autoid-inspector__section-title mat-icon{font-size:18px;width:18px;height:18px}.sd-autoid-inspector__section-title mat-icon.is-error{color:var(--sd-error, #F82C13)}.sd-autoid-inspector__section-title mat-icon.is-warning{color:var(--sd-warning, #FF9600)}.sd-autoid-inspector__section-title mat-icon.is-info{color:var(--sd-info, #2962FF)}.sd-autoid-inspector__success-card{display:flex;align-items:center;gap:12px;padding:14px 16px;background:var(--sd-success-light, #DBEFDC);border:1px solid var(--sd-success, #4CAF50);border-radius:10px;color:var(--sd-success-dark, #39833C)}.sd-autoid-inspector__success-card mat-icon{font-size:28px;width:28px;height:28px;color:var(--sd-success, #4CAF50)}.sd-autoid-inspector__success-card strong{display:block;font-size:13px;margin-bottom:2px}.sd-autoid-inspector__success-card small{font-size:11px;opacity:.85}.sd-autoid-inspector__table-wrap{border:1px solid var(--sd-black200, #E6E6E6);border-radius:8px;overflow:auto;max-height:60vh;background:#fff}.sd-autoid-inspector__table{width:100%;border-collapse:separate;border-spacing:0;font-size:12px}.sd-autoid-inspector__table th,.sd-autoid-inspector__table td{padding:8px 10px;text-align:left;vertical-align:middle;border-bottom:1px solid var(--sd-black200, #E6E6E6)}.sd-autoid-inspector__table thead th{position:sticky;top:0;z-index:1;background:var(--sd-black100, #F2F2F2);font-weight:600;color:var(--sd-black500, #212121);text-transform:none;font-size:11px;letter-spacing:.3px;border-bottom:none;box-shadow:inset 0 -1px 0 var(--sd-black200, #E6E6E6),0 2px 4px #0000000a;white-space:nowrap}.sd-autoid-inspector__table thead th.is-num{text-align:right;width:50px}.sd-autoid-inspector__table tbody tr{transition:background .1s ease}.sd-autoid-inspector__table tbody tr:hover{background:var(--sd-primary-light, #EAF1FF)}.sd-autoid-inspector__table tbody tr:last-child td{border-bottom:none}.sd-autoid-inspector__table tbody tr.is-error{background:var(--sd-error-light, #FED5D0)}.sd-autoid-inspector__table tbody tr.is-error:hover{background:var(--sd-error-light, #FED5D0);filter:brightness(.98)}.sd-autoid-inspector__table tbody tr.is-warning{background:var(--sd-warning-light, #FFEACC)}.sd-autoid-inspector__table tbody tr.is-warning:hover{background:var(--sd-warning-light, #FFEACC);filter:brightness(.98)}.sd-autoid-inspector__table td.is-num{text-align:right;color:var(--sd-black400, #757575);font-variant-numeric:tabular-nums}.sd-autoid-inspector__table code{font-family:JetBrains Mono,Fira Code,Consolas,monospace;font-size:11px;background:var(--sd-black100, #F2F2F2);padding:2px 6px;border-radius:4px;color:var(--sd-primary-dark, #1C4AD9);border:1px solid var(--sd-black200, #E6E6E6)}.sd-autoid-inspector__autoid-cell{display:inline-flex;align-items:center;gap:6px}.sd-autoid-inspector__tag-chip{display:inline-block;font-family:JetBrains Mono,Fira Code,Consolas,monospace;font-size:11px;background:var(--sd-info-light, #E7E9FF);color:var(--sd-info, #2962FF);border:1px solid var(--sd-info, #2962FF);padding:1px 8px;border-radius:999px;font-weight:500}.sd-autoid-inspector__value{max-width:220px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--sd-black400, #757575);font-style:italic}.sd-autoid-inspector__state-cell{display:flex;flex-wrap:wrap;gap:4px;align-items:center;min-width:0}.sd-autoid-inspector__state-chip{display:inline-block;font-family:JetBrains Mono,Fira Code,Consolas,monospace;font-size:10px;background:var(--sd-black100, #F2F2F2);color:var(--sd-black400, #757575);border:1px solid var(--sd-black200, #E6E6E6);padding:1px 6px;border-radius:999px;font-weight:500;white-space:nowrap}.sd-autoid-inspector__state-chip.is-error{background:var(--sd-error-light, #FED5D0);color:var(--sd-error-dark, #BA200E);border-color:var(--sd-error, #F82C13)}.sd-autoid-inspector__state-chip.is-warning{background:var(--sd-warning-light, #FFEACC);color:var(--sd-warning-dark, #BF7000);border-color:var(--sd-warning, #FF9600)}.sd-autoid-inspector__state-chip.is-info{background:var(--sd-info-light, #E7E9FF);color:var(--sd-info, #2962FF);border-color:var(--sd-info, #2962FF)}.sd-autoid-inspector__empty{text-align:center;color:var(--sd-black400, #757575);padding:24px;font-style:italic}.sd-autoid-inspector__filter{display:flex;align-items:center;gap:6px;background:var(--sd-black100, #F2F2F2);border:1px solid var(--sd-black200, #E6E6E6);border-radius:8px;padding:6px 10px;margin-bottom:12px;transition:border-color .15s ease}.sd-autoid-inspector__filter:focus-within{border-color:var(--sd-primary, #2A66F4);background:#fff}.sd-autoid-inspector__filter input{flex:1;border:none;background:transparent;outline:none;font-size:13px;color:var(--sd-black500, #212121)}.sd-autoid-inspector__filter input::placeholder{color:var(--sd-black300, #BFBFBF)}.sd-autoid-inspector__filter>mat-icon{font-size:18px;width:18px;height:18px;color:var(--sd-black400, #757575)}.sd-autoid-inspector__export-grid{display:grid;grid-template-columns:repeat(5,minmax(0,1fr));gap:8px}.sd-autoid-inspector__export-grid button{border:1px solid var(--sd-black200, #E6E6E6);background:#fff;border-radius:10px;padding:12px 10px;cursor:pointer;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:6px;min-width:0;transition:border-color .15s ease,background .15s ease,transform .12s ease;text-align:center}.sd-autoid-inspector__export-grid button:hover{border-color:var(--sd-primary, #2A66F4);background:var(--sd-primary-light, #EAF1FF);transform:translateY(-1px)}.sd-autoid-inspector__export-grid button span{font-size:12px;font-weight:600;color:var(--sd-black500, #212121);line-height:1.25}.sd-autoid-inspector__export-grid button small{font-size:10px;color:var(--sd-black400, #757575);line-height:1.2}.sd-autoid-inspector__export-grid button mat-icon{font-size:22px;width:22px;height:22px;color:var(--sd-primary, #2A66F4)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i3.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i4.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "pipe", type: i1.KeyValuePipe, name: "keyvalue" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
707
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.15", ngImport: i0, type: SdAutoidInspector, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
708
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.15", type: SdAutoidInspector, isStandalone: true, selector: "sd-autoid-inspector", inputs: { enabled: { classPropertyName: "enabled", publicName: "enabled", isSignal: true, isRequired: false, transformFunction: null }, config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: false, transformFunction: null } }, host: { listeners: { "document:keydown.escape": "onEscape()" } }, ngImport: i0, template: "@if (enabled() && !dismissed()) {\n <div class=\"sd-autoid-inspector__fab-wrap\">\n <button\n type=\"button\"\n class=\"sd-autoid-inspector__fab\"\n data-autoid=\"sd-autoid-inspector-fab\"\n [attr.data-opened]=\"dataOpened()\"\n [matTooltip]=\"open() ? '\u0110\u00F3ng AutoId Inspector' : 'M\u1EDF AutoId Inspector'\"\n matTooltipPosition=\"left\"\n (click)=\"togglePanel()\">\n <mat-icon>{{ open() ? 'close' : 'tag' }}</mat-icon>\n </button>\n <button\n type=\"button\"\n class=\"sd-autoid-inspector__fab-dismiss\"\n matTooltip=\"\u1EA8n t\u1EA1m \u2014 reload trang \u0111\u1EC3 hi\u1EC7n l\u1EA1i\"\n matTooltipPosition=\"left\"\n aria-label=\"\u1EA8n t\u1EA1m FAB\"\n (click)=\"dismissFab($event)\">\n <mat-icon>close</mat-icon>\n </button>\n </div>\n\n}\n\n@if (enabled() && open()) {\n <div class=\"sd-autoid-inspector__backdrop\" (click)=\"closePanel()\"></div>\n <section class=\"sd-autoid-inspector__panel\"\n role=\"dialog\"\n aria-label=\"AutoId Inspector\"\n data-autoid=\"sd-autoid-inspector-panel\"\n [attr.data-segment]=\"dataSegment()\"\n [attr.data-highlight-on]=\"dataHighlightOn()\"\n [attr.data-element-count]=\"dataElementCount()\"\n [attr.data-missing-count]=\"dataMissingCount()\"\n [attr.data-duplicate-count]=\"dataDuplicateCount()\">\n <header class=\"sd-autoid-inspector__header\">\n <div class=\"sd-autoid-inspector__segments\">\n <button\n type=\"button\"\n [class.is-active]=\"segment() === 'audit'\"\n (click)=\"setSegment('audit')\">\n Audit\n @if (audit(); as a) {\n <span class=\"sd-autoid-inspector__badge\" [class.is-warn]=\"a.missingCount + a.duplicateCount > 0\">\n {{ a.missingCount + a.duplicateCount }}\n </span>\n }\n </button>\n <button\n type=\"button\"\n [class.is-active]=\"segment() === 'elements'\"\n (click)=\"setSegment('elements')\">\n Elements\n <span class=\"sd-autoid-inspector__badge\">{{ elements().length }}</span>\n </button>\n <button\n type=\"button\"\n [class.is-active]=\"segment() === 'export'\"\n (click)=\"setSegment('export')\">\n Export\n </button>\n </div>\n <div class=\"sd-autoid-inspector__actions\">\n <button\n type=\"button\"\n class=\"sd-autoid-inspector__icon-btn\"\n matTooltip=\"Qu\u00E9t l\u1EA1i\"\n (click)=\"refresh()\">\n <mat-icon>refresh</mat-icon>\n </button>\n <button\n type=\"button\"\n class=\"sd-autoid-inspector__close-btn\"\n matTooltip=\"\u0110\u00F3ng\"\n aria-label=\"\u0110\u00F3ng panel\"\n (click)=\"closePanel()\">\n <mat-icon>close</mat-icon>\n </button>\n </div>\n </header>\n\n @if (copyOk()) {\n <div class=\"sd-autoid-inspector__toast\">\u0110\u00E3 copy \u2713</div>\n }\n\n <div class=\"sd-autoid-inspector__body\">\n @switch (segment()) {\n @case ('audit') {\n <ng-container *ngTemplateOutlet=\"auditTpl\"></ng-container>\n }\n @case ('elements') {\n <ng-container *ngTemplateOutlet=\"elementsTpl\"></ng-container>\n }\n @case ('export') {\n <ng-container *ngTemplateOutlet=\"exportTpl\"></ng-container>\n }\n }\n </div>\n </section>\n\n <ng-template #auditTpl>\n @if (audit(); as a) {\n <div class=\"sd-autoid-inspector__audit-toolbar\">\n <button\n type=\"button\"\n class=\"sd-autoid-inspector__toggle\"\n [class.is-on]=\"highlightOn()\"\n (click)=\"toggleHighlight()\">\n <mat-icon>{{ highlightOn() ? 'visibility' : 'visibility_off' }}</mat-icon>\n <span>Highlight DOM</span>\n <span class=\"sd-autoid-inspector__toggle-state\">{{ highlightOn() ? 'ON' : 'OFF' }}</span>\n </button>\n </div>\n <div class=\"sd-autoid-inspector__summary\">\n <div class=\"sd-autoid-inspector__stat is-info\">\n <div class=\"sd-autoid-inspector__stat-value\">{{ a.total }}</div>\n <div class=\"sd-autoid-inspector__stat-label\">T\u1ED5ng autoid</div>\n </div>\n <div class=\"sd-autoid-inspector__stat\" [class.is-error]=\"a.duplicateCount > 0\" [class.is-success]=\"a.duplicateCount === 0\">\n <div class=\"sd-autoid-inspector__stat-value\">{{ a.duplicateCount }}</div>\n <div class=\"sd-autoid-inspector__stat-label\">Tr\u00F9ng</div>\n </div>\n <div class=\"sd-autoid-inspector__stat\" [class.is-warning]=\"a.missingCount > 0\" [class.is-success]=\"a.missingCount === 0\">\n <div class=\"sd-autoid-inspector__stat-value\">{{ a.missingCount }}</div>\n <div class=\"sd-autoid-inspector__stat-label\">Thi\u1EBFu</div>\n </div>\n </div>\n\n @if (a.duplicateCount > 0) {\n <h4 class=\"sd-autoid-inspector__section-title\">\n <mat-icon class=\"is-error\">error_outline</mat-icon>\n Autoid b\u1ECB tr\u00F9ng\n </h4>\n <div class=\"sd-autoid-inspector__table-wrap\">\n <table class=\"sd-autoid-inspector__table\">\n <thead>\n <tr><th>Autoid</th><th>S\u1ED1 l\u1EA7n</th></tr>\n </thead>\n <tbody>\n @for (entry of a.duplicates | keyvalue; track entry.key) {\n <tr class=\"is-error\">\n <td><code>{{ entry.key }}</code></td>\n <td>{{ entry.value }}</td>\n </tr>\n }\n </tbody>\n </table>\n </div>\n }\n\n @if (a.missingCount > 0) {\n <h4 class=\"sd-autoid-inspector__section-title\">\n <mat-icon class=\"is-warning\">warning_amber</mat-icon>\n Element thi\u1EBFu autoid\n </h4>\n <div class=\"sd-autoid-inspector__table-wrap\">\n <table class=\"sd-autoid-inspector__table\">\n <thead>\n <tr><th>Tag</th><th>Name hint</th><th>Selector</th></tr>\n </thead>\n <tbody>\n @for (m of a.missing; track $index) {\n <tr class=\"is-warning\">\n <td><code>{{ m.tag }}</code></td>\n <td>{{ m.nameHint }}</td>\n <td><code>{{ m.selector }}</code></td>\n </tr>\n }\n </tbody>\n </table>\n </div>\n }\n\n @if (a.duplicateCount === 0 && a.missingCount === 0) {\n <div class=\"sd-autoid-inspector__success-card\">\n <mat-icon>check_circle</mat-icon>\n <div>\n <strong>Kh\u00F4ng c\u00F3 element thi\u1EBFu ho\u1EB7c tr\u00F9ng autoid.</strong>\n <small>Trang \u0111\u00E3 \u0111\u1EA1t chu\u1EA9n convention autoid.</small>\n </div>\n </div>\n }\n }\n </ng-template>\n\n <ng-template #elementsTpl>\n <div class=\"sd-autoid-inspector__filter\">\n <mat-icon>search</mat-icon>\n <input\n type=\"text\"\n placeholder=\"L\u1ECDc theo autoid / name / tag\"\n [ngModel]=\"filter()\"\n (ngModelChange)=\"filter.set($event)\"/>\n @if (filter()) {\n <button\n type=\"button\"\n class=\"sd-autoid-inspector__icon-btn\"\n matTooltip=\"Xo\u00E1 filter\"\n (click)=\"filter.set('')\">\n <mat-icon>close</mat-icon>\n </button>\n }\n </div>\n\n <!-- Top-level elements (not inside any sd-table) -->\n <h4 class=\"sd-autoid-inspector__section-title\">\n Top-level elements\n <span class=\"sd-autoid-inspector__badge\">{{ topLevelElements().length }}</span>\n </h4>\n <div class=\"sd-autoid-inspector__table-wrap\">\n <table class=\"sd-autoid-inspector__table\">\n <thead>\n <tr>\n <th class=\"is-num\">STT</th>\n <th>Name</th>\n <th>Autoid</th>\n <th>Tag</th>\n <th>State</th>\n <th>Value</th>\n </tr>\n </thead>\n <tbody>\n @for (el of topLevelElements(); track el.autoid + $index) {\n <tr [class.is-error]=\"el.duplicate\">\n <td class=\"is-num\">{{ el.stt }}</td>\n <td>{{ el.name || '\u2014' }}</td>\n <td>\n <div class=\"sd-autoid-inspector__autoid-cell\">\n <code>{{ el.autoid }}</code>\n <button\n type=\"button\"\n class=\"sd-autoid-inspector__icon-btn is-primary\"\n matTooltip=\"Copy xpath\"\n (click)=\"copyXpath(el.autoid)\">\n <mat-icon>content_copy</mat-icon>\n </button>\n </div>\n </td>\n <td><span class=\"sd-autoid-inspector__tag-chip\">{{ el.tag }}</span></td>\n <td class=\"sd-autoid-inspector__state-cell\">\n @if (el.state.disabled !== undefined) {\n <span class=\"sd-autoid-inspector__state-chip\"\n [class.is-error]=\"el.state.disabled === 'true'\">\n disabled={{ el.state.disabled }}\n </span>\n }\n @if (el.state.loading !== undefined) {\n <span class=\"sd-autoid-inspector__state-chip\"\n [class.is-warning]=\"el.state.loading === 'true'\">\n loading={{ el.state.loading }}\n </span>\n }\n @if (el.state.empty !== undefined) {\n <span class=\"sd-autoid-inspector__state-chip\"\n [class.is-info]=\"el.state.empty === 'true'\">\n empty={{ el.state.empty }}\n </span>\n }\n @if (el.state.invalid !== undefined) {\n <span class=\"sd-autoid-inspector__state-chip\"\n [class.is-error]=\"el.state.invalid === 'true'\">\n invalid={{ el.state.invalid }}\n </span>\n }\n @if (el.state.opened !== undefined) {\n <span class=\"sd-autoid-inspector__state-chip\"\n [class.is-info]=\"el.state.opened === 'true'\">\n opened={{ el.state.opened }}\n </span>\n }\n @if (el.state.count !== undefined) {\n <span class=\"sd-autoid-inspector__state-chip is-info\">\n count={{ el.state.count }}\n </span>\n }\n @if (el.state.required !== undefined) {\n <span class=\"sd-autoid-inspector__state-chip\"\n [class.is-warning]=\"el.state.required === 'true'\">\n required={{ el.state.required }}\n </span>\n }\n @if (el.state.maxlength !== undefined) {\n <span class=\"sd-autoid-inspector__state-chip is-info\">\n maxlength={{ el.state.maxlength }}\n </span>\n }\n @if (el.state.minlength !== undefined) {\n <span class=\"sd-autoid-inspector__state-chip is-info\">\n minlength={{ el.state.minlength }}\n </span>\n }\n @if (el.state.pattern !== undefined) {\n <span class=\"sd-autoid-inspector__state-chip is-info\">\n pattern={{ el.state.pattern }}\n </span>\n }\n @if (el.state.errorMessage !== undefined) {\n <span class=\"sd-autoid-inspector__state-chip is-error\">\n error: {{ el.state.errorMessage }}\n </span>\n }\n </td>\n <td class=\"sd-autoid-inspector__value\" [matTooltip]=\"el.state.dataValue || el.text || ''\">\n {{ el.state.dataValue || el.text || '\u2014' }}\n </td>\n </tr>\n } @empty {\n <tr><td colspan=\"6\" class=\"sd-autoid-inspector__empty\">Kh\u00F4ng c\u00F3 k\u1EBFt qu\u1EA3.</td></tr>\n }\n </tbody>\n </table>\n </div>\n\n <!-- One section per sd-table group -->\n @for (group of tableGroups(); track group.scope) {\n <h4 class=\"sd-autoid-inspector__section-title\">\n <mat-icon class=\"is-info\">table_chart</mat-icon>\n Inside <code>{{ group.scope }}</code>\n <span class=\"sd-autoid-inspector__badge\">{{ group.items.length }}</span>\n </h4>\n <div class=\"sd-autoid-inspector__table-wrap\">\n <table class=\"sd-autoid-inspector__table\">\n <thead>\n <tr>\n <th class=\"is-num\">STT</th>\n <th>Name</th>\n <th>Autoid</th>\n <th>Tag</th>\n <th>State</th>\n <th>Value</th>\n </tr>\n </thead>\n <tbody>\n @for (el of group.items; track el.autoid + $index) {\n <tr [class.is-error]=\"el.duplicate\">\n <td class=\"is-num\">{{ el.stt }}</td>\n <td>{{ el.name || '\u2014' }}</td>\n <td>\n <div class=\"sd-autoid-inspector__autoid-cell\">\n <code>{{ el.autoid }}</code>\n <button\n type=\"button\"\n class=\"sd-autoid-inspector__icon-btn is-primary\"\n matTooltip=\"Copy xpath\"\n (click)=\"copyXpath(el.autoid)\">\n <mat-icon>content_copy</mat-icon>\n </button>\n </div>\n </td>\n <td><span class=\"sd-autoid-inspector__tag-chip\">{{ el.tag }}</span></td>\n <td class=\"sd-autoid-inspector__state-cell\">\n @if (el.state.disabled !== undefined) {\n <span class=\"sd-autoid-inspector__state-chip\"\n [class.is-error]=\"el.state.disabled === 'true'\">\n disabled={{ el.state.disabled }}\n </span>\n }\n @if (el.state.loading !== undefined) {\n <span class=\"sd-autoid-inspector__state-chip\"\n [class.is-warning]=\"el.state.loading === 'true'\">\n loading={{ el.state.loading }}\n </span>\n }\n @if (el.state.empty !== undefined) {\n <span class=\"sd-autoid-inspector__state-chip\"\n [class.is-info]=\"el.state.empty === 'true'\">\n empty={{ el.state.empty }}\n </span>\n }\n @if (el.state.invalid !== undefined) {\n <span class=\"sd-autoid-inspector__state-chip\"\n [class.is-error]=\"el.state.invalid === 'true'\">\n invalid={{ el.state.invalid }}\n </span>\n }\n @if (el.state.opened !== undefined) {\n <span class=\"sd-autoid-inspector__state-chip\"\n [class.is-info]=\"el.state.opened === 'true'\">\n opened={{ el.state.opened }}\n </span>\n }\n @if (el.state.count !== undefined) {\n <span class=\"sd-autoid-inspector__state-chip is-info\">\n count={{ el.state.count }}\n </span>\n }\n @if (el.state.required !== undefined) {\n <span class=\"sd-autoid-inspector__state-chip\"\n [class.is-warning]=\"el.state.required === 'true'\">\n required={{ el.state.required }}\n </span>\n }\n @if (el.state.maxlength !== undefined) {\n <span class=\"sd-autoid-inspector__state-chip is-info\">\n maxlength={{ el.state.maxlength }}\n </span>\n }\n @if (el.state.minlength !== undefined) {\n <span class=\"sd-autoid-inspector__state-chip is-info\">\n minlength={{ el.state.minlength }}\n </span>\n }\n @if (el.state.pattern !== undefined) {\n <span class=\"sd-autoid-inspector__state-chip is-info\">\n pattern={{ el.state.pattern }}\n </span>\n }\n @if (el.state.errorMessage !== undefined) {\n <span class=\"sd-autoid-inspector__state-chip is-error\">\n error: {{ el.state.errorMessage }}\n </span>\n }\n </td>\n <td class=\"sd-autoid-inspector__value\" [matTooltip]=\"el.state.dataValue || el.text || ''\">\n {{ el.state.dataValue || el.text || '\u2014' }}\n </td>\n </tr>\n }\n </tbody>\n </table>\n </div>\n }\n </ng-template>\n\n <ng-template #exportTpl>\n <div class=\"sd-autoid-inspector__export-grid\">\n <button type=\"button\" matTooltip=\"Copy JSON v\u00E0o clipboard\" (click)=\"copyJson()\">\n <mat-icon>content_copy</mat-icon>\n <span>Copy JSON</span>\n <small>clipboard</small>\n </button>\n <button type=\"button\" matTooltip=\"T\u1EA3i file JSON\" (click)=\"exportJson()\">\n <mat-icon>download</mat-icon>\n <span>JSON</span>\n <small>.json</small>\n </button>\n <button type=\"button\" matTooltip=\"T\u1EA3i file CSV\" (click)=\"exportCsv()\">\n <mat-icon>table_view</mat-icon>\n <span>CSV</span>\n <small>.csv</small>\n </button>\n <button type=\"button\" matTooltip=\"T\u1EA3i MD POM skeleton \u2014 cho AI vi\u1EBFt auto-test\" (click)=\"exportMdPom()\">\n <mat-icon>code</mat-icon>\n <span>MD POM</span>\n <small>AI test</small>\n </button>\n <button type=\"button\" matTooltip=\"T\u1EA3i MD reference table \u2014 group theo tag sd-*\" (click)=\"exportMdTable()\">\n <mat-icon>view_list</mat-icon>\n <span>MD Table</span>\n <small>reference</small>\n </button>\n </div>\n </ng-template>\n}\n", styles: [":host{position:fixed;inset:auto 0 0 auto;z-index:100000;font-family:system-ui,-apple-system,Segoe UI,Roboto,sans-serif;font-size:13px;color:var(--sd-black500, #212121)}.sd-autoid-inspector__fab-wrap{position:fixed;right:16px;bottom:16px;z-index:100000}.sd-autoid-inspector__fab-wrap:hover .sd-autoid-inspector__fab-dismiss{opacity:1;transform:scale(1);pointer-events:auto}.sd-autoid-inspector__fab{width:36px;height:36px;border-radius:50%;border:none;background:var(--sd-primary, #2A66F4);color:#fff;cursor:pointer;box-shadow:0 3px 10px #00000038;display:inline-flex;align-items:center;justify-content:center;transition:transform .15s ease,background .15s ease,box-shadow .15s ease}.sd-autoid-inspector__fab:hover{background:var(--sd-primary-dark, #1C4AD9);transform:scale(1.08);box-shadow:0 5px 14px #00000047}.sd-autoid-inspector__fab mat-icon{font-size:18px;width:18px;height:18px}.sd-autoid-inspector__fab-dismiss{position:absolute;top:-6px;right:-6px;width:18px;height:18px;border-radius:50%;border:1px solid var(--sd-black200, #E6E6E6);background:#fff;color:var(--sd-black400, #757575);cursor:pointer;display:inline-flex;align-items:center;justify-content:center;padding:0;opacity:0;transform:scale(.7);pointer-events:none;transition:opacity .12s ease,transform .12s ease,color .12s ease,background .12s ease;box-shadow:0 1px 4px #00000026}.sd-autoid-inspector__fab-dismiss:hover{background:var(--sd-error-light, #FED5D0);color:var(--sd-error-dark, #BA200E);border-color:var(--sd-error, #F82C13)}.sd-autoid-inspector__fab-dismiss mat-icon{font-size:12px;width:12px;height:12px;line-height:12px}.sd-autoid-inspector__backdrop{position:fixed;inset:0;background:#00000052;z-index:100001;-webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px)}.sd-autoid-inspector__panel{position:fixed;right:20px;bottom:80px;width:min(860px,100vw - 40px);max-height:calc(100vh - 110px);background:#fff;border-radius:12px;box-shadow:0 16px 48px #00000038;display:flex;flex-direction:column;z-index:100002;overflow:hidden;border:1px solid var(--sd-black200, #E6E6E6)}.sd-autoid-inspector__header{display:flex;align-items:center;gap:8px;padding:8px 10px;border-bottom:1px solid var(--sd-black200, #E6E6E6);background:var(--sd-black100, #F2F2F2);flex-shrink:0}.sd-autoid-inspector__segments{display:inline-flex;border:1px solid var(--sd-black200, #E6E6E6);border-radius:8px;background:#fff;overflow:hidden}.sd-autoid-inspector__segments button{border:none;background:transparent;padding:5px 12px;cursor:pointer;font-size:12px;font-weight:500;color:var(--sd-black400, #757575);display:inline-flex;align-items:center;gap:6px;border-right:1px solid var(--sd-black200, #E6E6E6);transition:background .12s ease,color .12s ease}.sd-autoid-inspector__segments button:last-child{border-right:none}.sd-autoid-inspector__segments button:hover:not(.is-active){background:var(--sd-black100, #F2F2F2);color:var(--sd-black500, #212121)}.sd-autoid-inspector__segments button.is-active{background:var(--sd-primary, #2A66F4);color:#fff}.sd-autoid-inspector__badge{background:var(--sd-black200, #E6E6E6);color:var(--sd-black500, #212121);border-radius:10px;padding:0 7px;font-size:11px;font-weight:600;line-height:16px}.is-active .sd-autoid-inspector__badge{background:#ffffff40;color:#fff}.sd-autoid-inspector__badge.is-warn{background:var(--sd-error, #F82C13);color:#fff}.sd-autoid-inspector__actions{display:inline-flex;gap:4px;margin-left:auto}.sd-autoid-inspector__icon-btn{border:none;background:transparent;cursor:pointer;padding:4px;border-radius:6px;color:var(--sd-black400, #757575);display:inline-flex;align-items:center;justify-content:center;transition:background .12s ease,color .12s ease}.sd-autoid-inspector__icon-btn:hover{background:var(--sd-black100, #F2F2F2);color:var(--sd-black500, #212121)}.sd-autoid-inspector__icon-btn.is-primary{color:var(--sd-primary, #2A66F4)}.sd-autoid-inspector__icon-btn.is-primary:hover{background:var(--sd-primary-light, #EAF1FF);color:var(--sd-primary-dark, #1C4AD9)}.sd-autoid-inspector__icon-btn mat-icon{font-size:18px;width:18px;height:18px}.sd-autoid-inspector__close-btn{border:none;cursor:pointer;padding:4px;border-radius:50%;width:28px;height:28px;background:transparent;color:var(--sd-black400, #757575);display:inline-flex;align-items:center;justify-content:center;transition:background .12s ease,color .12s ease}.sd-autoid-inspector__close-btn:hover{background:var(--sd-error-light, #FED5D0);color:var(--sd-error-dark, #BA200E)}.sd-autoid-inspector__close-btn mat-icon{font-size:18px;width:18px;height:18px}.sd-autoid-inspector__body{padding:14px;overflow:auto;flex:1;background:#fff}.sd-autoid-inspector__toast{position:absolute;top:56px;right:14px;background:var(--sd-success, #4CAF50);color:#fff;padding:6px 12px;border-radius:6px;font-size:12px;z-index:2;box-shadow:0 4px 12px #0000002e}.sd-autoid-inspector__audit-toolbar{display:flex;justify-content:flex-end;margin-bottom:12px}.sd-autoid-inspector__toggle{display:inline-flex;align-items:center;gap:8px;border:1px solid var(--sd-black200, #E6E6E6);background:#fff;border-radius:999px;padding:5px 12px 5px 10px;cursor:pointer;font-size:12px;font-weight:500;color:var(--sd-black400, #757575);transition:all .15s ease}.sd-autoid-inspector__toggle:hover{border-color:var(--sd-primary, #2A66F4);color:var(--sd-primary, #2A66F4)}.sd-autoid-inspector__toggle.is-on{border-color:var(--sd-primary, #2A66F4);color:var(--sd-primary, #2A66F4);background:var(--sd-primary-light, #EAF1FF)}.sd-autoid-inspector__toggle mat-icon{font-size:16px;width:16px;height:16px}.sd-autoid-inspector__toggle-state{font-size:10px;font-weight:700;padding:1px 7px;border-radius:999px;background:var(--sd-black200, #E6E6E6);color:var(--sd-black400, #757575)}.is-on .sd-autoid-inspector__toggle-state{background:var(--sd-primary, #2A66F4);color:#fff}.sd-autoid-inspector__summary{display:grid;grid-template-columns:repeat(3,1fr);gap:10px;margin-bottom:16px}.sd-autoid-inspector__stat{background:var(--sd-black100, #F2F2F2);border-radius:10px;padding:12px;text-align:center;border:1px solid transparent}.sd-autoid-inspector__stat.is-info{background:var(--sd-info-light, #E7E9FF);border-color:var(--sd-info, #2962FF)}.sd-autoid-inspector__stat.is-info .sd-autoid-inspector__stat-value{color:var(--sd-info, #2962FF)}.sd-autoid-inspector__stat.is-success{background:var(--sd-success-light, #DBEFDC);border-color:var(--sd-success, #4CAF50)}.sd-autoid-inspector__stat.is-success .sd-autoid-inspector__stat-value{color:var(--sd-success-dark, #39833C)}.sd-autoid-inspector__stat.is-warning{background:var(--sd-warning-light, #FFEACC);border-color:var(--sd-warning, #FF9600)}.sd-autoid-inspector__stat.is-warning .sd-autoid-inspector__stat-value{color:var(--sd-warning-dark, #BF7000)}.sd-autoid-inspector__stat.is-error{background:var(--sd-error-light, #FED5D0);border-color:var(--sd-error, #F82C13)}.sd-autoid-inspector__stat.is-error .sd-autoid-inspector__stat-value{color:var(--sd-error-dark, #BA200E)}.sd-autoid-inspector__stat-value{font-size:22px;font-weight:700;line-height:1;margin-bottom:4px}.sd-autoid-inspector__stat-label{font-size:11px;color:var(--sd-black400, #757575);text-transform:uppercase;letter-spacing:.4px;font-weight:600}.sd-autoid-inspector__section-title{display:flex;align-items:center;gap:6px;margin:14px 0 8px;font-size:13px;font-weight:600;color:var(--sd-black500, #212121)}.sd-autoid-inspector__section-title mat-icon{font-size:18px;width:18px;height:18px}.sd-autoid-inspector__section-title mat-icon.is-error{color:var(--sd-error, #F82C13)}.sd-autoid-inspector__section-title mat-icon.is-warning{color:var(--sd-warning, #FF9600)}.sd-autoid-inspector__section-title mat-icon.is-info{color:var(--sd-info, #2962FF)}.sd-autoid-inspector__success-card{display:flex;align-items:center;gap:12px;padding:14px 16px;background:var(--sd-success-light, #DBEFDC);border:1px solid var(--sd-success, #4CAF50);border-radius:10px;color:var(--sd-success-dark, #39833C)}.sd-autoid-inspector__success-card mat-icon{font-size:28px;width:28px;height:28px;color:var(--sd-success, #4CAF50)}.sd-autoid-inspector__success-card strong{display:block;font-size:13px;margin-bottom:2px}.sd-autoid-inspector__success-card small{font-size:11px;opacity:.85}.sd-autoid-inspector__table-wrap{border:1px solid var(--sd-black200, #E6E6E6);border-radius:8px;overflow:auto;max-height:60vh;background:#fff}.sd-autoid-inspector__table{width:100%;border-collapse:separate;border-spacing:0;font-size:12px}.sd-autoid-inspector__table th,.sd-autoid-inspector__table td{padding:8px 10px;text-align:left;vertical-align:middle;border-bottom:1px solid var(--sd-black200, #E6E6E6)}.sd-autoid-inspector__table thead th{position:sticky;top:0;z-index:1;background:var(--sd-black100, #F2F2F2);font-weight:600;color:var(--sd-black500, #212121);text-transform:none;font-size:11px;letter-spacing:.3px;border-bottom:none;box-shadow:inset 0 -1px 0 var(--sd-black200, #E6E6E6),0 2px 4px #0000000a;white-space:nowrap}.sd-autoid-inspector__table thead th.is-num{text-align:right;width:50px}.sd-autoid-inspector__table tbody tr{transition:background .1s ease}.sd-autoid-inspector__table tbody tr:hover{background:var(--sd-primary-light, #EAF1FF)}.sd-autoid-inspector__table tbody tr:last-child td{border-bottom:none}.sd-autoid-inspector__table tbody tr.is-error{background:var(--sd-error-light, #FED5D0)}.sd-autoid-inspector__table tbody tr.is-error:hover{background:var(--sd-error-light, #FED5D0);filter:brightness(.98)}.sd-autoid-inspector__table tbody tr.is-warning{background:var(--sd-warning-light, #FFEACC)}.sd-autoid-inspector__table tbody tr.is-warning:hover{background:var(--sd-warning-light, #FFEACC);filter:brightness(.98)}.sd-autoid-inspector__table td.is-num{text-align:right;color:var(--sd-black400, #757575);font-variant-numeric:tabular-nums}.sd-autoid-inspector__table code{font-family:JetBrains Mono,Fira Code,Consolas,monospace;font-size:11px;background:var(--sd-black100, #F2F2F2);padding:2px 6px;border-radius:4px;color:var(--sd-primary-dark, #1C4AD9);border:1px solid var(--sd-black200, #E6E6E6)}.sd-autoid-inspector__autoid-cell{display:inline-flex;align-items:center;gap:6px}.sd-autoid-inspector__tag-chip{display:inline-block;font-family:JetBrains Mono,Fira Code,Consolas,monospace;font-size:11px;background:var(--sd-info-light, #E7E9FF);color:var(--sd-info, #2962FF);border:1px solid var(--sd-info, #2962FF);padding:1px 8px;border-radius:999px;font-weight:500}.sd-autoid-inspector__value{max-width:220px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--sd-black400, #757575);font-style:italic}.sd-autoid-inspector__state-cell{display:flex;flex-wrap:wrap;gap:4px;align-items:center;min-width:0}.sd-autoid-inspector__state-chip{display:inline-block;font-family:JetBrains Mono,Fira Code,Consolas,monospace;font-size:10px;background:var(--sd-black100, #F2F2F2);color:var(--sd-black400, #757575);border:1px solid var(--sd-black200, #E6E6E6);padding:1px 6px;border-radius:999px;font-weight:500;white-space:nowrap}.sd-autoid-inspector__state-chip.is-error{background:var(--sd-error-light, #FED5D0);color:var(--sd-error-dark, #BA200E);border-color:var(--sd-error, #F82C13)}.sd-autoid-inspector__state-chip.is-warning{background:var(--sd-warning-light, #FFEACC);color:var(--sd-warning-dark, #BF7000);border-color:var(--sd-warning, #FF9600)}.sd-autoid-inspector__state-chip.is-info{background:var(--sd-info-light, #E7E9FF);color:var(--sd-info, #2962FF);border-color:var(--sd-info, #2962FF)}.sd-autoid-inspector__empty{text-align:center;color:var(--sd-black400, #757575);padding:24px;font-style:italic}.sd-autoid-inspector__filter{display:flex;align-items:center;gap:6px;background:var(--sd-black100, #F2F2F2);border:1px solid var(--sd-black200, #E6E6E6);border-radius:8px;padding:6px 10px;margin-bottom:12px;transition:border-color .15s ease}.sd-autoid-inspector__filter:focus-within{border-color:var(--sd-primary, #2A66F4);background:#fff}.sd-autoid-inspector__filter input{flex:1;border:none;background:transparent;outline:none;font-size:13px;color:var(--sd-black500, #212121)}.sd-autoid-inspector__filter input::placeholder{color:var(--sd-black300, #BFBFBF)}.sd-autoid-inspector__filter>mat-icon{font-size:18px;width:18px;height:18px;color:var(--sd-black400, #757575)}.sd-autoid-inspector__export-grid{display:grid;grid-template-columns:repeat(5,minmax(0,1fr));gap:8px}.sd-autoid-inspector__export-grid button{border:1px solid var(--sd-black200, #E6E6E6);background:#fff;border-radius:10px;padding:12px 10px;cursor:pointer;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:6px;min-width:0;transition:border-color .15s ease,background .15s ease,transform .12s ease;text-align:center}.sd-autoid-inspector__export-grid button:hover{border-color:var(--sd-primary, #2A66F4);background:var(--sd-primary-light, #EAF1FF);transform:translateY(-1px)}.sd-autoid-inspector__export-grid button span{font-size:12px;font-weight:600;color:var(--sd-black500, #212121);line-height:1.25}.sd-autoid-inspector__export-grid button small{font-size:10px;color:var(--sd-black400, #757575);line-height:1.2}.sd-autoid-inspector__export-grid button mat-icon{font-size:22px;width:22px;height:22px;color:var(--sd-primary, #2A66F4)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i3.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i4.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "pipe", type: i1.KeyValuePipe, name: "keyvalue" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
709
709
|
}
|
|
710
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
710
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.15", ngImport: i0, type: SdAutoidInspector, decorators: [{
|
|
711
711
|
type: Component,
|
|
712
712
|
args: [{ selector: 'sd-autoid-inspector', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [CommonModule, FormsModule, MatIconModule, MatTooltipModule], template: "@if (enabled() && !dismissed()) {\n <div class=\"sd-autoid-inspector__fab-wrap\">\n <button\n type=\"button\"\n class=\"sd-autoid-inspector__fab\"\n data-autoid=\"sd-autoid-inspector-fab\"\n [attr.data-opened]=\"dataOpened()\"\n [matTooltip]=\"open() ? '\u0110\u00F3ng AutoId Inspector' : 'M\u1EDF AutoId Inspector'\"\n matTooltipPosition=\"left\"\n (click)=\"togglePanel()\">\n <mat-icon>{{ open() ? 'close' : 'tag' }}</mat-icon>\n </button>\n <button\n type=\"button\"\n class=\"sd-autoid-inspector__fab-dismiss\"\n matTooltip=\"\u1EA8n t\u1EA1m \u2014 reload trang \u0111\u1EC3 hi\u1EC7n l\u1EA1i\"\n matTooltipPosition=\"left\"\n aria-label=\"\u1EA8n t\u1EA1m FAB\"\n (click)=\"dismissFab($event)\">\n <mat-icon>close</mat-icon>\n </button>\n </div>\n\n}\n\n@if (enabled() && open()) {\n <div class=\"sd-autoid-inspector__backdrop\" (click)=\"closePanel()\"></div>\n <section class=\"sd-autoid-inspector__panel\"\n role=\"dialog\"\n aria-label=\"AutoId Inspector\"\n data-autoid=\"sd-autoid-inspector-panel\"\n [attr.data-segment]=\"dataSegment()\"\n [attr.data-highlight-on]=\"dataHighlightOn()\"\n [attr.data-element-count]=\"dataElementCount()\"\n [attr.data-missing-count]=\"dataMissingCount()\"\n [attr.data-duplicate-count]=\"dataDuplicateCount()\">\n <header class=\"sd-autoid-inspector__header\">\n <div class=\"sd-autoid-inspector__segments\">\n <button\n type=\"button\"\n [class.is-active]=\"segment() === 'audit'\"\n (click)=\"setSegment('audit')\">\n Audit\n @if (audit(); as a) {\n <span class=\"sd-autoid-inspector__badge\" [class.is-warn]=\"a.missingCount + a.duplicateCount > 0\">\n {{ a.missingCount + a.duplicateCount }}\n </span>\n }\n </button>\n <button\n type=\"button\"\n [class.is-active]=\"segment() === 'elements'\"\n (click)=\"setSegment('elements')\">\n Elements\n <span class=\"sd-autoid-inspector__badge\">{{ elements().length }}</span>\n </button>\n <button\n type=\"button\"\n [class.is-active]=\"segment() === 'export'\"\n (click)=\"setSegment('export')\">\n Export\n </button>\n </div>\n <div class=\"sd-autoid-inspector__actions\">\n <button\n type=\"button\"\n class=\"sd-autoid-inspector__icon-btn\"\n matTooltip=\"Qu\u00E9t l\u1EA1i\"\n (click)=\"refresh()\">\n <mat-icon>refresh</mat-icon>\n </button>\n <button\n type=\"button\"\n class=\"sd-autoid-inspector__close-btn\"\n matTooltip=\"\u0110\u00F3ng\"\n aria-label=\"\u0110\u00F3ng panel\"\n (click)=\"closePanel()\">\n <mat-icon>close</mat-icon>\n </button>\n </div>\n </header>\n\n @if (copyOk()) {\n <div class=\"sd-autoid-inspector__toast\">\u0110\u00E3 copy \u2713</div>\n }\n\n <div class=\"sd-autoid-inspector__body\">\n @switch (segment()) {\n @case ('audit') {\n <ng-container *ngTemplateOutlet=\"auditTpl\"></ng-container>\n }\n @case ('elements') {\n <ng-container *ngTemplateOutlet=\"elementsTpl\"></ng-container>\n }\n @case ('export') {\n <ng-container *ngTemplateOutlet=\"exportTpl\"></ng-container>\n }\n }\n </div>\n </section>\n\n <ng-template #auditTpl>\n @if (audit(); as a) {\n <div class=\"sd-autoid-inspector__audit-toolbar\">\n <button\n type=\"button\"\n class=\"sd-autoid-inspector__toggle\"\n [class.is-on]=\"highlightOn()\"\n (click)=\"toggleHighlight()\">\n <mat-icon>{{ highlightOn() ? 'visibility' : 'visibility_off' }}</mat-icon>\n <span>Highlight DOM</span>\n <span class=\"sd-autoid-inspector__toggle-state\">{{ highlightOn() ? 'ON' : 'OFF' }}</span>\n </button>\n </div>\n <div class=\"sd-autoid-inspector__summary\">\n <div class=\"sd-autoid-inspector__stat is-info\">\n <div class=\"sd-autoid-inspector__stat-value\">{{ a.total }}</div>\n <div class=\"sd-autoid-inspector__stat-label\">T\u1ED5ng autoid</div>\n </div>\n <div class=\"sd-autoid-inspector__stat\" [class.is-error]=\"a.duplicateCount > 0\" [class.is-success]=\"a.duplicateCount === 0\">\n <div class=\"sd-autoid-inspector__stat-value\">{{ a.duplicateCount }}</div>\n <div class=\"sd-autoid-inspector__stat-label\">Tr\u00F9ng</div>\n </div>\n <div class=\"sd-autoid-inspector__stat\" [class.is-warning]=\"a.missingCount > 0\" [class.is-success]=\"a.missingCount === 0\">\n <div class=\"sd-autoid-inspector__stat-value\">{{ a.missingCount }}</div>\n <div class=\"sd-autoid-inspector__stat-label\">Thi\u1EBFu</div>\n </div>\n </div>\n\n @if (a.duplicateCount > 0) {\n <h4 class=\"sd-autoid-inspector__section-title\">\n <mat-icon class=\"is-error\">error_outline</mat-icon>\n Autoid b\u1ECB tr\u00F9ng\n </h4>\n <div class=\"sd-autoid-inspector__table-wrap\">\n <table class=\"sd-autoid-inspector__table\">\n <thead>\n <tr><th>Autoid</th><th>S\u1ED1 l\u1EA7n</th></tr>\n </thead>\n <tbody>\n @for (entry of a.duplicates | keyvalue; track entry.key) {\n <tr class=\"is-error\">\n <td><code>{{ entry.key }}</code></td>\n <td>{{ entry.value }}</td>\n </tr>\n }\n </tbody>\n </table>\n </div>\n }\n\n @if (a.missingCount > 0) {\n <h4 class=\"sd-autoid-inspector__section-title\">\n <mat-icon class=\"is-warning\">warning_amber</mat-icon>\n Element thi\u1EBFu autoid\n </h4>\n <div class=\"sd-autoid-inspector__table-wrap\">\n <table class=\"sd-autoid-inspector__table\">\n <thead>\n <tr><th>Tag</th><th>Name hint</th><th>Selector</th></tr>\n </thead>\n <tbody>\n @for (m of a.missing; track $index) {\n <tr class=\"is-warning\">\n <td><code>{{ m.tag }}</code></td>\n <td>{{ m.nameHint }}</td>\n <td><code>{{ m.selector }}</code></td>\n </tr>\n }\n </tbody>\n </table>\n </div>\n }\n\n @if (a.duplicateCount === 0 && a.missingCount === 0) {\n <div class=\"sd-autoid-inspector__success-card\">\n <mat-icon>check_circle</mat-icon>\n <div>\n <strong>Kh\u00F4ng c\u00F3 element thi\u1EBFu ho\u1EB7c tr\u00F9ng autoid.</strong>\n <small>Trang \u0111\u00E3 \u0111\u1EA1t chu\u1EA9n convention autoid.</small>\n </div>\n </div>\n }\n }\n </ng-template>\n\n <ng-template #elementsTpl>\n <div class=\"sd-autoid-inspector__filter\">\n <mat-icon>search</mat-icon>\n <input\n type=\"text\"\n placeholder=\"L\u1ECDc theo autoid / name / tag\"\n [ngModel]=\"filter()\"\n (ngModelChange)=\"filter.set($event)\"/>\n @if (filter()) {\n <button\n type=\"button\"\n class=\"sd-autoid-inspector__icon-btn\"\n matTooltip=\"Xo\u00E1 filter\"\n (click)=\"filter.set('')\">\n <mat-icon>close</mat-icon>\n </button>\n }\n </div>\n\n <!-- Top-level elements (not inside any sd-table) -->\n <h4 class=\"sd-autoid-inspector__section-title\">\n Top-level elements\n <span class=\"sd-autoid-inspector__badge\">{{ topLevelElements().length }}</span>\n </h4>\n <div class=\"sd-autoid-inspector__table-wrap\">\n <table class=\"sd-autoid-inspector__table\">\n <thead>\n <tr>\n <th class=\"is-num\">STT</th>\n <th>Name</th>\n <th>Autoid</th>\n <th>Tag</th>\n <th>State</th>\n <th>Value</th>\n </tr>\n </thead>\n <tbody>\n @for (el of topLevelElements(); track el.autoid + $index) {\n <tr [class.is-error]=\"el.duplicate\">\n <td class=\"is-num\">{{ el.stt }}</td>\n <td>{{ el.name || '\u2014' }}</td>\n <td>\n <div class=\"sd-autoid-inspector__autoid-cell\">\n <code>{{ el.autoid }}</code>\n <button\n type=\"button\"\n class=\"sd-autoid-inspector__icon-btn is-primary\"\n matTooltip=\"Copy xpath\"\n (click)=\"copyXpath(el.autoid)\">\n <mat-icon>content_copy</mat-icon>\n </button>\n </div>\n </td>\n <td><span class=\"sd-autoid-inspector__tag-chip\">{{ el.tag }}</span></td>\n <td class=\"sd-autoid-inspector__state-cell\">\n @if (el.state.disabled !== undefined) {\n <span class=\"sd-autoid-inspector__state-chip\"\n [class.is-error]=\"el.state.disabled === 'true'\">\n disabled={{ el.state.disabled }}\n </span>\n }\n @if (el.state.loading !== undefined) {\n <span class=\"sd-autoid-inspector__state-chip\"\n [class.is-warning]=\"el.state.loading === 'true'\">\n loading={{ el.state.loading }}\n </span>\n }\n @if (el.state.empty !== undefined) {\n <span class=\"sd-autoid-inspector__state-chip\"\n [class.is-info]=\"el.state.empty === 'true'\">\n empty={{ el.state.empty }}\n </span>\n }\n @if (el.state.invalid !== undefined) {\n <span class=\"sd-autoid-inspector__state-chip\"\n [class.is-error]=\"el.state.invalid === 'true'\">\n invalid={{ el.state.invalid }}\n </span>\n }\n @if (el.state.opened !== undefined) {\n <span class=\"sd-autoid-inspector__state-chip\"\n [class.is-info]=\"el.state.opened === 'true'\">\n opened={{ el.state.opened }}\n </span>\n }\n @if (el.state.count !== undefined) {\n <span class=\"sd-autoid-inspector__state-chip is-info\">\n count={{ el.state.count }}\n </span>\n }\n @if (el.state.required !== undefined) {\n <span class=\"sd-autoid-inspector__state-chip\"\n [class.is-warning]=\"el.state.required === 'true'\">\n required={{ el.state.required }}\n </span>\n }\n @if (el.state.maxlength !== undefined) {\n <span class=\"sd-autoid-inspector__state-chip is-info\">\n maxlength={{ el.state.maxlength }}\n </span>\n }\n @if (el.state.minlength !== undefined) {\n <span class=\"sd-autoid-inspector__state-chip is-info\">\n minlength={{ el.state.minlength }}\n </span>\n }\n @if (el.state.pattern !== undefined) {\n <span class=\"sd-autoid-inspector__state-chip is-info\">\n pattern={{ el.state.pattern }}\n </span>\n }\n @if (el.state.errorMessage !== undefined) {\n <span class=\"sd-autoid-inspector__state-chip is-error\">\n error: {{ el.state.errorMessage }}\n </span>\n }\n </td>\n <td class=\"sd-autoid-inspector__value\" [matTooltip]=\"el.state.dataValue || el.text || ''\">\n {{ el.state.dataValue || el.text || '\u2014' }}\n </td>\n </tr>\n } @empty {\n <tr><td colspan=\"6\" class=\"sd-autoid-inspector__empty\">Kh\u00F4ng c\u00F3 k\u1EBFt qu\u1EA3.</td></tr>\n }\n </tbody>\n </table>\n </div>\n\n <!-- One section per sd-table group -->\n @for (group of tableGroups(); track group.scope) {\n <h4 class=\"sd-autoid-inspector__section-title\">\n <mat-icon class=\"is-info\">table_chart</mat-icon>\n Inside <code>{{ group.scope }}</code>\n <span class=\"sd-autoid-inspector__badge\">{{ group.items.length }}</span>\n </h4>\n <div class=\"sd-autoid-inspector__table-wrap\">\n <table class=\"sd-autoid-inspector__table\">\n <thead>\n <tr>\n <th class=\"is-num\">STT</th>\n <th>Name</th>\n <th>Autoid</th>\n <th>Tag</th>\n <th>State</th>\n <th>Value</th>\n </tr>\n </thead>\n <tbody>\n @for (el of group.items; track el.autoid + $index) {\n <tr [class.is-error]=\"el.duplicate\">\n <td class=\"is-num\">{{ el.stt }}</td>\n <td>{{ el.name || '\u2014' }}</td>\n <td>\n <div class=\"sd-autoid-inspector__autoid-cell\">\n <code>{{ el.autoid }}</code>\n <button\n type=\"button\"\n class=\"sd-autoid-inspector__icon-btn is-primary\"\n matTooltip=\"Copy xpath\"\n (click)=\"copyXpath(el.autoid)\">\n <mat-icon>content_copy</mat-icon>\n </button>\n </div>\n </td>\n <td><span class=\"sd-autoid-inspector__tag-chip\">{{ el.tag }}</span></td>\n <td class=\"sd-autoid-inspector__state-cell\">\n @if (el.state.disabled !== undefined) {\n <span class=\"sd-autoid-inspector__state-chip\"\n [class.is-error]=\"el.state.disabled === 'true'\">\n disabled={{ el.state.disabled }}\n </span>\n }\n @if (el.state.loading !== undefined) {\n <span class=\"sd-autoid-inspector__state-chip\"\n [class.is-warning]=\"el.state.loading === 'true'\">\n loading={{ el.state.loading }}\n </span>\n }\n @if (el.state.empty !== undefined) {\n <span class=\"sd-autoid-inspector__state-chip\"\n [class.is-info]=\"el.state.empty === 'true'\">\n empty={{ el.state.empty }}\n </span>\n }\n @if (el.state.invalid !== undefined) {\n <span class=\"sd-autoid-inspector__state-chip\"\n [class.is-error]=\"el.state.invalid === 'true'\">\n invalid={{ el.state.invalid }}\n </span>\n }\n @if (el.state.opened !== undefined) {\n <span class=\"sd-autoid-inspector__state-chip\"\n [class.is-info]=\"el.state.opened === 'true'\">\n opened={{ el.state.opened }}\n </span>\n }\n @if (el.state.count !== undefined) {\n <span class=\"sd-autoid-inspector__state-chip is-info\">\n count={{ el.state.count }}\n </span>\n }\n @if (el.state.required !== undefined) {\n <span class=\"sd-autoid-inspector__state-chip\"\n [class.is-warning]=\"el.state.required === 'true'\">\n required={{ el.state.required }}\n </span>\n }\n @if (el.state.maxlength !== undefined) {\n <span class=\"sd-autoid-inspector__state-chip is-info\">\n maxlength={{ el.state.maxlength }}\n </span>\n }\n @if (el.state.minlength !== undefined) {\n <span class=\"sd-autoid-inspector__state-chip is-info\">\n minlength={{ el.state.minlength }}\n </span>\n }\n @if (el.state.pattern !== undefined) {\n <span class=\"sd-autoid-inspector__state-chip is-info\">\n pattern={{ el.state.pattern }}\n </span>\n }\n @if (el.state.errorMessage !== undefined) {\n <span class=\"sd-autoid-inspector__state-chip is-error\">\n error: {{ el.state.errorMessage }}\n </span>\n }\n </td>\n <td class=\"sd-autoid-inspector__value\" [matTooltip]=\"el.state.dataValue || el.text || ''\">\n {{ el.state.dataValue || el.text || '\u2014' }}\n </td>\n </tr>\n }\n </tbody>\n </table>\n </div>\n }\n </ng-template>\n\n <ng-template #exportTpl>\n <div class=\"sd-autoid-inspector__export-grid\">\n <button type=\"button\" matTooltip=\"Copy JSON v\u00E0o clipboard\" (click)=\"copyJson()\">\n <mat-icon>content_copy</mat-icon>\n <span>Copy JSON</span>\n <small>clipboard</small>\n </button>\n <button type=\"button\" matTooltip=\"T\u1EA3i file JSON\" (click)=\"exportJson()\">\n <mat-icon>download</mat-icon>\n <span>JSON</span>\n <small>.json</small>\n </button>\n <button type=\"button\" matTooltip=\"T\u1EA3i file CSV\" (click)=\"exportCsv()\">\n <mat-icon>table_view</mat-icon>\n <span>CSV</span>\n <small>.csv</small>\n </button>\n <button type=\"button\" matTooltip=\"T\u1EA3i MD POM skeleton \u2014 cho AI vi\u1EBFt auto-test\" (click)=\"exportMdPom()\">\n <mat-icon>code</mat-icon>\n <span>MD POM</span>\n <small>AI test</small>\n </button>\n <button type=\"button\" matTooltip=\"T\u1EA3i MD reference table \u2014 group theo tag sd-*\" (click)=\"exportMdTable()\">\n <mat-icon>view_list</mat-icon>\n <span>MD Table</span>\n <small>reference</small>\n </button>\n </div>\n </ng-template>\n}\n", styles: [":host{position:fixed;inset:auto 0 0 auto;z-index:100000;font-family:system-ui,-apple-system,Segoe UI,Roboto,sans-serif;font-size:13px;color:var(--sd-black500, #212121)}.sd-autoid-inspector__fab-wrap{position:fixed;right:16px;bottom:16px;z-index:100000}.sd-autoid-inspector__fab-wrap:hover .sd-autoid-inspector__fab-dismiss{opacity:1;transform:scale(1);pointer-events:auto}.sd-autoid-inspector__fab{width:36px;height:36px;border-radius:50%;border:none;background:var(--sd-primary, #2A66F4);color:#fff;cursor:pointer;box-shadow:0 3px 10px #00000038;display:inline-flex;align-items:center;justify-content:center;transition:transform .15s ease,background .15s ease,box-shadow .15s ease}.sd-autoid-inspector__fab:hover{background:var(--sd-primary-dark, #1C4AD9);transform:scale(1.08);box-shadow:0 5px 14px #00000047}.sd-autoid-inspector__fab mat-icon{font-size:18px;width:18px;height:18px}.sd-autoid-inspector__fab-dismiss{position:absolute;top:-6px;right:-6px;width:18px;height:18px;border-radius:50%;border:1px solid var(--sd-black200, #E6E6E6);background:#fff;color:var(--sd-black400, #757575);cursor:pointer;display:inline-flex;align-items:center;justify-content:center;padding:0;opacity:0;transform:scale(.7);pointer-events:none;transition:opacity .12s ease,transform .12s ease,color .12s ease,background .12s ease;box-shadow:0 1px 4px #00000026}.sd-autoid-inspector__fab-dismiss:hover{background:var(--sd-error-light, #FED5D0);color:var(--sd-error-dark, #BA200E);border-color:var(--sd-error, #F82C13)}.sd-autoid-inspector__fab-dismiss mat-icon{font-size:12px;width:12px;height:12px;line-height:12px}.sd-autoid-inspector__backdrop{position:fixed;inset:0;background:#00000052;z-index:100001;-webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px)}.sd-autoid-inspector__panel{position:fixed;right:20px;bottom:80px;width:min(860px,100vw - 40px);max-height:calc(100vh - 110px);background:#fff;border-radius:12px;box-shadow:0 16px 48px #00000038;display:flex;flex-direction:column;z-index:100002;overflow:hidden;border:1px solid var(--sd-black200, #E6E6E6)}.sd-autoid-inspector__header{display:flex;align-items:center;gap:8px;padding:8px 10px;border-bottom:1px solid var(--sd-black200, #E6E6E6);background:var(--sd-black100, #F2F2F2);flex-shrink:0}.sd-autoid-inspector__segments{display:inline-flex;border:1px solid var(--sd-black200, #E6E6E6);border-radius:8px;background:#fff;overflow:hidden}.sd-autoid-inspector__segments button{border:none;background:transparent;padding:5px 12px;cursor:pointer;font-size:12px;font-weight:500;color:var(--sd-black400, #757575);display:inline-flex;align-items:center;gap:6px;border-right:1px solid var(--sd-black200, #E6E6E6);transition:background .12s ease,color .12s ease}.sd-autoid-inspector__segments button:last-child{border-right:none}.sd-autoid-inspector__segments button:hover:not(.is-active){background:var(--sd-black100, #F2F2F2);color:var(--sd-black500, #212121)}.sd-autoid-inspector__segments button.is-active{background:var(--sd-primary, #2A66F4);color:#fff}.sd-autoid-inspector__badge{background:var(--sd-black200, #E6E6E6);color:var(--sd-black500, #212121);border-radius:10px;padding:0 7px;font-size:11px;font-weight:600;line-height:16px}.is-active .sd-autoid-inspector__badge{background:#ffffff40;color:#fff}.sd-autoid-inspector__badge.is-warn{background:var(--sd-error, #F82C13);color:#fff}.sd-autoid-inspector__actions{display:inline-flex;gap:4px;margin-left:auto}.sd-autoid-inspector__icon-btn{border:none;background:transparent;cursor:pointer;padding:4px;border-radius:6px;color:var(--sd-black400, #757575);display:inline-flex;align-items:center;justify-content:center;transition:background .12s ease,color .12s ease}.sd-autoid-inspector__icon-btn:hover{background:var(--sd-black100, #F2F2F2);color:var(--sd-black500, #212121)}.sd-autoid-inspector__icon-btn.is-primary{color:var(--sd-primary, #2A66F4)}.sd-autoid-inspector__icon-btn.is-primary:hover{background:var(--sd-primary-light, #EAF1FF);color:var(--sd-primary-dark, #1C4AD9)}.sd-autoid-inspector__icon-btn mat-icon{font-size:18px;width:18px;height:18px}.sd-autoid-inspector__close-btn{border:none;cursor:pointer;padding:4px;border-radius:50%;width:28px;height:28px;background:transparent;color:var(--sd-black400, #757575);display:inline-flex;align-items:center;justify-content:center;transition:background .12s ease,color .12s ease}.sd-autoid-inspector__close-btn:hover{background:var(--sd-error-light, #FED5D0);color:var(--sd-error-dark, #BA200E)}.sd-autoid-inspector__close-btn mat-icon{font-size:18px;width:18px;height:18px}.sd-autoid-inspector__body{padding:14px;overflow:auto;flex:1;background:#fff}.sd-autoid-inspector__toast{position:absolute;top:56px;right:14px;background:var(--sd-success, #4CAF50);color:#fff;padding:6px 12px;border-radius:6px;font-size:12px;z-index:2;box-shadow:0 4px 12px #0000002e}.sd-autoid-inspector__audit-toolbar{display:flex;justify-content:flex-end;margin-bottom:12px}.sd-autoid-inspector__toggle{display:inline-flex;align-items:center;gap:8px;border:1px solid var(--sd-black200, #E6E6E6);background:#fff;border-radius:999px;padding:5px 12px 5px 10px;cursor:pointer;font-size:12px;font-weight:500;color:var(--sd-black400, #757575);transition:all .15s ease}.sd-autoid-inspector__toggle:hover{border-color:var(--sd-primary, #2A66F4);color:var(--sd-primary, #2A66F4)}.sd-autoid-inspector__toggle.is-on{border-color:var(--sd-primary, #2A66F4);color:var(--sd-primary, #2A66F4);background:var(--sd-primary-light, #EAF1FF)}.sd-autoid-inspector__toggle mat-icon{font-size:16px;width:16px;height:16px}.sd-autoid-inspector__toggle-state{font-size:10px;font-weight:700;padding:1px 7px;border-radius:999px;background:var(--sd-black200, #E6E6E6);color:var(--sd-black400, #757575)}.is-on .sd-autoid-inspector__toggle-state{background:var(--sd-primary, #2A66F4);color:#fff}.sd-autoid-inspector__summary{display:grid;grid-template-columns:repeat(3,1fr);gap:10px;margin-bottom:16px}.sd-autoid-inspector__stat{background:var(--sd-black100, #F2F2F2);border-radius:10px;padding:12px;text-align:center;border:1px solid transparent}.sd-autoid-inspector__stat.is-info{background:var(--sd-info-light, #E7E9FF);border-color:var(--sd-info, #2962FF)}.sd-autoid-inspector__stat.is-info .sd-autoid-inspector__stat-value{color:var(--sd-info, #2962FF)}.sd-autoid-inspector__stat.is-success{background:var(--sd-success-light, #DBEFDC);border-color:var(--sd-success, #4CAF50)}.sd-autoid-inspector__stat.is-success .sd-autoid-inspector__stat-value{color:var(--sd-success-dark, #39833C)}.sd-autoid-inspector__stat.is-warning{background:var(--sd-warning-light, #FFEACC);border-color:var(--sd-warning, #FF9600)}.sd-autoid-inspector__stat.is-warning .sd-autoid-inspector__stat-value{color:var(--sd-warning-dark, #BF7000)}.sd-autoid-inspector__stat.is-error{background:var(--sd-error-light, #FED5D0);border-color:var(--sd-error, #F82C13)}.sd-autoid-inspector__stat.is-error .sd-autoid-inspector__stat-value{color:var(--sd-error-dark, #BA200E)}.sd-autoid-inspector__stat-value{font-size:22px;font-weight:700;line-height:1;margin-bottom:4px}.sd-autoid-inspector__stat-label{font-size:11px;color:var(--sd-black400, #757575);text-transform:uppercase;letter-spacing:.4px;font-weight:600}.sd-autoid-inspector__section-title{display:flex;align-items:center;gap:6px;margin:14px 0 8px;font-size:13px;font-weight:600;color:var(--sd-black500, #212121)}.sd-autoid-inspector__section-title mat-icon{font-size:18px;width:18px;height:18px}.sd-autoid-inspector__section-title mat-icon.is-error{color:var(--sd-error, #F82C13)}.sd-autoid-inspector__section-title mat-icon.is-warning{color:var(--sd-warning, #FF9600)}.sd-autoid-inspector__section-title mat-icon.is-info{color:var(--sd-info, #2962FF)}.sd-autoid-inspector__success-card{display:flex;align-items:center;gap:12px;padding:14px 16px;background:var(--sd-success-light, #DBEFDC);border:1px solid var(--sd-success, #4CAF50);border-radius:10px;color:var(--sd-success-dark, #39833C)}.sd-autoid-inspector__success-card mat-icon{font-size:28px;width:28px;height:28px;color:var(--sd-success, #4CAF50)}.sd-autoid-inspector__success-card strong{display:block;font-size:13px;margin-bottom:2px}.sd-autoid-inspector__success-card small{font-size:11px;opacity:.85}.sd-autoid-inspector__table-wrap{border:1px solid var(--sd-black200, #E6E6E6);border-radius:8px;overflow:auto;max-height:60vh;background:#fff}.sd-autoid-inspector__table{width:100%;border-collapse:separate;border-spacing:0;font-size:12px}.sd-autoid-inspector__table th,.sd-autoid-inspector__table td{padding:8px 10px;text-align:left;vertical-align:middle;border-bottom:1px solid var(--sd-black200, #E6E6E6)}.sd-autoid-inspector__table thead th{position:sticky;top:0;z-index:1;background:var(--sd-black100, #F2F2F2);font-weight:600;color:var(--sd-black500, #212121);text-transform:none;font-size:11px;letter-spacing:.3px;border-bottom:none;box-shadow:inset 0 -1px 0 var(--sd-black200, #E6E6E6),0 2px 4px #0000000a;white-space:nowrap}.sd-autoid-inspector__table thead th.is-num{text-align:right;width:50px}.sd-autoid-inspector__table tbody tr{transition:background .1s ease}.sd-autoid-inspector__table tbody tr:hover{background:var(--sd-primary-light, #EAF1FF)}.sd-autoid-inspector__table tbody tr:last-child td{border-bottom:none}.sd-autoid-inspector__table tbody tr.is-error{background:var(--sd-error-light, #FED5D0)}.sd-autoid-inspector__table tbody tr.is-error:hover{background:var(--sd-error-light, #FED5D0);filter:brightness(.98)}.sd-autoid-inspector__table tbody tr.is-warning{background:var(--sd-warning-light, #FFEACC)}.sd-autoid-inspector__table tbody tr.is-warning:hover{background:var(--sd-warning-light, #FFEACC);filter:brightness(.98)}.sd-autoid-inspector__table td.is-num{text-align:right;color:var(--sd-black400, #757575);font-variant-numeric:tabular-nums}.sd-autoid-inspector__table code{font-family:JetBrains Mono,Fira Code,Consolas,monospace;font-size:11px;background:var(--sd-black100, #F2F2F2);padding:2px 6px;border-radius:4px;color:var(--sd-primary-dark, #1C4AD9);border:1px solid var(--sd-black200, #E6E6E6)}.sd-autoid-inspector__autoid-cell{display:inline-flex;align-items:center;gap:6px}.sd-autoid-inspector__tag-chip{display:inline-block;font-family:JetBrains Mono,Fira Code,Consolas,monospace;font-size:11px;background:var(--sd-info-light, #E7E9FF);color:var(--sd-info, #2962FF);border:1px solid var(--sd-info, #2962FF);padding:1px 8px;border-radius:999px;font-weight:500}.sd-autoid-inspector__value{max-width:220px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--sd-black400, #757575);font-style:italic}.sd-autoid-inspector__state-cell{display:flex;flex-wrap:wrap;gap:4px;align-items:center;min-width:0}.sd-autoid-inspector__state-chip{display:inline-block;font-family:JetBrains Mono,Fira Code,Consolas,monospace;font-size:10px;background:var(--sd-black100, #F2F2F2);color:var(--sd-black400, #757575);border:1px solid var(--sd-black200, #E6E6E6);padding:1px 6px;border-radius:999px;font-weight:500;white-space:nowrap}.sd-autoid-inspector__state-chip.is-error{background:var(--sd-error-light, #FED5D0);color:var(--sd-error-dark, #BA200E);border-color:var(--sd-error, #F82C13)}.sd-autoid-inspector__state-chip.is-warning{background:var(--sd-warning-light, #FFEACC);color:var(--sd-warning-dark, #BF7000);border-color:var(--sd-warning, #FF9600)}.sd-autoid-inspector__state-chip.is-info{background:var(--sd-info-light, #E7E9FF);color:var(--sd-info, #2962FF);border-color:var(--sd-info, #2962FF)}.sd-autoid-inspector__empty{text-align:center;color:var(--sd-black400, #757575);padding:24px;font-style:italic}.sd-autoid-inspector__filter{display:flex;align-items:center;gap:6px;background:var(--sd-black100, #F2F2F2);border:1px solid var(--sd-black200, #E6E6E6);border-radius:8px;padding:6px 10px;margin-bottom:12px;transition:border-color .15s ease}.sd-autoid-inspector__filter:focus-within{border-color:var(--sd-primary, #2A66F4);background:#fff}.sd-autoid-inspector__filter input{flex:1;border:none;background:transparent;outline:none;font-size:13px;color:var(--sd-black500, #212121)}.sd-autoid-inspector__filter input::placeholder{color:var(--sd-black300, #BFBFBF)}.sd-autoid-inspector__filter>mat-icon{font-size:18px;width:18px;height:18px;color:var(--sd-black400, #757575)}.sd-autoid-inspector__export-grid{display:grid;grid-template-columns:repeat(5,minmax(0,1fr));gap:8px}.sd-autoid-inspector__export-grid button{border:1px solid var(--sd-black200, #E6E6E6);background:#fff;border-radius:10px;padding:12px 10px;cursor:pointer;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:6px;min-width:0;transition:border-color .15s ease,background .15s ease,transform .12s ease;text-align:center}.sd-autoid-inspector__export-grid button:hover{border-color:var(--sd-primary, #2A66F4);background:var(--sd-primary-light, #EAF1FF);transform:translateY(-1px)}.sd-autoid-inspector__export-grid button span{font-size:12px;font-weight:600;color:var(--sd-black500, #212121);line-height:1.25}.sd-autoid-inspector__export-grid button small{font-size:10px;color:var(--sd-black400, #757575);line-height:1.2}.sd-autoid-inspector__export-grid button mat-icon{font-size:22px;width:22px;height:22px;color:var(--sd-primary, #2A66F4)}\n"] }]
|
|
713
713
|
}], propDecorators: { enabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "enabled", required: false }] }], config: [{ type: i0.Input, args: [{ isSignal: true, alias: "config", required: false }] }], onEscape: [{
|