|
121 | 121 | </div> |
122 | 122 | </div> |
123 | 123 |
|
124 | | - <div v-if="saveError" class="rounded-lg border border-red-200 bg-red-50 px-4 py-3 text-sm text-red-700"> |
| 124 | + <div v-if="saveErrors.length" class="rounded-lg border border-red-200 bg-red-50 px-4 py-3 text-sm text-red-700"> |
| 125 | + <p class="font-medium">Please fix the following fields:</p> |
| 126 | + <ul class="mt-1 list-disc pl-5 space-y-1"> |
| 127 | + <li v-for="errorItem in saveErrors" :key="errorItem">{{ errorItem }}</li> |
| 128 | + </ul> |
| 129 | + </div> |
| 130 | + <div v-else-if="saveError" class="rounded-lg border border-red-200 bg-red-50 px-4 py-3 text-sm text-red-700"> |
125 | 131 | {{ saveError }} |
126 | 132 | </div> |
127 | 133 | <div v-if="saveSuccess" class="rounded-lg border border-green-200 bg-green-50 px-4 py-3 text-sm text-green-700"> |
@@ -164,6 +170,7 @@ const isLoading = ref(false) |
164 | 170 | const loadError = ref('') |
165 | 171 | const isSaving = ref(false) |
166 | 172 | const saveError = ref('') |
| 173 | +const saveErrors = ref([]) |
167 | 174 | const saveSuccess = ref('') |
168 | 175 | const form = ref({ |
169 | 176 | title: '', |
@@ -240,19 +247,63 @@ const handleFileChange = (event) => { |
240 | 247 | form.value.file = file || null |
241 | 248 | } |
242 | 249 |
|
| 250 | +const validationFieldLabels = { |
| 251 | + title: 'Title', |
| 252 | + content: 'Content', |
| 253 | + text: 'Text version', |
| 254 | + file: 'Template file', |
| 255 | + list_order: 'List order', |
| 256 | + check_links: 'Check links', |
| 257 | + check_images: 'Check images', |
| 258 | + check_external_images: 'Check external images' |
| 259 | +} |
| 260 | +
|
| 261 | +const normalizeFieldName = (fieldPath = '') => { |
| 262 | + if (validationFieldLabels[fieldPath]) return validationFieldLabels[fieldPath] |
| 263 | +
|
| 264 | + const fallback = String(fieldPath) |
| 265 | + .split('.') |
| 266 | + .pop() |
| 267 | + ?.replace(/\[\d+]/g, '') |
| 268 | + ?.replace(/_/g, ' ') |
| 269 | + ?.replace(/([a-z])([A-Z])/g, '$1 $2') |
| 270 | + ?.trim() |
| 271 | +
|
| 272 | + if (!fallback) return 'Field' |
| 273 | + return fallback.charAt(0).toUpperCase() + fallback.slice(1) |
| 274 | +} |
| 275 | +
|
| 276 | +const formatValidationErrors = (error) => { |
| 277 | + const responseData = error?.responseData |
| 278 | + const messages = [] |
| 279 | +
|
| 280 | + if (responseData && typeof responseData === 'object' && !Array.isArray(responseData)) { |
| 281 | + Object.entries(responseData).forEach(([field, rawMessage]) => { |
| 282 | + if (!rawMessage) return |
| 283 | + const text = Array.isArray(rawMessage) ? rawMessage.join(' ') : String(rawMessage) |
| 284 | + messages.push(`${normalizeFieldName(field)}: ${text}`) |
| 285 | + }) |
| 286 | + } |
| 287 | +
|
| 288 | + return [...new Set(messages)] |
| 289 | +} |
| 290 | +
|
243 | 291 | const saveTemplate = async () => { |
244 | 292 | if (!isCreateMode.value && (!Number.isFinite(templateId.value) || templateId.value <= 0)) { |
245 | 293 | saveError.value = 'Template ID is invalid.' |
| 294 | + saveErrors.value = [] |
246 | 295 | return |
247 | 296 | } |
248 | 297 |
|
249 | 298 | if (!form.value.title) { |
250 | 299 | saveError.value = 'Title is required.' |
| 300 | + saveErrors.value = [] |
251 | 301 | return |
252 | 302 | } |
253 | 303 |
|
254 | 304 | isSaving.value = true |
255 | 305 | saveError.value = '' |
| 306 | + saveErrors.value = [] |
256 | 307 | saveSuccess.value = '' |
257 | 308 |
|
258 | 309 | try { |
@@ -292,7 +343,14 @@ const saveTemplate = async () => { |
292 | 343 | saveSuccess.value = 'Template updated successfully.' |
293 | 344 | } catch (error) { |
294 | 345 | console.error('Failed to save template:', error) |
295 | | - saveError.value = error?.message || 'Failed to save template.' |
| 346 | + const formattedErrors = formatValidationErrors(error) |
| 347 | + if (formattedErrors.length > 0) { |
| 348 | + saveErrors.value = formattedErrors |
| 349 | + saveError.value = '' |
| 350 | + } else { |
| 351 | + saveError.value = error?.message || 'Failed to save template.' |
| 352 | + saveErrors.value = [] |
| 353 | + } |
296 | 354 | } finally { |
297 | 355 | isSaving.value = false |
298 | 356 | } |
|
0 commit comments