flameresttable 1.0.141 → 1.0.143

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "flameresttable",
3
- "version": "1.0.141",
3
+ "version": "1.0.143",
4
4
  "main": "./src/plugin.ts",
5
5
  "repository": {
6
6
  "type": "git",
@@ -8,7 +8,7 @@
8
8
  },
9
9
  "scripts": {
10
10
  "publishx": "npm --no-git-tag-version version patch && npm publish",
11
- "install/update": "npm i && npm update --save",
11
+ "install/update": "npm update --save",
12
12
  "dev": "vite"
13
13
  },
14
14
  "dependencies": {
@@ -4,6 +4,10 @@
4
4
  <slot name="header" />
5
5
 
6
6
  <v-card-text>
7
+ <!-- Глобальная ошибка сверху над всеми полями (500, 403, нет соединения) -->
8
+ <v-alert v-if="popupErrors.global" type="error" variant="tonal" class="mx-2 mb-4" density="compact" style="white-space: pre-line;">
9
+ {{ popupErrors.global }}
10
+ </v-alert>
7
11
 
8
12
  <div v-for="column in ColumnNames" v-show="Table.columns[column].Popup.isShow" :key="'c' + column"
9
13
  style="margin-bottom: 10px;">
@@ -114,22 +118,21 @@
114
118
 
115
119
 
116
120
 
117
- <div class="mx-2 my-1 text-red-600" v-if="(typeof popupErrors[column] !== 'undefined')">{{ popupErrors[column]
118
- }}</div>
121
+ <!-- Вывод ошибки валидации конкретного поля под ним -->
122
+ <div class="mx-2 my-1 text-red-600 text-xs font-medium" v-if="popupErrors.fields[column]">
123
+ {{ popupErrors.fields[column] }}
124
+ </div>
119
125
 
120
126
  </div>
121
127
  </v-card-text>
122
128
 
123
- <div class="text-red-600 mx-2 my-1" v-if="(typeof popupErrors['globalErrorStack'] !== 'undefined')">{{
124
- popupErrors['globalErrorStack'] }}</div>
125
-
126
129
 
127
130
  <v-card-actions>
128
- <v-btn color="grey" variant="text" @click="close">
131
+ <v-btn color="grey" variant="text" @click="close" :disabled="isSaving">
129
132
  Отмена
130
133
  </v-btn>
131
134
  <v-spacer></v-spacer>
132
- <v-btn color="blue-darken-1" variant="text" @click="SaveTable">
135
+ <v-btn color="blue-darken-1" variant="text" @click="SaveTable" :loading="isSaving" :disabled="isSaving">
133
136
  {{ Table.mode === 'add' ? 'Добавить' : 'Сохранить' }}
134
137
  </v-btn>
135
138
  </v-card-actions>
@@ -173,14 +176,31 @@ export default defineComponent({
173
176
  const isDialogVisible = ref(false);
174
177
  const ColumnNames = Object.keys(Table.columns);
175
178
 
176
- // Ошибки сохранения
177
- let popupErrors: { [key: string]: string } = reactive({});
179
+ // Ошибки сохранения в реактивной структуре.
180
+ // global - для общих ошибок (500, 403, отсутствие соединения и т.д.)
181
+ // fields - для ошибок валидации конкретных полей (422)
182
+ const popupErrors = reactive({
183
+ global: null as string | null,
184
+ fields: {} as { [key: string]: string }
185
+ });
186
+
187
+ // Индикатор процесса сохранения/добавления
188
+ const isSaving = ref(false);
189
+
190
+ // Функция для полной очистки ошибок перед операциями
191
+ const clearErrors = () => {
192
+ popupErrors.global = null;
193
+ popupErrors.fields = {};
194
+ };
178
195
 
179
196
  /**
180
197
  * Добавление новой записи
181
198
  */
182
199
  const showAdd = () => {
183
200
  Table.mode = 'add';
201
+
202
+ // Очищаем старые ошибки при открытии формы добавления
203
+ clearErrors();
184
204
 
185
205
  // Установим все поля в пустые значения
186
206
  ColumnNames.forEach(key => {
@@ -201,6 +221,9 @@ export default defineComponent({
201
221
  */
202
222
  const showEdit = async (row: any) => {
203
223
  Table.mode = 'edit';
224
+
225
+ // Очищаем старые ошибки при открытии формы редактирования
226
+ clearErrors();
204
227
 
205
228
  await Table.opts.Popup.load(row, Table as any);
206
229
 
@@ -227,7 +250,9 @@ export default defineComponent({
227
250
  isDialogVisible.value = false;
228
251
  }
229
252
 
253
+ // Сохранение таблицы с детальной обработкой ошибок
230
254
  const SaveTable = async () => {
255
+ isSaving.value = true;
231
256
 
232
257
  try {
233
258
  if (Table.mode === 'add') {
@@ -236,21 +261,69 @@ export default defineComponent({
236
261
  else {
237
262
  await Table.save()
238
263
  }
239
- popupErrors = {};
264
+ // Очищаем ошибки при успешном сохранении
265
+ clearErrors();
240
266
  }
241
267
  catch (ex: any) {
242
268
 
243
- for (const keyx in popupErrors)
244
- delete popupErrors[keyx];
245
-
246
- if (typeof ex.stack !== 'undefined' && typeof ex.message !== 'undefined') {
247
- popupErrors.globalErrorStack = ex.message;
269
+ // Очищаем ошибки перед записью новых
270
+ clearErrors();
271
+
272
+ // Обработка ошибок, пришедших от REST-клиента (BaseResponse)
273
+ if (ex && typeof ex === 'object' && 'ok' in ex && ex.ok === false) {
274
+ if (ex.status === 422) {
275
+ // Ошибки валидации полей Yii2
276
+ if (ex.errors && typeof ex.errors === 'object') {
277
+ popupErrors.fields = { ...ex.errors };
278
+ } else {
279
+ popupErrors.global = ex.message || 'Ошибка валидации полей';
280
+ }
281
+ } else {
282
+ // Другие ошибки сервера (500, 403, 404 и т.д.)
283
+ let errorMsg = '';
284
+ if (ex.status === 403) {
285
+ errorMsg = 'Доступ запрещен (403)';
286
+ } else if (ex.status === 500) {
287
+ errorMsg = 'Внутренняя ошибка сервера (500)';
288
+ } else {
289
+ errorMsg = `Ошибка сервера (${ex.status})`;
290
+ }
291
+
292
+ if (ex.message) {
293
+ errorMsg += `: ${ex.message}`;
294
+ }
295
+
296
+ // Если сервер вернул детальное сообщение об ошибке в errors
297
+ if (ex.errors) {
298
+ if (typeof ex.errors === 'string') {
299
+ errorMsg += `\n${ex.errors}`;
300
+ } else if (typeof ex.errors === 'object') {
301
+ if (ex.errors.message) {
302
+ errorMsg += `\n${ex.errors.message}`;
303
+ } else if (ex.errors.error) {
304
+ errorMsg += `\n${ex.errors.error}`;
305
+ } else {
306
+ errorMsg += `\n${JSON.stringify(ex.errors)}`;
307
+ }
308
+ }
309
+ }
310
+
311
+ popupErrors.global = errorMsg;
312
+ }
313
+ } else if (ex instanceof Error) {
314
+ // Сетевая ошибка (нет соединения) или JS-исклечение
315
+ popupErrors.global = ex.message || 'Произошла неизвестная ошибка';
316
+ } else if (typeof ex === 'string') {
317
+ popupErrors.global = ex;
318
+ } else {
319
+ popupErrors.global = 'Произошла неизвестная ошибка при сохранении';
248
320
  }
249
- else
250
- Object.assign(popupErrors, ex);
251
321
 
252
322
  return;
253
323
  }
324
+ finally {
325
+ isSaving.value = false;
326
+ }
254
327
 
255
328
  close();
256
329
 
@@ -283,6 +356,7 @@ export default defineComponent({
283
356
  SaveTable,
284
357
  fileUpdated,
285
358
  popupErrors,
359
+ isSaving,
286
360
  PopupTextSaved,
287
361
  close
288
362
  }