// ==================================================================== // FILE: composables/useDatasetFormSubmission.ts // ==================================================================== import { Ref } from 'vue'; import type { Dataset, License } from '@/Dataset'; import { InertiaForm } from '@inertiajs/vue3'; import { stardust } from '@eidellev/adonis-stardust/client'; import { notify } from '@/notiwind'; interface SubmissionOptions { onSuccess?: (updatedDataset: Dataset) => void; onError?: (errors: any) => void; showNotification?: boolean; } export function useDatasetFormSubmission( form: InertiaForm, originalDataset: Ref ) { /** * Check if object has id attribute (type guard) */ const hasIdAttribute = (obj: License | number): obj is License => { return typeof obj === 'object' && 'id' in obj; }; /** * Transform licenses for submission */ const transformLicenses = (): string[] => { return form.licenses.map((obj) => { if (hasIdAttribute(obj)) { return obj.id.toString(); } return String(obj); }); }; /** * Validate form before submission */ const validateForm = (): { valid: boolean; errors: string[] } => { const errors: string[] = []; // Required field validations if (!form.language) { errors.push('Language is required'); } if (!form.type) { errors.push('Dataset type is required'); } if (!form.creating_corporation) { errors.push('Creating corporation is required'); } if (!form.titles || !form.titles[0]?.value) { errors.push('Main title is required'); } if (!form.descriptions || !form.descriptions[0]?.value) { errors.push('Main abstract is required'); } return { valid: errors.length === 0, errors, }; }; /** * Handle successful submission */ const handleSubmitSuccess = ( updatedDataset: Dataset, showNotification: boolean = true ) => { // Clear deletion arrays if (updatedDataset.subjectsToDelete) { updatedDataset.subjectsToDelete = []; } if (updatedDataset.referencesToDelete) { updatedDataset.referencesToDelete = []; } // Update form with fresh data from server Object.keys(updatedDataset).forEach((key) => { if (key !== 'licenses' && key in form) { form[key] = updatedDataset[key]; } }); // Clear form errors form.clearErrors(); // Update original dataset reference originalDataset.value = JSON.parse(JSON.stringify(updatedDataset)); // Show success notification if (showNotification) { notify( { type: 'success', title: 'Success', text: 'Dataset updated successfully', }, 4000, ); } }; /** * Handle submission errors */ const handleSubmitError = (errors: any) => { console.error('Submission errors:', errors); notify( { type: 'error', title: 'Error', text: 'Failed to update dataset. Please check the form for errors.', }, 5000, ); }; /** * Submit form with auto-save behavior */ const submitWithAutoSave = async ( options: SubmissionOptions = {} ): Promise => { try { const route = stardust.route('editor.dataset.update', [form.id]); const licenses = transformLicenses(); await form .transform((data) => ({ ...data, licenses, rights: 'true', })) .put(route, { onSuccess: (page) => { const updatedDataset = page.props.dataset || form.data(); handleSubmitSuccess( updatedDataset, options.showNotification ?? true ); if (options.onSuccess) { options.onSuccess(updatedDataset); } }, onError: (errors) => { handleSubmitError(errors); if (options.onError) { options.onError(errors); } }, }); } catch (error) { console.error('Unexpected error during submission:', error); notify( { type: 'error', title: 'Error', text: 'An unexpected error occurred. Please try again.', }, 5000, ); } }; /** * Standard submit with validation */ const submit = async ( options: SubmissionOptions = {} ): Promise => { // Validate form first const validation = validateForm(); if (!validation.valid) { notify( { type: 'error', title: 'Validation Error', text: validation.errors.join(', '), }, 5000, ); return; } await submitWithAutoSave({ ...options, showNotification: true, }); }; /** * Silent submit without notification (for auto-save) */ const submitSilently = async (): Promise => { await submitWithAutoSave({ showNotification: false, }); }; return { submit, submitWithAutoSave, submitSilently, validateForm, transformLicenses, }; }