@sd-angular/core 19.0.0-beta.93 → 19.0.0-beta.94
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/components/document-builder/src/components/header-footer-builder/header-footer-builder.component.d.ts +4 -1
- package/components/document-builder/src/document-builder.model.d.ts +2 -0
- package/components/editor/src/models/editor.model.d.ts +2 -0
- package/components/editor/src/plugins/image-upload/utils/validate.utils.d.ts +2 -1
- package/components/splitter/src/splitter.component.d.ts +15 -2
- package/components/table/src/components/selector-action/selector-action.component.d.ts +1 -0
- package/components/table/src/table.component.d.ts +1 -0
- package/configurations/src/sd-core.configuration.d.ts +1 -0
- package/fesm2022/sd-angular-core-components-code-editor.mjs +3 -2
- package/fesm2022/sd-angular-core-components-code-editor.mjs.map +1 -1
- package/fesm2022/sd-angular-core-components-document-builder.mjs +29 -8
- package/fesm2022/sd-angular-core-components-document-builder.mjs.map +1 -1
- package/fesm2022/sd-angular-core-components-editor.mjs +31 -16
- package/fesm2022/sd-angular-core-components-editor.mjs.map +1 -1
- package/fesm2022/sd-angular-core-components-form-generic.mjs +68 -61
- package/fesm2022/sd-angular-core-components-form-generic.mjs.map +1 -1
- package/fesm2022/sd-angular-core-components-history.mjs +3 -2
- package/fesm2022/sd-angular-core-components-history.mjs.map +1 -1
- package/fesm2022/sd-angular-core-components-import-excel.mjs +25 -23
- package/fesm2022/sd-angular-core-components-import-excel.mjs.map +1 -1
- package/fesm2022/sd-angular-core-components-preview.mjs +6 -4
- package/fesm2022/sd-angular-core-components-preview.mjs.map +1 -1
- package/fesm2022/sd-angular-core-components-splitter.mjs +188 -18
- package/fesm2022/sd-angular-core-components-splitter.mjs.map +1 -1
- package/fesm2022/sd-angular-core-components-tab-router.mjs +3 -1
- package/fesm2022/sd-angular-core-components-tab-router.mjs.map +1 -1
- package/fesm2022/sd-angular-core-components-table.mjs +30 -23
- package/fesm2022/sd-angular-core-components-table.mjs.map +1 -1
- package/fesm2022/sd-angular-core-components-upload-file.mjs +24 -21
- package/fesm2022/sd-angular-core-components-upload-file.mjs.map +1 -1
- package/fesm2022/sd-angular-core-configurations.mjs.map +1 -1
- package/fesm2022/sd-angular-core-directives.mjs +6 -2
- package/fesm2022/sd-angular-core-directives.mjs.map +1 -1
- package/fesm2022/sd-angular-core-forms-autocomplete.mjs +3 -1
- package/fesm2022/sd-angular-core-forms-autocomplete.mjs.map +1 -1
- package/fesm2022/sd-angular-core-forms-chip-calendar.mjs +5 -3
- package/fesm2022/sd-angular-core-forms-chip-calendar.mjs.map +1 -1
- package/fesm2022/sd-angular-core-forms-chip.mjs +5 -3
- package/fesm2022/sd-angular-core-forms-chip.mjs.map +1 -1
- package/fesm2022/sd-angular-core-forms-date-range.mjs +8 -5
- package/fesm2022/sd-angular-core-forms-date-range.mjs.map +1 -1
- package/fesm2022/sd-angular-core-forms-date.mjs +7 -5
- package/fesm2022/sd-angular-core-forms-date.mjs.map +1 -1
- package/fesm2022/sd-angular-core-forms-datetime.mjs +10 -8
- package/fesm2022/sd-angular-core-forms-datetime.mjs.map +1 -1
- package/fesm2022/sd-angular-core-forms-input-number.mjs +5 -3
- package/fesm2022/sd-angular-core-forms-input-number.mjs.map +1 -1
- package/fesm2022/sd-angular-core-forms-input.mjs +13 -6
- package/fesm2022/sd-angular-core-forms-input.mjs.map +1 -1
- package/fesm2022/sd-angular-core-forms-radio.mjs +3 -2
- package/fesm2022/sd-angular-core-forms-radio.mjs.map +1 -1
- package/fesm2022/sd-angular-core-forms-select.mjs +5 -3
- package/fesm2022/sd-angular-core-forms-select.mjs.map +1 -1
- package/fesm2022/sd-angular-core-forms-textarea.mjs +8 -5
- package/fesm2022/sd-angular-core-forms-textarea.mjs.map +1 -1
- package/fesm2022/sd-angular-core-handlers.mjs +7 -6
- package/fesm2022/sd-angular-core-handlers.mjs.map +1 -1
- package/fesm2022/sd-angular-core-i18n.mjs +790 -0
- package/fesm2022/sd-angular-core-i18n.mjs.map +1 -0
- package/fesm2022/sd-angular-core-interceptors.mjs +10 -6
- package/fesm2022/sd-angular-core-interceptors.mjs.map +1 -1
- package/fesm2022/sd-angular-core-modules-authom.mjs +1 -0
- package/fesm2022/sd-angular-core-modules-authom.mjs.map +1 -1
- package/fesm2022/sd-angular-core-modules-keycloak.mjs +1 -0
- package/fesm2022/sd-angular-core-modules-keycloak.mjs.map +1 -1
- package/fesm2022/sd-angular-core-modules-layout.mjs +47 -46
- package/fesm2022/sd-angular-core-modules-layout.mjs.map +1 -1
- package/fesm2022/sd-angular-core-services-confirm.mjs +15 -13
- package/fesm2022/sd-angular-core-services-confirm.mjs.map +1 -1
- package/fesm2022/sd-angular-core-services-docx.mjs +7 -7
- package/fesm2022/sd-angular-core-services-docx.mjs.map +1 -1
- package/fesm2022/sd-angular-core-services-excel.mjs +5 -3
- package/fesm2022/sd-angular-core-services-excel.mjs.map +1 -1
- package/fesm2022/sd-angular-core-utilities-extensions.mjs +18 -11
- package/fesm2022/sd-angular-core-utilities-extensions.mjs.map +1 -1
- package/fesm2022/sd-angular-core-utilities-models.mjs +30 -28
- package/fesm2022/sd-angular-core-utilities-models.mjs.map +1 -1
- package/fesm2022/sd-angular-core.mjs +1 -0
- package/fesm2022/sd-angular-core.mjs.map +1 -1
- package/i18n/index.d.ts +5 -0
- package/i18n/src/en.d.ts +2 -0
- package/i18n/src/sd-i18n.messages.d.ts +2 -0
- package/i18n/src/sd-i18n.pipe.d.ts +9 -0
- package/i18n/src/sd-i18n.service.d.ts +12 -0
- package/i18n/src/sd-i18n.token.d.ts +1 -0
- package/i18n/src/sd-i18n.types.d.ts +5 -0
- package/i18n/src/vi.d.ts +312 -0
- package/package.json +53 -49
- package/public-api.d.ts +1 -0
- package/sd-angular-core-19.0.0-beta.94.tgz +0 -0
- package/services/confirm/src/lib/confirm.service.d.ts +1 -0
- package/sd-angular-core-19.0.0-beta.93.tgz +0 -0
|
@@ -0,0 +1,790 @@
|
|
|
1
|
+
import * as i0 from '@angular/core';
|
|
2
|
+
import { inject, signal, computed, Injectable, Pipe } from '@angular/core';
|
|
3
|
+
import { SD_CORE_CONFIGURATION } from '@sd-angular/core/configurations';
|
|
4
|
+
|
|
5
|
+
const SD_I18N_STORAGE_KEY = 'sd-core.language';
|
|
6
|
+
|
|
7
|
+
const SD_SUPPORTED_LANGUAGES = ['vi', 'en'];
|
|
8
|
+
|
|
9
|
+
const EN_MESSAGES = {
|
|
10
|
+
'core.common.cancel': 'Cancel',
|
|
11
|
+
'core.common.close': 'Close',
|
|
12
|
+
'core.common.reload': 'Reload page',
|
|
13
|
+
'core.test.greet': 'Hello {name}',
|
|
14
|
+
// ---- Validators (pattern.model.ts) ----
|
|
15
|
+
'core.validator.email.name': 'Email',
|
|
16
|
+
'core.validator.email.error': 'Invalid email',
|
|
17
|
+
'core.validator.phone.name': 'Phone',
|
|
18
|
+
'core.validator.phone.error': 'Invalid phone number',
|
|
19
|
+
'core.validator.phone-vn.name': 'VN phone',
|
|
20
|
+
'core.validator.phone-vn.error': 'Invalid phone number',
|
|
21
|
+
'core.validator.cccd.name': 'National ID',
|
|
22
|
+
'core.validator.cccd.error': 'Invalid national ID (12 digits)',
|
|
23
|
+
'core.validator.passport.name': 'Passport',
|
|
24
|
+
'core.validator.passport.error': 'Invalid passport (1 letter + 7 digits)',
|
|
25
|
+
'core.validator.id-vn.name': 'National ID / Passport',
|
|
26
|
+
'core.validator.id-vn.error': 'Invalid national ID or passport',
|
|
27
|
+
'core.validator.time.name': 'Time',
|
|
28
|
+
'core.validator.time.error': 'Invalid time (format HH:mm)',
|
|
29
|
+
// ---- Operators (operator.model.ts) ----
|
|
30
|
+
'core.operator.equal.display': 'Equal',
|
|
31
|
+
'core.operator.not-equal.display': 'Not equal',
|
|
32
|
+
'core.operator.greater-than.display': 'Greater than',
|
|
33
|
+
'core.operator.less-than.display': 'Less than',
|
|
34
|
+
'core.operator.greater-or-equal.display': 'Greater than or equal',
|
|
35
|
+
'core.operator.less-or-equal.display': 'Less than or equal',
|
|
36
|
+
'core.operator.contain.display': 'Contains',
|
|
37
|
+
'core.operator.not-contain.display': 'Does not contain',
|
|
38
|
+
'core.operator.start-with.display': 'Starts with',
|
|
39
|
+
'core.operator.end-with.display': 'Ends with',
|
|
40
|
+
'core.operator.in.display': 'In',
|
|
41
|
+
'core.operator.not-in.display': 'Not in',
|
|
42
|
+
'core.operator.null.display': 'Is empty',
|
|
43
|
+
'core.operator.not-null.display': 'Is not empty',
|
|
44
|
+
// ---- Utility errors (utility.extension.ts) ----
|
|
45
|
+
'core.utility.upload.invalid-format': '[{name}] Invalid file format. Please select again',
|
|
46
|
+
'core.utility.upload.invalid-size': '[{name}] Invalid file size. Please choose a different file',
|
|
47
|
+
// ---- Global error handler ----
|
|
48
|
+
'core.handler.global-error.update-title': 'A NEW SYSTEM UPDATE IS AVAILABLE',
|
|
49
|
+
'core.handler.global-error.update-body': 'The current version is outdated and could not load resources.\nPlease press OK to reload the page.',
|
|
50
|
+
// ---- Interceptor: no-internet ----
|
|
51
|
+
'core.interceptor.no-internet.offline': 'No network connection. Waiting for connection...',
|
|
52
|
+
'core.interceptor.no-internet.cors-error': 'Cannot connect to server (CORS or configuration error).',
|
|
53
|
+
'core.interceptor.no-internet.maintenance': 'Server is under maintenance. Please try again later.',
|
|
54
|
+
'core.interceptor.no-internet.restored': 'Connection restored.',
|
|
55
|
+
// ---- Service: excel ----
|
|
56
|
+
'core.excel.cannot-read-file': 'Could not read file content',
|
|
57
|
+
'core.excel.no-sheet': 'Excel file has no data sheet',
|
|
58
|
+
// ---- Service: docx ----
|
|
59
|
+
'core.docx.invalid-format': 'Invalid format. Please select a template in DOC or DOCX format',
|
|
60
|
+
'core.docx.size-exceeded': 'Template file size exceeds the supported limit. Please try again',
|
|
61
|
+
'core.docx.convert-error': 'An error occurred while converting the DOCX file',
|
|
62
|
+
// ---- Service: confirm ----
|
|
63
|
+
'core.confirm.title': 'Confirm',
|
|
64
|
+
'core.confirm.yes': 'OK',
|
|
65
|
+
'core.confirm.no': 'Cancel',
|
|
66
|
+
'core.confirm.yes-short': 'Yes',
|
|
67
|
+
'core.confirm.no-short': 'No',
|
|
68
|
+
// ---- Directive: hover-copy ----
|
|
69
|
+
'core.directive.hover-copy.tooltip': 'Copy',
|
|
70
|
+
// ---- Forms: input ----
|
|
71
|
+
'core.form.input.required': 'Please enter information',
|
|
72
|
+
'core.form.input.maxlength': 'Maximum characters: {max}',
|
|
73
|
+
'core.form.input.invalid-pattern': 'Invalid format',
|
|
74
|
+
'core.form.input.exceeded': 'Exceeded maximum characters',
|
|
75
|
+
// ---- Forms: autocomplete ----
|
|
76
|
+
'core.form.autocomplete.required': 'Please enter information',
|
|
77
|
+
// ---- Forms: chip ----
|
|
78
|
+
'core.form.chip.required': 'Please enter information',
|
|
79
|
+
'core.form.chip.minlength': 'Please enter at least {min} values',
|
|
80
|
+
'core.form.chip.maxlength': 'Please enter at most {max} values',
|
|
81
|
+
// ---- Forms: chip-calendar ----
|
|
82
|
+
'core.form.chip-calendar.required': 'Please enter information',
|
|
83
|
+
'core.form.chip-calendar.minlength': 'Please enter at least {min} values',
|
|
84
|
+
'core.form.chip-calendar.maxlength': 'Please enter at most {max} values',
|
|
85
|
+
// ---- Forms: date ----
|
|
86
|
+
'core.form.date.required': 'Please enter information',
|
|
87
|
+
'core.form.date.min-date': 'Minimum date: {date}',
|
|
88
|
+
'core.form.date.max-date': 'Maximum date: {date}',
|
|
89
|
+
'core.form.date.parse-error': 'Parse error: {text}',
|
|
90
|
+
'core.form.date.invalid-format': 'Invalid format',
|
|
91
|
+
// ---- Forms: date-range ----
|
|
92
|
+
'core.form.date-range.required': 'Please enter information',
|
|
93
|
+
'core.form.date-range.invalid-min': 'Start date is invalid (below limit)',
|
|
94
|
+
'core.form.date-range.invalid-max': 'End date is invalid (above limit)',
|
|
95
|
+
'core.form.date-range.from': 'From',
|
|
96
|
+
'core.form.date-range.to': 'to',
|
|
97
|
+
// ---- Forms: datetime ----
|
|
98
|
+
'core.form.datetime.required': 'Please enter information',
|
|
99
|
+
'core.form.datetime.min-date': 'Minimum date: {date}',
|
|
100
|
+
'core.form.datetime.max-date': 'Maximum date: {date}',
|
|
101
|
+
'core.form.datetime.invalid-format': 'Invalid format',
|
|
102
|
+
'core.form.datetime.now': 'Now',
|
|
103
|
+
'core.form.datetime.confirm': 'Confirm',
|
|
104
|
+
// ---- Forms: time-spinner ----
|
|
105
|
+
'core.form.time-spinner.hour': 'Hour',
|
|
106
|
+
'core.form.time-spinner.minute': 'Minute',
|
|
107
|
+
'core.form.time-spinner.second': 'Second',
|
|
108
|
+
'core.form.time-spinner.increase-hour': 'Increase hour',
|
|
109
|
+
'core.form.time-spinner.decrease-hour': 'Decrease hour',
|
|
110
|
+
'core.form.time-spinner.increase-minute': 'Increase minute',
|
|
111
|
+
'core.form.time-spinner.decrease-minute': 'Decrease minute',
|
|
112
|
+
'core.form.time-spinner.increase-second': 'Increase second',
|
|
113
|
+
'core.form.time-spinner.decrease-second': 'Decrease second',
|
|
114
|
+
// ---- Forms: input-number ----
|
|
115
|
+
'core.form.input-number.required': 'Please enter information',
|
|
116
|
+
'core.form.input-number.min': 'Value must not be less than {min}',
|
|
117
|
+
'core.form.input-number.max': 'Value must not be greater than {max}',
|
|
118
|
+
// ---- Forms: radio ----
|
|
119
|
+
'core.form.radio.required': 'Please enter information',
|
|
120
|
+
// ---- Forms: select ----
|
|
121
|
+
'core.form.select.required': 'Please enter information',
|
|
122
|
+
// ---- Forms: textarea ----
|
|
123
|
+
'core.form.textarea.required': 'Please enter information',
|
|
124
|
+
'core.form.textarea.maxlength': 'Maximum characters: {max}',
|
|
125
|
+
'core.form.textarea.invalid-pattern': 'Invalid format',
|
|
126
|
+
'core.form.textarea.exceeded': 'Exceeded maximum characters',
|
|
127
|
+
// ---- Component: editor ----
|
|
128
|
+
'core.component.editor.required': 'Please enter content',
|
|
129
|
+
'core.component.editor.maxlength': 'Maximum characters: {max}',
|
|
130
|
+
'core.component.editor.image.invalid-format': 'File format ".{format}" is not allowed. Allowed formats: {allowed}',
|
|
131
|
+
'core.component.editor.image.size-exceeded': 'File size {sizeMB}MB exceeds the limit of {maxSizeMB}MB',
|
|
132
|
+
'core.component.editor.image.min-width': 'Image width {width}px is below the minimum of {min}px',
|
|
133
|
+
'core.component.editor.image.min-height': 'Image height {height}px is below the minimum of {min}px',
|
|
134
|
+
'core.component.editor.image.max-width': 'Image width {width}px exceeds the limit of {max}px',
|
|
135
|
+
'core.component.editor.image.max-height': 'Image height {height}px exceeds the limit of {max}px',
|
|
136
|
+
'core.component.editor.image.max-per-selection': 'You can select at most {max} images per selection',
|
|
137
|
+
// ---- Component: document-builder ----
|
|
138
|
+
'core.component.document-builder.page-number.current': 'Current page number',
|
|
139
|
+
'core.component.document-builder.page-number.total': 'Total pages',
|
|
140
|
+
'core.component.document-builder.ck-comment.label': 'Comment',
|
|
141
|
+
'core.component.document-builder.ck-comment.text-too-long': 'Text too long ({length} characters). Maximum {max} characters.',
|
|
142
|
+
'core.component.document-builder.variable.not-allowed': 'Adding variable to the text is not allowed',
|
|
143
|
+
'core.component.document-builder.variable.invalid-data': 'Invalid variable data',
|
|
144
|
+
// ---- Component: form-builder ----
|
|
145
|
+
'core.component.form-builder.field-key': 'Field key',
|
|
146
|
+
'core.component.form-builder.display': 'Display',
|
|
147
|
+
'core.component.form-builder.general': 'General',
|
|
148
|
+
'core.component.form-builder.visible-when': 'Visible when',
|
|
149
|
+
'core.component.form-builder.required': 'Required',
|
|
150
|
+
'core.component.form-builder.label': 'Label',
|
|
151
|
+
'core.component.form-builder.disabled': 'Disabled',
|
|
152
|
+
'core.component.form-builder.disabled-when': 'Disabled when',
|
|
153
|
+
'core.component.form-builder.hidden-when': 'Hidden when',
|
|
154
|
+
'core.component.form-builder.validation': 'Validation',
|
|
155
|
+
'core.component.form-builder.required-when': 'Required when',
|
|
156
|
+
'core.component.form-builder.confirm': 'Confirm',
|
|
157
|
+
'core.component.form-builder.delete': 'Delete',
|
|
158
|
+
'core.component.form-builder.save': 'Save',
|
|
159
|
+
'core.component.form-builder.hint': 'Hint',
|
|
160
|
+
'core.component.form-builder.parameter': 'Parameters',
|
|
161
|
+
'core.component.form-builder.add-field': 'Add field',
|
|
162
|
+
'core.component.form-builder.data': 'Data',
|
|
163
|
+
'core.component.form-builder.query-condition': 'Query condition',
|
|
164
|
+
'core.component.form-builder.set-query-value': 'Set query value',
|
|
165
|
+
'core.component.form-builder.value-source-field': 'Source field',
|
|
166
|
+
'core.component.form-builder.assign-parameter': 'Assign parameter',
|
|
167
|
+
'core.component.form-builder.template-data': 'Template data',
|
|
168
|
+
'core.component.form-builder.set-expression': 'Set expression',
|
|
169
|
+
'core.component.form-builder.condition-group': 'Condition group',
|
|
170
|
+
'core.component.form-builder.condition': 'Condition',
|
|
171
|
+
'core.component.form-builder.layout': 'Layout',
|
|
172
|
+
'core.component.form-builder.maxlength': 'Maximum characters',
|
|
173
|
+
'core.component.form-builder.assign-parameter-value': 'Assign parameter value',
|
|
174
|
+
'core.component.form-builder.parameter-name': 'Parameter name',
|
|
175
|
+
'core.component.form-builder.parameter-value': 'Parameter value',
|
|
176
|
+
'core.component.form-builder.assign-value': 'Assign value',
|
|
177
|
+
'core.component.form-builder.add-data': 'Add data',
|
|
178
|
+
'core.component.form-builder.data-api': 'API data',
|
|
179
|
+
'core.component.form-builder.data-static': 'Static data',
|
|
180
|
+
'core.component.form-builder.set-on-change-assign': 'Set value-on-change',
|
|
181
|
+
'core.component.form-builder.target-field': 'Target field',
|
|
182
|
+
'core.component.form-builder.target-value': 'Target value',
|
|
183
|
+
'core.component.form-builder.column-data': 'Column data',
|
|
184
|
+
'core.component.form-builder.add-column': 'Add column',
|
|
185
|
+
'core.component.form-builder.column-config': 'Column config',
|
|
186
|
+
'core.component.form-builder.column-name': 'Column name',
|
|
187
|
+
'core.component.form-builder.width': 'Width',
|
|
188
|
+
'core.component.form-builder.data-type': 'Data type',
|
|
189
|
+
'core.component.form-builder.show-when-true': 'Show when TRUE',
|
|
190
|
+
'core.component.form-builder.show-when-false': 'Show when FALSE',
|
|
191
|
+
'core.component.form-builder.column-list': 'Column list',
|
|
192
|
+
'core.component.form-builder.yes-no': 'Yes/No',
|
|
193
|
+
'core.component.form-builder.config-validation-error-warning': 'Configure validation error/warning',
|
|
194
|
+
'core.component.form-builder.message-type': 'Message type',
|
|
195
|
+
'core.component.form-builder.message-display': 'Display message',
|
|
196
|
+
'core.component.form-builder.condition-expression': 'Condition expression',
|
|
197
|
+
'core.component.form-builder.add-validation': 'Add validation',
|
|
198
|
+
'core.component.form-builder.expression': 'Expression',
|
|
199
|
+
'core.component.form-builder.available-methods': 'Available methods',
|
|
200
|
+
'core.component.form-builder.format': 'Format',
|
|
201
|
+
'core.component.form-builder.time': 'Time',
|
|
202
|
+
'core.component.form-builder.content': 'Content',
|
|
203
|
+
'core.component.form-builder.min': 'Minimum',
|
|
204
|
+
'core.component.form-builder.max': 'Maximum',
|
|
205
|
+
'core.component.form-builder.vertical': 'Vertical',
|
|
206
|
+
'core.component.form-builder.multiple': 'Multiple selection',
|
|
207
|
+
'core.component.form-builder.default-value': 'Default value',
|
|
208
|
+
'core.component.form-builder.type': 'Type',
|
|
209
|
+
'core.component.form-builder.file': 'File',
|
|
210
|
+
'core.component.form-builder.image': 'Image',
|
|
211
|
+
'core.component.form-builder.max-files': 'Max files/images',
|
|
212
|
+
'core.component.form-builder.size-mb': 'Size (MB)',
|
|
213
|
+
'core.component.form-builder.format-example': 'Format (e.g. png,jpg ...)',
|
|
214
|
+
'core.component.form-builder.source-mobile': 'Source (mobile)',
|
|
215
|
+
'core.component.form-builder.config-variable': 'Configure variables',
|
|
216
|
+
'core.component.form-builder.config-validation-warning-error': 'Configure validation warning/error',
|
|
217
|
+
'core.component.form-builder.back-to-design': 'Back to design',
|
|
218
|
+
'core.component.form-builder.preview': 'Preview',
|
|
219
|
+
'core.component.form-builder.drag-vertically': 'Drag up/down',
|
|
220
|
+
'core.component.form-builder.unset-readonly': 'Remove read-only',
|
|
221
|
+
'core.component.form-builder.set-readonly': 'Read-only',
|
|
222
|
+
'core.component.form-builder.duplicate': 'Duplicate',
|
|
223
|
+
'core.component.form-builder.show': 'Show',
|
|
224
|
+
'core.component.form-builder.hide': 'Hide',
|
|
225
|
+
'core.component.form-builder.flex': 'Flex',
|
|
226
|
+
'core.component.form-builder.display-label': 'Display label',
|
|
227
|
+
'core.component.form-builder.attribute': 'Attribute',
|
|
228
|
+
'core.component.form-builder.add-variable': 'Add variable',
|
|
229
|
+
'core.component.form-builder.add-new': 'Add new',
|
|
230
|
+
'core.component.form-builder.detail': 'Details',
|
|
231
|
+
'core.component.form-builder.create-update': 'Create/update',
|
|
232
|
+
'core.component.form-builder.default': 'Default',
|
|
233
|
+
'core.component.form-builder.show-more': 'Show more',
|
|
234
|
+
'core.component.form-builder.show-less': 'Show less',
|
|
235
|
+
'core.component.form-builder.row-overflow': 'Cannot move to this row because the total size exceeds 12 columns',
|
|
236
|
+
'core.component.form-builder.upload-source.all': 'All',
|
|
237
|
+
'core.component.form-builder.upload-source.photo-library': 'Pick from library',
|
|
238
|
+
'core.component.form-builder.upload-source.capture': 'Take photo',
|
|
239
|
+
// ---- Component: code-editor ----
|
|
240
|
+
'core.component.code-editor.copied': 'Copied!',
|
|
241
|
+
'core.component.code-editor.copy': 'Copy code',
|
|
242
|
+
// ---- Component: history ----
|
|
243
|
+
'core.component.history.by': 'By',
|
|
244
|
+
// ---- Component: import-excel ----
|
|
245
|
+
'core.component.import-excel.title': 'Import Excel data',
|
|
246
|
+
'core.component.import-excel.see-all': 'See all',
|
|
247
|
+
'core.component.import-excel.valid-rows': 'Valid rows',
|
|
248
|
+
'core.component.import-excel.error-rows': 'Error rows',
|
|
249
|
+
'core.component.import-excel.warning-rows': 'Warning rows',
|
|
250
|
+
'core.component.import-excel.valid-data': 'Valid data',
|
|
251
|
+
'core.component.import-excel.download-template-tooltip': 'Click to download template',
|
|
252
|
+
'core.component.import-excel.upload': 'Upload',
|
|
253
|
+
'core.component.import-excel.download': 'Download',
|
|
254
|
+
'core.component.import-excel.confirm-save': 'Confirm & Save',
|
|
255
|
+
'core.component.import-excel.status': 'Status',
|
|
256
|
+
'core.component.import-excel.no-data-upload': 'No data uploaded',
|
|
257
|
+
'core.component.import-excel.click-here-template': 'Click here to download template',
|
|
258
|
+
'core.component.import-excel.no-data-in-file': 'File has no data',
|
|
259
|
+
'core.component.import-excel.row-limit': 'Upload limit is {limit} rows',
|
|
260
|
+
'core.component.import-excel.required': 'Required data',
|
|
261
|
+
'core.component.import-excel.min-length': 'Minimum string length: {min}',
|
|
262
|
+
'core.component.import-excel.max-length': 'Maximum string length: {max}',
|
|
263
|
+
'core.component.import-excel.not-a-number': '{value} is not a valid number',
|
|
264
|
+
'core.component.import-excel.below-min': '{value} is below the minimum value: {min}',
|
|
265
|
+
'core.component.import-excel.above-max': '{value} is above the maximum value: {max}',
|
|
266
|
+
'core.component.import-excel.invalid-bool': 'Please enter a valid value (true, false, 1, 0)',
|
|
267
|
+
'core.component.import-excel.invalid-value': 'Value {value} is invalid',
|
|
268
|
+
'core.component.import-excel.value-not-in-list': 'Value {value} is not in the allowed list [{list}]',
|
|
269
|
+
'core.component.import-excel.invalid-date-format': 'Date {value} does not match format {format}',
|
|
270
|
+
'core.component.import-excel.generic-error': 'An error occurred',
|
|
271
|
+
'core.component.import-excel.notify-title': 'Notification',
|
|
272
|
+
'core.component.import-excel.message-column': 'Message',
|
|
273
|
+
'core.component.import-excel.success': 'Success',
|
|
274
|
+
// ---- Component: preview-image ----
|
|
275
|
+
'core.component.preview-image.no-image': 'No image information',
|
|
276
|
+
'core.component.preview-image.title': 'Preview image',
|
|
277
|
+
// ---- Component: table ----
|
|
278
|
+
'core.component.table.setup': 'Table setup',
|
|
279
|
+
'core.component.table.column-header': 'Column header',
|
|
280
|
+
'core.component.table.width': 'Width',
|
|
281
|
+
'core.component.table.fixed': 'Fixed',
|
|
282
|
+
'core.component.table.char-limit': 'Character limit',
|
|
283
|
+
'core.component.table.skip': 'Skip',
|
|
284
|
+
'core.component.table.apply': 'Apply',
|
|
285
|
+
'core.component.table.filter': 'Filter',
|
|
286
|
+
'core.component.table.clear-selection': 'Clear selection',
|
|
287
|
+
'core.component.table.customize': 'Customize',
|
|
288
|
+
'core.component.table.search': 'Search',
|
|
289
|
+
'core.component.table.reload': 'Reload',
|
|
290
|
+
'core.component.table.setup-short': 'Setup',
|
|
291
|
+
'core.component.table.no-results': 'No results found',
|
|
292
|
+
'core.component.table.no-results-hint': 'Please search or filter with different criteria',
|
|
293
|
+
'core.component.table.choose-filter-hint': 'Please choose a filter to start',
|
|
294
|
+
'core.component.table.no-data': 'No data',
|
|
295
|
+
'core.component.table.export-excel': 'Export Excel',
|
|
296
|
+
'core.component.table.export-csv': 'Export CSV',
|
|
297
|
+
'core.component.table.showing': 'Showing:',
|
|
298
|
+
'core.component.table.paginator.first-page': 'First page',
|
|
299
|
+
'core.component.table.paginator.last-page': 'Last page',
|
|
300
|
+
'core.component.table.paginator.items-per-page': 'Showing',
|
|
301
|
+
'core.component.table.paginator.next-page': 'Next page',
|
|
302
|
+
'core.component.table.paginator.previous-page': 'Previous page',
|
|
303
|
+
'core.component.table.error-occurred': 'An error occurred',
|
|
304
|
+
'core.component.table.not-an-array': 'Data is not an array',
|
|
305
|
+
'core.component.table.config.confirm-reset': 'Confirm reset all settings to defaults',
|
|
306
|
+
'core.component.table.popup-export.select-columns': 'Please select columns to export',
|
|
307
|
+
'core.component.table.selector-action.default-msg': 'items selected',
|
|
308
|
+
'core.component.tab-router.too-many-tabs': 'You have opened too many tabs.',
|
|
309
|
+
// ---- Component: upload-file ----
|
|
310
|
+
'core.component.upload-file.upload': 'Upload file',
|
|
311
|
+
'core.component.upload-file.error-occurred': 'An error occurred',
|
|
312
|
+
'core.component.upload-file.please-upload': 'Please upload a file/image',
|
|
313
|
+
'core.component.upload-file.desc-format-and-size': 'Format: {exts} and up to: {maxSize}MB',
|
|
314
|
+
'core.component.upload-file.desc-format': 'Format: {exts}',
|
|
315
|
+
'core.component.upload-file.desc-max-size': 'Up to: {maxSize}MB',
|
|
316
|
+
'core.component.upload-file.not-image': '[{name}] Uploaded file is not an image',
|
|
317
|
+
'core.component.upload-file.invalid-format': '[{name}] Uploaded file has invalid format: {exts}',
|
|
318
|
+
'core.component.upload-file.size-exceeded': '[{name}] Max file size: {maxSize} MB',
|
|
319
|
+
'core.component.upload-file.upload-failed': 'An error occurred during file upload',
|
|
320
|
+
'core.component.upload-file.too-many-files': 'You selected too many files. Please check the count',
|
|
321
|
+
'core.component.upload-file.confirm-delete-message': 'Do you want to delete this file? This action cannot be undone',
|
|
322
|
+
'core.component.upload-file.confirm-delete-title': 'Confirm delete?',
|
|
323
|
+
'core.component.upload-file.confirm-yes': 'Confirm',
|
|
324
|
+
'core.component.upload-file.confirm-no': 'Cancel',
|
|
325
|
+
'core.component.upload-file.no-configuration': 'Please inject SD_UPLOAD_FILE_CONFIGURATION or pass [upload] directly into the component',
|
|
326
|
+
'core.component.upload-file.no-configuration-key': 'No upload configuration found for key=\'{key}\'. Please check providers or pass [upload] directly',
|
|
327
|
+
'core.component.upload-file.preview-title': 'Preview image',
|
|
328
|
+
// ---- Module: layout (sidebar / user menu) ----
|
|
329
|
+
'core.module.layout.user.change-password': 'Change password',
|
|
330
|
+
'core.module.layout.user.logout': 'Sign out',
|
|
331
|
+
'core.module.layout.sidebar.search': 'Search',
|
|
332
|
+
// ---- Module: layout (greeting + weekday) ----
|
|
333
|
+
'core.module.layout.greeting.hello': 'Hello, {name}',
|
|
334
|
+
'core.module.layout.weekday.0': 'Sunday',
|
|
335
|
+
'core.module.layout.weekday.1': 'Monday',
|
|
336
|
+
'core.module.layout.weekday.2': 'Tuesday',
|
|
337
|
+
'core.module.layout.weekday.3': 'Wednesday',
|
|
338
|
+
'core.module.layout.weekday.4': 'Thursday',
|
|
339
|
+
'core.module.layout.weekday.5': 'Friday',
|
|
340
|
+
'core.module.layout.weekday.6': 'Saturday',
|
|
341
|
+
'core.module.layout.today-info.format': '{weekday}, {date}',
|
|
342
|
+
// ---- Module: layout (forbidden page) ----
|
|
343
|
+
'core.module.layout.forbidden.title': 'Access denied',
|
|
344
|
+
'core.module.layout.forbidden.message': "You don't have permission to access this page. Please contact your administrator or go back to the home page",
|
|
345
|
+
'core.module.layout.forbidden.back-home': 'Back to home',
|
|
346
|
+
// ---- Module: layout (not-found page) ----
|
|
347
|
+
'core.module.layout.not-found.title': '404 - Page not found',
|
|
348
|
+
'core.module.layout.not-found.message': "The page you're looking for doesn't exist or has been removed. Please check the URL or go back to the home page to continue.",
|
|
349
|
+
'core.module.layout.not-found.back': 'Go back',
|
|
350
|
+
// ---- Module: layout (home page) ----
|
|
351
|
+
'core.module.layout.home.tab-name': 'Home',
|
|
352
|
+
'core.module.layout.home.wish-line-1': 'Wishing you a workday',
|
|
353
|
+
'core.module.layout.home.wish-line-2': 'full of energy & productivity!',
|
|
354
|
+
// ---- Module: generic (generic-select) ----
|
|
355
|
+
'core.module.generic.generic-select.detail-link': 'details',
|
|
356
|
+
};
|
|
357
|
+
|
|
358
|
+
const VI_MESSAGES = {
|
|
359
|
+
'core.common.cancel': 'Hủy',
|
|
360
|
+
'core.common.close': 'Đóng',
|
|
361
|
+
'core.common.reload': 'Tải lại trang',
|
|
362
|
+
'core.test.greet': 'Xin chào {name}',
|
|
363
|
+
// ---- Validators (pattern.model.ts) ----
|
|
364
|
+
'core.validator.email.name': 'Email',
|
|
365
|
+
'core.validator.email.error': 'Email không hợp lệ',
|
|
366
|
+
'core.validator.phone.name': 'SĐT',
|
|
367
|
+
'core.validator.phone.error': 'Số điện thoại không hợp lệ',
|
|
368
|
+
'core.validator.phone-vn.name': 'SĐT VN',
|
|
369
|
+
'core.validator.phone-vn.error': 'Số điện thoại không hợp lệ',
|
|
370
|
+
'core.validator.cccd.name': 'CCCD',
|
|
371
|
+
'core.validator.cccd.error': 'CCCD không hợp lệ (12 chữ số)',
|
|
372
|
+
'core.validator.passport.name': 'Hộ chiếu',
|
|
373
|
+
'core.validator.passport.error': 'Hộ chiếu không hợp lệ (1 chữ cái + 7 chữ số)',
|
|
374
|
+
'core.validator.id-vn.name': 'CCCD/Hộ chiếu',
|
|
375
|
+
'core.validator.id-vn.error': 'CCCD/CMND hoặc Hộ chiếu không hợp lệ',
|
|
376
|
+
'core.validator.time.name': 'Giờ',
|
|
377
|
+
'core.validator.time.error': 'Giờ không hợp lệ (định dạng HH:mm)',
|
|
378
|
+
// ---- Operators (operator.model.ts) ----
|
|
379
|
+
'core.operator.equal.display': 'Bằng',
|
|
380
|
+
'core.operator.not-equal.display': 'Không bằng',
|
|
381
|
+
'core.operator.greater-than.display': 'Lớn hơn',
|
|
382
|
+
'core.operator.less-than.display': 'Nhỏ hơn',
|
|
383
|
+
'core.operator.greater-or-equal.display': 'Lớn hơn, hoặc bằng',
|
|
384
|
+
'core.operator.less-or-equal.display': 'Nhỏ hơn, hoặc bằng',
|
|
385
|
+
'core.operator.contain.display': 'Chứa',
|
|
386
|
+
'core.operator.not-contain.display': 'Không chứa',
|
|
387
|
+
'core.operator.start-with.display': 'Bắt đầu bởi',
|
|
388
|
+
'core.operator.end-with.display': 'Kết thúc bởi',
|
|
389
|
+
'core.operator.in.display': 'Nằm trong',
|
|
390
|
+
'core.operator.not-in.display': 'Không nằm trong',
|
|
391
|
+
'core.operator.null.display': 'Là rỗng',
|
|
392
|
+
'core.operator.not-null.display': 'Không rỗng',
|
|
393
|
+
// ---- Utility errors (utility.extension.ts) ----
|
|
394
|
+
'core.utility.upload.invalid-format': '[{name}] File tải lên không đúng định dạng. Vui lòng chọn lại',
|
|
395
|
+
'core.utility.upload.invalid-size': '[{name}] Kích thước file không hợp lệ. Vui lòng chọn một file khác',
|
|
396
|
+
// ---- Global error handler ----
|
|
397
|
+
'core.handler.global-error.update-title': 'HỆ THỐNG CÓ BẢN CẬP NHẬT MỚI',
|
|
398
|
+
'core.handler.global-error.update-body': 'Phiên bản hiện tại đã cũ và không tải được tài nguyên.\nVui lòng bấm OK để tải lại trang.',
|
|
399
|
+
// ---- Interceptor: no-internet ----
|
|
400
|
+
'core.interceptor.no-internet.offline': 'Không có kết nối mạng. Đang chờ kết nối...',
|
|
401
|
+
'core.interceptor.no-internet.cors-error': 'Không thể kết nối đến máy chủ (Lỗi CORS hoặc cấu hình).',
|
|
402
|
+
'core.interceptor.no-internet.maintenance': 'Máy chủ đang bảo trì. Vui lòng thử lại sau!',
|
|
403
|
+
'core.interceptor.no-internet.restored': 'Kết nối đã được khôi phục!',
|
|
404
|
+
// ---- Service: excel ----
|
|
405
|
+
'core.excel.cannot-read-file': 'Không đọc được nội dung file',
|
|
406
|
+
'core.excel.no-sheet': 'File Excel không có sheet dữ liệu',
|
|
407
|
+
// ---- Service: docx ----
|
|
408
|
+
'core.docx.invalid-format': 'Định dạng không hợp lệ. Vui lòng chọn Mẫu có định dạng DOC hoặc DOCX',
|
|
409
|
+
'core.docx.size-exceeded': 'Kích thước tệp mẫu vượt quá tiêu chuẩn hỗ trợ của hệ thống. Vui lòng thử lại',
|
|
410
|
+
'core.docx.convert-error': 'Có lỗi xảy ra khi chuyển đổi file DOCX',
|
|
411
|
+
// ---- Service: confirm ----
|
|
412
|
+
'core.confirm.title': 'Xác nhận',
|
|
413
|
+
'core.confirm.yes': 'Đồng ý',
|
|
414
|
+
'core.confirm.no': 'Hủy bỏ',
|
|
415
|
+
'core.confirm.yes-short': 'Có',
|
|
416
|
+
'core.confirm.no-short': 'Không',
|
|
417
|
+
// ---- Directive: hover-copy ----
|
|
418
|
+
'core.directive.hover-copy.tooltip': 'Sao chép',
|
|
419
|
+
// ---- Forms: input ----
|
|
420
|
+
'core.form.input.required': 'Vui lòng nhập thông tin',
|
|
421
|
+
'core.form.input.maxlength': 'Số ký tự tối đa: {max}',
|
|
422
|
+
'core.form.input.invalid-pattern': 'Định dạng không hợp lệ',
|
|
423
|
+
'core.form.input.exceeded': 'Vượt quá số ký tự tối đa',
|
|
424
|
+
// ---- Forms: autocomplete ----
|
|
425
|
+
'core.form.autocomplete.required': 'Vui lòng nhập thông tin',
|
|
426
|
+
// ---- Forms: chip ----
|
|
427
|
+
'core.form.chip.required': 'Vui lòng nhập thông tin',
|
|
428
|
+
'core.form.chip.minlength': 'Vui lòng nhập ít nhất {min} giá trị',
|
|
429
|
+
'core.form.chip.maxlength': 'Vui lòng nhập tối đa {max} giá trị',
|
|
430
|
+
// ---- Forms: chip-calendar ----
|
|
431
|
+
'core.form.chip-calendar.required': 'Vui lòng nhập thông tin',
|
|
432
|
+
'core.form.chip-calendar.minlength': 'Vui lòng nhập ít nhất {min} giá trị',
|
|
433
|
+
'core.form.chip-calendar.maxlength': 'Vui lòng nhập tối đa {max} giá trị',
|
|
434
|
+
// ---- Forms: date ----
|
|
435
|
+
'core.form.date.required': 'Vui lòng nhập thông tin',
|
|
436
|
+
'core.form.date.min-date': 'Ngày nhỏ nhất: {date}',
|
|
437
|
+
'core.form.date.max-date': 'Ngày lớn nhất: {date}',
|
|
438
|
+
'core.form.date.parse-error': 'Lỗi phân tích: {text}',
|
|
439
|
+
'core.form.date.invalid-format': 'Sai định dạng',
|
|
440
|
+
// ---- Forms: date-range ----
|
|
441
|
+
'core.form.date-range.required': 'Vui lòng nhập thông tin',
|
|
442
|
+
'core.form.date-range.invalid-min': 'Ngày bắt đầu không hợp lệ (nhỏ hơn giới hạn)',
|
|
443
|
+
'core.form.date-range.invalid-max': 'Ngày kết thúc không hợp lệ (lớn hơn giới hạn)',
|
|
444
|
+
'core.form.date-range.from': 'Từ',
|
|
445
|
+
'core.form.date-range.to': 'đến',
|
|
446
|
+
// ---- Forms: datetime ----
|
|
447
|
+
'core.form.datetime.required': 'Vui lòng nhập thông tin',
|
|
448
|
+
'core.form.datetime.min-date': 'Ngày nhỏ nhất: {date}',
|
|
449
|
+
'core.form.datetime.max-date': 'Ngày lớn nhất: {date}',
|
|
450
|
+
'core.form.datetime.invalid-format': 'Sai định dạng',
|
|
451
|
+
'core.form.datetime.now': 'Bây giờ',
|
|
452
|
+
'core.form.datetime.confirm': 'Xác nhận',
|
|
453
|
+
// ---- Forms: time-spinner ----
|
|
454
|
+
'core.form.time-spinner.hour': 'Giờ',
|
|
455
|
+
'core.form.time-spinner.minute': 'Phút',
|
|
456
|
+
'core.form.time-spinner.second': 'Giây',
|
|
457
|
+
'core.form.time-spinner.increase-hour': 'Tăng giờ',
|
|
458
|
+
'core.form.time-spinner.decrease-hour': 'Giảm giờ',
|
|
459
|
+
'core.form.time-spinner.increase-minute': 'Tăng phút',
|
|
460
|
+
'core.form.time-spinner.decrease-minute': 'Giảm phút',
|
|
461
|
+
'core.form.time-spinner.increase-second': 'Tăng giây',
|
|
462
|
+
'core.form.time-spinner.decrease-second': 'Giảm giây',
|
|
463
|
+
// ---- Forms: input-number ----
|
|
464
|
+
'core.form.input-number.required': 'Vui lòng nhập thông tin',
|
|
465
|
+
'core.form.input-number.min': 'Giá trị không được nhỏ hơn {min}',
|
|
466
|
+
'core.form.input-number.max': 'Giá trị không được lớn hơn {max}',
|
|
467
|
+
// ---- Forms: radio ----
|
|
468
|
+
'core.form.radio.required': 'Vui lòng nhập thông tin',
|
|
469
|
+
// ---- Forms: select ----
|
|
470
|
+
'core.form.select.required': 'Vui lòng nhập thông tin',
|
|
471
|
+
// ---- Forms: textarea ----
|
|
472
|
+
'core.form.textarea.required': 'Vui lòng nhập thông tin',
|
|
473
|
+
'core.form.textarea.maxlength': 'Số ký tự tối đa: {max}',
|
|
474
|
+
'core.form.textarea.invalid-pattern': 'Định dạng không hợp lệ',
|
|
475
|
+
'core.form.textarea.exceeded': 'Vượt quá số ký tự tối đa',
|
|
476
|
+
// ---- Component: editor ----
|
|
477
|
+
'core.component.editor.required': 'Vui lòng nhập nội dung',
|
|
478
|
+
'core.component.editor.maxlength': 'Số ký tự tối đa: {max}',
|
|
479
|
+
'core.component.editor.image.invalid-format': 'Định dạng file ".{format}" không được phép. Các định dạng hợp lệ: {allowed}',
|
|
480
|
+
'core.component.editor.image.size-exceeded': 'Dung lượng file {sizeMB}MB vượt quá giới hạn {maxSizeMB}MB',
|
|
481
|
+
'core.component.editor.image.min-width': 'Chiều rộng ảnh {width}px nhỏ hơn giới hạn tối thiểu {min}px',
|
|
482
|
+
'core.component.editor.image.min-height': 'Chiều cao ảnh {height}px nhỏ hơn giới hạn tối thiểu {min}px',
|
|
483
|
+
'core.component.editor.image.max-width': 'Chiều rộng ảnh {width}px vượt quá giới hạn {max}px',
|
|
484
|
+
'core.component.editor.image.max-height': 'Chiều cao ảnh {height}px vượt quá giới hạn {max}px',
|
|
485
|
+
'core.component.editor.image.max-per-selection': 'Chỉ được phép chọn tối đa {max} ảnh mỗi lần',
|
|
486
|
+
// ---- Component: document-builder ----
|
|
487
|
+
'core.component.document-builder.page-number.current': 'Số trang hiện tại',
|
|
488
|
+
'core.component.document-builder.page-number.total': 'Tổng số trang',
|
|
489
|
+
'core.component.document-builder.ck-comment.label': 'Bình luận',
|
|
490
|
+
'core.component.document-builder.ck-comment.text-too-long': 'Văn bản quá dài ({length} ký tự). Tối đa {max} ký tự.',
|
|
491
|
+
'core.component.document-builder.variable.not-allowed': 'Không cho phép thêm variable vào văn bản',
|
|
492
|
+
'core.component.document-builder.variable.invalid-data': 'Dữ liệu variable không hợp lệ',
|
|
493
|
+
// ---- Component: form-builder ----
|
|
494
|
+
'core.component.form-builder.field-key': 'Trường dữ liệu',
|
|
495
|
+
'core.component.form-builder.display': 'Hiển thị',
|
|
496
|
+
'core.component.form-builder.general': 'Thông tin chung',
|
|
497
|
+
'core.component.form-builder.visible-when': 'Hiển thị khi',
|
|
498
|
+
'core.component.form-builder.required': 'Bắt buộc',
|
|
499
|
+
'core.component.form-builder.label': 'Tên hiển thị',
|
|
500
|
+
'core.component.form-builder.disabled': 'Vô hiệu',
|
|
501
|
+
'core.component.form-builder.disabled-when': 'Vô hiệu khi',
|
|
502
|
+
'core.component.form-builder.hidden-when': 'Ẩn khi',
|
|
503
|
+
'core.component.form-builder.validation': 'Ràng buộc',
|
|
504
|
+
'core.component.form-builder.required-when': 'Bắt buộc khi',
|
|
505
|
+
'core.component.form-builder.confirm': 'Xác nhận',
|
|
506
|
+
'core.component.form-builder.delete': 'Xóa',
|
|
507
|
+
'core.component.form-builder.save': 'Lưu',
|
|
508
|
+
'core.component.form-builder.hint': 'Gợi ý',
|
|
509
|
+
'core.component.form-builder.parameter': 'Tham số',
|
|
510
|
+
'core.component.form-builder.add-field': 'Thêm trường',
|
|
511
|
+
'core.component.form-builder.data': 'Dữ liệu',
|
|
512
|
+
'core.component.form-builder.query-condition': 'Điều kiện truy vấn',
|
|
513
|
+
'core.component.form-builder.set-query-value': 'Thiết lập giá trị truy vấn',
|
|
514
|
+
'core.component.form-builder.value-source-field': 'Trường lấy giá trị',
|
|
515
|
+
'core.component.form-builder.assign-parameter': 'Gán tham số',
|
|
516
|
+
'core.component.form-builder.template-data': 'Dữ liệu mẫu',
|
|
517
|
+
'core.component.form-builder.set-expression': 'Thiết lập biểu thức',
|
|
518
|
+
'core.component.form-builder.condition-group': 'Nhóm điều kiện',
|
|
519
|
+
'core.component.form-builder.condition': 'Điều kiện',
|
|
520
|
+
'core.component.form-builder.layout': 'Bố cục',
|
|
521
|
+
'core.component.form-builder.maxlength': 'Ký tự tối đa',
|
|
522
|
+
'core.component.form-builder.assign-parameter-value': 'Gán giá trị Tham số',
|
|
523
|
+
'core.component.form-builder.parameter-name': 'Tên tham số',
|
|
524
|
+
'core.component.form-builder.parameter-value': 'Giá trị tương ứng',
|
|
525
|
+
'core.component.form-builder.assign-value': 'Gán giá trị',
|
|
526
|
+
'core.component.form-builder.add-data': 'Thêm dữ liệu',
|
|
527
|
+
'core.component.form-builder.data-api': 'Dữ liệu API',
|
|
528
|
+
'core.component.form-builder.data-static': 'Dữ liệu tĩnh',
|
|
529
|
+
'core.component.form-builder.set-on-change-assign': 'Thiết lập gán giá trị khi thay đổi',
|
|
530
|
+
'core.component.form-builder.target-field': 'Trường muốn gán giá trị',
|
|
531
|
+
'core.component.form-builder.target-value': 'Giá trị muốn gán',
|
|
532
|
+
'core.component.form-builder.column-data': 'Dữ liệu cột',
|
|
533
|
+
'core.component.form-builder.add-column': 'Thêm cột',
|
|
534
|
+
'core.component.form-builder.column-config': 'Cấu hình cột',
|
|
535
|
+
'core.component.form-builder.column-name': 'Tên cột',
|
|
536
|
+
'core.component.form-builder.width': 'Chiều rộng',
|
|
537
|
+
'core.component.form-builder.data-type': 'Loại dữ liệu',
|
|
538
|
+
'core.component.form-builder.show-when-true': 'Hiển thị khi TRUE',
|
|
539
|
+
'core.component.form-builder.show-when-false': 'Hiển thị khi FALSE',
|
|
540
|
+
'core.component.form-builder.column-list': 'Danh sách cột',
|
|
541
|
+
'core.component.form-builder.yes-no': 'Có/Không',
|
|
542
|
+
'core.component.form-builder.config-validation-error-warning': 'Cấu hình xác thực lỗi/cảnh báo',
|
|
543
|
+
'core.component.form-builder.message-type': 'Loại thông báo',
|
|
544
|
+
'core.component.form-builder.message-display': 'Thông báo hiển thị',
|
|
545
|
+
'core.component.form-builder.condition-expression': 'Biểu thức điều kiện',
|
|
546
|
+
'core.component.form-builder.add-validation': 'Thêm xác thực',
|
|
547
|
+
'core.component.form-builder.expression': 'Biểu thức',
|
|
548
|
+
'core.component.form-builder.available-methods': 'Phương thức sẵn có',
|
|
549
|
+
'core.component.form-builder.format': 'Định dạng',
|
|
550
|
+
'core.component.form-builder.time': 'Thời điểm',
|
|
551
|
+
'core.component.form-builder.content': 'Nội dung',
|
|
552
|
+
'core.component.form-builder.min': 'Giá trị nhỏ nhất',
|
|
553
|
+
'core.component.form-builder.max': 'Giá trị lớn nhất',
|
|
554
|
+
'core.component.form-builder.vertical': 'Dọc',
|
|
555
|
+
'core.component.form-builder.multiple': 'Chọn nhiều',
|
|
556
|
+
'core.component.form-builder.default-value': 'Giá trị mặc định',
|
|
557
|
+
'core.component.form-builder.type': 'Loại',
|
|
558
|
+
'core.component.form-builder.file': 'Tệp',
|
|
559
|
+
'core.component.form-builder.image': 'Ảnh',
|
|
560
|
+
'core.component.form-builder.max-files': 'SL tệp/ảnh tối đa',
|
|
561
|
+
'core.component.form-builder.size-mb': 'Dung lượng (Mb)',
|
|
562
|
+
'core.component.form-builder.format-example': 'Định dạng (VD: png,jpg ...)',
|
|
563
|
+
'core.component.form-builder.source-mobile': 'Nguồn (mobile)',
|
|
564
|
+
'core.component.form-builder.config-variable': 'Cấu hình biến',
|
|
565
|
+
'core.component.form-builder.config-validation-warning-error': 'Cấu hình xác thực cảnh báo/lỗi',
|
|
566
|
+
'core.component.form-builder.back-to-design': 'Trở về thiết kế',
|
|
567
|
+
'core.component.form-builder.preview': 'Xem thử',
|
|
568
|
+
'core.component.form-builder.drag-vertically': 'Kéo lên / xuống',
|
|
569
|
+
'core.component.form-builder.unset-readonly': 'Bỏ chỉ xem',
|
|
570
|
+
'core.component.form-builder.set-readonly': 'Chỉ xem',
|
|
571
|
+
'core.component.form-builder.duplicate': 'Nhân bản',
|
|
572
|
+
'core.component.form-builder.show': 'Hiện',
|
|
573
|
+
'core.component.form-builder.hide': 'Ẩn',
|
|
574
|
+
'core.component.form-builder.flex': 'Co dãn',
|
|
575
|
+
'core.component.form-builder.display-label': 'Nhãn hiển thị',
|
|
576
|
+
'core.component.form-builder.attribute': 'Thuộc tính',
|
|
577
|
+
'core.component.form-builder.add-variable': 'Thêm biến',
|
|
578
|
+
'core.component.form-builder.add-new': 'Thêm mới',
|
|
579
|
+
'core.component.form-builder.detail': 'Chi tiết',
|
|
580
|
+
'core.component.form-builder.create-update': 'Tạo mới/cập nhật',
|
|
581
|
+
'core.component.form-builder.default': 'Mặc định',
|
|
582
|
+
'core.component.form-builder.show-more': 'Xem thêm',
|
|
583
|
+
'core.component.form-builder.show-less': 'Thu gọn',
|
|
584
|
+
'core.component.form-builder.row-overflow': 'Không thể di chuyển tới dòng này vì tổng kích thước vượt quá 12 cột',
|
|
585
|
+
'core.component.form-builder.upload-source.all': 'Tất cả',
|
|
586
|
+
'core.component.form-builder.upload-source.photo-library': 'Chọn từ thư viện',
|
|
587
|
+
'core.component.form-builder.upload-source.capture': 'Chụp ảnh',
|
|
588
|
+
// ---- Component: code-editor ----
|
|
589
|
+
'core.component.code-editor.copied': 'Đã copy!',
|
|
590
|
+
'core.component.code-editor.copy': 'Copy code',
|
|
591
|
+
// ---- Component: history ----
|
|
592
|
+
'core.component.history.by': 'Bởi',
|
|
593
|
+
// ---- Component: import-excel ----
|
|
594
|
+
'core.component.import-excel.title': 'Nhập dữ liệu Excel',
|
|
595
|
+
'core.component.import-excel.see-all': 'Xem tất cả',
|
|
596
|
+
'core.component.import-excel.valid-rows': 'Số dòng dữ liệu hợp lệ',
|
|
597
|
+
'core.component.import-excel.error-rows': 'Số dòng dữ liệu có lỗi',
|
|
598
|
+
'core.component.import-excel.warning-rows': 'Số dòng dữ liệu có cảnh báo',
|
|
599
|
+
'core.component.import-excel.valid-data': 'Dữ liệu hợp lệ',
|
|
600
|
+
'core.component.import-excel.download-template-tooltip': 'Nhấn để tải tệp mẫu về máy',
|
|
601
|
+
'core.component.import-excel.upload': 'Tải lên',
|
|
602
|
+
'core.component.import-excel.download': 'Tải về',
|
|
603
|
+
'core.component.import-excel.confirm-save': 'Xác nhận & Lưu',
|
|
604
|
+
'core.component.import-excel.status': 'Trạng thái',
|
|
605
|
+
'core.component.import-excel.no-data-upload': 'Chưa có dữ liệu tải lên',
|
|
606
|
+
'core.component.import-excel.click-here-template': 'Nhấn vào đây để tải tệp mẫu',
|
|
607
|
+
'core.component.import-excel.no-data-in-file': 'Tệp tin không có dữ liệu',
|
|
608
|
+
'core.component.import-excel.row-limit': 'Giới hạn tải lên {limit} dòng',
|
|
609
|
+
'core.component.import-excel.required': 'Dữ liệu bắt buộc',
|
|
610
|
+
'core.component.import-excel.min-length': 'Độ dài chuỗi tối thiểu: {min}',
|
|
611
|
+
'core.component.import-excel.max-length': 'Độ dài chuỗi tối đa: {max}',
|
|
612
|
+
'core.component.import-excel.not-a-number': '{value} không phải số hợp lệ',
|
|
613
|
+
'core.component.import-excel.below-min': '{value} không thỏa giá trị tối thiểu: {min}',
|
|
614
|
+
'core.component.import-excel.above-max': '{value} không thỏa giá trị tối đa: {max}',
|
|
615
|
+
'core.component.import-excel.invalid-bool': 'Vui lòng nhập giá trị hợp lệ true, false, 1, 0',
|
|
616
|
+
'core.component.import-excel.invalid-value': 'Giá trị {value} không hợp lệ',
|
|
617
|
+
'core.component.import-excel.value-not-in-list': 'Giá trị {value} không thuộc danh sách cho phép [{list}]',
|
|
618
|
+
'core.component.import-excel.invalid-date-format': 'Ngày {value} không đúng định dạng {format}',
|
|
619
|
+
'core.component.import-excel.generic-error': 'Có lỗi xảy ra',
|
|
620
|
+
'core.component.import-excel.notify-title': 'Thông báo',
|
|
621
|
+
'core.component.import-excel.message-column': 'Thông báo',
|
|
622
|
+
'core.component.import-excel.success': 'Thành công',
|
|
623
|
+
// ---- Component: preview-image ----
|
|
624
|
+
'core.component.preview-image.no-image': 'Không có thông tin ảnh',
|
|
625
|
+
'core.component.preview-image.title': 'Xem ảnh',
|
|
626
|
+
// ---- Component: table ----
|
|
627
|
+
'core.component.table.setup': 'Thiết lập bảng',
|
|
628
|
+
'core.component.table.column-header': 'Tiêu đề cột',
|
|
629
|
+
'core.component.table.width': 'Rộng',
|
|
630
|
+
'core.component.table.fixed': 'Cố định',
|
|
631
|
+
'core.component.table.char-limit': 'Giới hạn ký tự',
|
|
632
|
+
'core.component.table.skip': 'Bỏ qua',
|
|
633
|
+
'core.component.table.apply': 'Áp dụng',
|
|
634
|
+
'core.component.table.filter': 'Bộ lọc',
|
|
635
|
+
'core.component.table.clear-selection': 'Xóa lựa chọn',
|
|
636
|
+
'core.component.table.customize': 'Tùy chỉnh',
|
|
637
|
+
'core.component.table.search': 'Tìm kiếm',
|
|
638
|
+
'core.component.table.reload': 'Tải lại',
|
|
639
|
+
'core.component.table.setup-short': 'Thiết lập',
|
|
640
|
+
'core.component.table.no-results': 'Không có kết quả phù hợp',
|
|
641
|
+
'core.component.table.no-results-hint': 'Vui lòng tìm kiếm hoặc lọc theo tiêu chí khác',
|
|
642
|
+
'core.component.table.choose-filter-hint': 'Vui lòng chọn bộ lọc để bắt đầu',
|
|
643
|
+
'core.component.table.no-data': 'Chưa có dữ liệu',
|
|
644
|
+
'core.component.table.export-excel': 'Xuất excel',
|
|
645
|
+
'core.component.table.export-csv': 'Xuất CSV',
|
|
646
|
+
'core.component.table.showing': 'Đang hiển thị:',
|
|
647
|
+
'core.component.table.paginator.first-page': 'Trang đầu',
|
|
648
|
+
'core.component.table.paginator.last-page': 'Trang cuối',
|
|
649
|
+
'core.component.table.paginator.items-per-page': 'Đang hiển thị',
|
|
650
|
+
'core.component.table.paginator.next-page': 'Trang sau',
|
|
651
|
+
'core.component.table.paginator.previous-page': 'Trang trước',
|
|
652
|
+
'core.component.table.error-occurred': 'Có lỗi xảy ra',
|
|
653
|
+
'core.component.table.not-an-array': 'Dữ liệu không phải là một mảng',
|
|
654
|
+
'core.component.table.config.confirm-reset': 'Xác nhận đưa tất cả thiết lập về mặc định',
|
|
655
|
+
'core.component.table.popup-export.select-columns': 'Vui lòng chọn cột dữ liệu để xuất',
|
|
656
|
+
'core.component.table.selector-action.default-msg': 'dữ liệu được chọn',
|
|
657
|
+
'core.component.tab-router.too-many-tabs': 'Bạn đã mở quá nhiều tab.',
|
|
658
|
+
// ---- Component: upload-file ----
|
|
659
|
+
'core.component.upload-file.upload': 'Tải file',
|
|
660
|
+
'core.component.upload-file.error-occurred': 'Có lỗi xảy ra',
|
|
661
|
+
'core.component.upload-file.please-upload': 'Vui lòng tải lên tệp/ảnh',
|
|
662
|
+
'core.component.upload-file.desc-format-and-size': 'Định dạng: {exts} và tối đa: {maxSize}MB',
|
|
663
|
+
'core.component.upload-file.desc-format': 'Định dạng: {exts}',
|
|
664
|
+
'core.component.upload-file.desc-max-size': 'Tối đa: {maxSize}MB',
|
|
665
|
+
'core.component.upload-file.not-image': '[{name}] Tệp tải lên không phải là ảnh',
|
|
666
|
+
'core.component.upload-file.invalid-format': '[{name}] Tệp tải lên không đúng định dạng: {exts}',
|
|
667
|
+
'core.component.upload-file.size-exceeded': '[{name}] Kích thước tệp tối đa: {maxSize} MB',
|
|
668
|
+
'core.component.upload-file.upload-failed': 'Có lỗi xảy ra trong quá trình tải lên tệp',
|
|
669
|
+
'core.component.upload-file.too-many-files': 'Bạn đã chọn quá nhiều file. Vui lòng kiểm tra lại số lượng',
|
|
670
|
+
'core.component.upload-file.confirm-delete-message': 'Bạn có muốn xóa file này không? Thao tác này không thể hoàn tác',
|
|
671
|
+
'core.component.upload-file.confirm-delete-title': 'Xác nhận xóa?',
|
|
672
|
+
'core.component.upload-file.confirm-yes': 'Xác nhận',
|
|
673
|
+
'core.component.upload-file.confirm-no': 'Hủy',
|
|
674
|
+
'core.component.upload-file.no-configuration': 'Vui lòng inject SD_UPLOAD_FILE_CONFIGURATION hoặc truyền [upload] trực tiếp vào component',
|
|
675
|
+
'core.component.upload-file.no-configuration-key': 'Không tìm thấy upload configuration theo key=\'{key}\'. Vui lòng kiểm tra providers hoặc truyền [upload] trực tiếp',
|
|
676
|
+
'core.component.upload-file.preview-title': 'Xem ảnh',
|
|
677
|
+
// ---- Module: layout (sidebar / user menu) ----
|
|
678
|
+
'core.module.layout.user.change-password': 'Đổi mật khẩu',
|
|
679
|
+
'core.module.layout.user.logout': 'Đăng xuất',
|
|
680
|
+
'core.module.layout.sidebar.search': 'Tìm kiếm',
|
|
681
|
+
// ---- Module: layout (greeting + weekday) ----
|
|
682
|
+
'core.module.layout.greeting.hello': 'Xin chào, {name}',
|
|
683
|
+
'core.module.layout.weekday.0': 'Chủ Nhật',
|
|
684
|
+
'core.module.layout.weekday.1': 'Thứ 2',
|
|
685
|
+
'core.module.layout.weekday.2': 'Thứ 3',
|
|
686
|
+
'core.module.layout.weekday.3': 'Thứ 4',
|
|
687
|
+
'core.module.layout.weekday.4': 'Thứ 5',
|
|
688
|
+
'core.module.layout.weekday.5': 'Thứ 6',
|
|
689
|
+
'core.module.layout.weekday.6': 'Thứ 7',
|
|
690
|
+
'core.module.layout.today-info.format': '{weekday}, ngày {date}',
|
|
691
|
+
// ---- Module: layout (forbidden page) ----
|
|
692
|
+
'core.module.layout.forbidden.title': 'Không được phép truy cập',
|
|
693
|
+
'core.module.layout.forbidden.message': 'Bạn không có quyền truy cập vào trang này. Liên hệ với quản trị viên hoặc quay lại trang chủ',
|
|
694
|
+
'core.module.layout.forbidden.back-home': 'Quay lại trang chủ',
|
|
695
|
+
// ---- Module: layout (not-found page) ----
|
|
696
|
+
'core.module.layout.not-found.title': '404 - Trang không tồn tại',
|
|
697
|
+
'core.module.layout.not-found.message': 'Trang bạn tìm không tồn tại hoặc đã bị xóa. Vui lòng kiểm tra lại địa chỉ URL hoặc quay lại trang chủ để tiếp tục.',
|
|
698
|
+
'core.module.layout.not-found.back': 'Quay trở lại',
|
|
699
|
+
// ---- Module: layout (home page) ----
|
|
700
|
+
'core.module.layout.home.tab-name': 'Trang chủ',
|
|
701
|
+
'core.module.layout.home.wish-line-1': 'Chúc bạn một ngày làm việc',
|
|
702
|
+
'core.module.layout.home.wish-line-2': 'tràn đầy năng lượng & hiệu quả!',
|
|
703
|
+
// ---- Module: generic (generic-select) ----
|
|
704
|
+
'core.module.generic.generic-select.detail-link': 'chi tiết',
|
|
705
|
+
};
|
|
706
|
+
|
|
707
|
+
const SD_MESSAGES = {
|
|
708
|
+
vi: VI_MESSAGES,
|
|
709
|
+
en: EN_MESSAGES,
|
|
710
|
+
};
|
|
711
|
+
|
|
712
|
+
class SdI18nService {
|
|
713
|
+
#config = inject(SD_CORE_CONFIGURATION, { optional: true });
|
|
714
|
+
#language = signal(this.#resolveInitial());
|
|
715
|
+
#warned = new Set();
|
|
716
|
+
language = this.#language.asReadonly();
|
|
717
|
+
messages = computed(() => SD_MESSAGES[this.#language()]);
|
|
718
|
+
setLanguage(lang) {
|
|
719
|
+
if (!SD_SUPPORTED_LANGUAGES.includes(lang))
|
|
720
|
+
return;
|
|
721
|
+
this.#language.set(lang);
|
|
722
|
+
try {
|
|
723
|
+
localStorage.setItem(SD_I18N_STORAGE_KEY, lang);
|
|
724
|
+
}
|
|
725
|
+
catch { /* ignore */ }
|
|
726
|
+
}
|
|
727
|
+
t(key, params) {
|
|
728
|
+
const current = SD_MESSAGES[this.#language()];
|
|
729
|
+
const raw = current[key] ?? this.#fallback(key);
|
|
730
|
+
return this.#interpolate(raw, params);
|
|
731
|
+
}
|
|
732
|
+
#fallback(key) {
|
|
733
|
+
const vi = SD_MESSAGES.vi[key];
|
|
734
|
+
if (vi !== undefined) {
|
|
735
|
+
this.#warnOnce(`[SdI18n] Missing key in ${this.#language()}: ${key} (fallback to vi)`);
|
|
736
|
+
return vi;
|
|
737
|
+
}
|
|
738
|
+
this.#warnOnce(`[SdI18n] Missing key: ${key}`);
|
|
739
|
+
return key;
|
|
740
|
+
}
|
|
741
|
+
#interpolate(raw, params) {
|
|
742
|
+
if (!params)
|
|
743
|
+
return raw;
|
|
744
|
+
return raw.replace(/\{(\w+)\}/g, (m, name) => (name in params ? String(params[name]) : m));
|
|
745
|
+
}
|
|
746
|
+
#warnOnce(msg) {
|
|
747
|
+
if (this.#warned.has(msg))
|
|
748
|
+
return;
|
|
749
|
+
this.#warned.add(msg);
|
|
750
|
+
console.warn(msg);
|
|
751
|
+
}
|
|
752
|
+
#resolveInitial() {
|
|
753
|
+
try {
|
|
754
|
+
const stored = localStorage.getItem(SD_I18N_STORAGE_KEY);
|
|
755
|
+
if (stored && SD_SUPPORTED_LANGUAGES.includes(stored))
|
|
756
|
+
return stored;
|
|
757
|
+
}
|
|
758
|
+
catch { /* ignore */ }
|
|
759
|
+
const configured = this.#config?.language;
|
|
760
|
+
if (configured && SD_SUPPORTED_LANGUAGES.includes(configured))
|
|
761
|
+
return configured;
|
|
762
|
+
return 'vi';
|
|
763
|
+
}
|
|
764
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: SdI18nService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
765
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: SdI18nService, providedIn: 'root' });
|
|
766
|
+
}
|
|
767
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: SdI18nService, decorators: [{
|
|
768
|
+
type: Injectable,
|
|
769
|
+
args: [{ providedIn: 'root' }]
|
|
770
|
+
}] });
|
|
771
|
+
|
|
772
|
+
class SdTPipe {
|
|
773
|
+
#i18n = inject(SdI18nService);
|
|
774
|
+
transform(key, params) {
|
|
775
|
+
return this.#i18n.t(key, params);
|
|
776
|
+
}
|
|
777
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: SdTPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
|
|
778
|
+
static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "19.2.21", ngImport: i0, type: SdTPipe, isStandalone: true, name: "sdT", pure: false });
|
|
779
|
+
}
|
|
780
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: SdTPipe, decorators: [{
|
|
781
|
+
type: Pipe,
|
|
782
|
+
args: [{ name: 'sdT', pure: false, standalone: true }]
|
|
783
|
+
}] });
|
|
784
|
+
|
|
785
|
+
/**
|
|
786
|
+
* Generated bundle index. Do not edit.
|
|
787
|
+
*/
|
|
788
|
+
|
|
789
|
+
export { SD_I18N_STORAGE_KEY, SD_MESSAGES, SD_SUPPORTED_LANGUAGES, SdI18nService, SdTPipe };
|
|
790
|
+
//# sourceMappingURL=sd-angular-core-i18n.mjs.map
|