diff --git a/app/Controllers/Http/Submitter/DatasetController.ts b/app/Controllers/Http/Submitter/DatasetController.ts index e683e7d..e6018cc 100644 --- a/app/Controllers/Http/Submitter/DatasetController.ts +++ b/app/Controllers/Http/Submitter/DatasetController.ts @@ -926,7 +926,7 @@ export default class DatasetController { // throw new GeneralException(trans('exceptions.publish.release.update_error')); } - public async edit({ request, inertia, response }: HttpContext) { + public async edit({ request, inertia, response, auth }: HttpContext) { const id = request.param('id'); const datasetQuery = Dataset.query().where('id', id); datasetQuery @@ -1015,6 +1015,10 @@ export default class DatasetController { referenceIdentifierTypes: Object.entries(ReferenceIdentifierTypes).map(([key, value]) => ({ value: key, label: value })), relationTypes: Object.entries(RelationTypes).map(([key, value]) => ({ value: key, label: value })), doctypes: DatasetTypes, + can: { + edit: await auth.user?.can(['dataset-edit']), + delete: await auth.user?.can(['dataset-delete']), + }, }); } diff --git a/resources/js/Components/TableKeywords.vue b/resources/js/Components/TableKeywords.vue index d11108a..fbe979c 100644 --- a/resources/js/Components/TableKeywords.vue +++ b/resources/js/Components/TableKeywords.vue @@ -154,7 +154,7 @@ const isKeywordReadOnly = (item: Subject) => {
{{ errors[`subjects.${index}.type`].join(', ') }} diff --git a/resources/js/Pages/Submitter/Dataset/Edit.vue b/resources/js/Pages/Submitter/Dataset/Edit.vue index d7d63bc..8a658dd 100644 --- a/resources/js/Pages/Submitter/Dataset/Edit.vue +++ b/resources/js/Pages/Submitter/Dataset/Edit.vue @@ -468,15 +468,6 @@
- - - -
- - @@ -570,7 +551,9 @@ import { mdiBookOpenPageVariant, mdiEarthPlus, mdiAlertBoxOutline, - mdiRestore + mdiRestore, + mdiLockOpen, + mdiDisc } from '@mdi/js'; import { notify } from '@/notiwind'; import NotificationBar from '@/Components/NotificationBar.vue'; @@ -624,8 +607,10 @@ const props = defineProps({ type: Object, default: () => ({}), }, - - + can: { + type: Object, + default: () => ({}), + }, }); const flash: ComputedRef = computed(() => { @@ -650,31 +635,70 @@ const fitBounds: LatLngBoundsExpression = [ ]; const mapId = 'test'; -// const downloadFile = async (id: string): Promise => { -// const response = await axios.get(`/api/download/${id}`, { -// responseType: 'blob', -// }); -// const url = URL.createObjectURL(response.data); -// setTimeout(() => { -// URL.revokeObjectURL(url); -// }, 1000); -// return url; -// }; - -// for (const file of props.dataset.files) { -// // console.log(`${file.name} path is ${file.filePath} here.`); -// file.fileSrc = ref(""); -// // downloadFile(file.id).then((value: string) => { -// // file.fileSrc = ref(value); -// // form = useForm(props.dataset as Dataset); -// // }); -// } props.dataset.filesToDelete = []; props.dataset.subjectsToDelete = []; props.dataset.referencesToDelete = []; let form = useForm(props.dataset as Dataset); +// Add this computed property to the script section +const hasUnsavedChanges = computed(() => { + // Check if form is processing + if (form.processing) return true; + + // Compare current form state with original dataset + // Check basic properties + if (form.language !== props.dataset.language) return true; + if (form.type !== props.dataset.type) return true; + if (form.project_id !== props.dataset.project_id) return true; + if (form.embargo_date !== props.dataset.embargo_date) return true; + + // Check if licenses have changed + const originalLicenses = Array.isArray(props.dataset.licenses) + ? props.dataset.licenses.map(l => typeof l === 'object' ? l.id.toString() : l) + : []; + const currentLicenses = Array.isArray(form.licenses) + ? form.licenses.map(l => typeof l === 'object' ? l.id.toString() : l) + : []; + if (JSON.stringify(currentLicenses) !== JSON.stringify(originalLicenses)) return true; + + // Check if titles have changed + if (JSON.stringify(form.titles) !== JSON.stringify(props.dataset.titles)) return true; + + // Check if descriptions have changed + if (JSON.stringify(form.descriptions) !== JSON.stringify(props.dataset.descriptions)) return true; + + // Check if authors have changed + if (JSON.stringify(form.authors) !== JSON.stringify(props.dataset.authors)) return true; + + // Check if contributors have changed + if (JSON.stringify(form.contributors) !== JSON.stringify(props.dataset.contributors)) return true; + + // Check if subjects have changed + // if (JSON.stringify(form.subjects) !== JSON.stringify(props.dataset.subjects)) return true; + let test = JSON.stringify(form.subjects); + let test2 = JSON.stringify(props.dataset.subjects); + if (test !== test2) { + return true; + } + + // Check if references have changed + if (JSON.stringify(form.references) !== JSON.stringify(props.dataset.references)) return true; + + // Check if coverage has changed + if (JSON.stringify(form.coverage) !== JSON.stringify(props.dataset.coverage)) return true; + + // Check if files have changed + if (form.files?.length !== props.dataset.files?.length) return true; + if (form.filesToDelete?.length > 0) return true; + + // Check if there are new files to upload + if (form.files?.some(file => !file.id)) return true; + + // No changes detected + return false; +}); + const submit = async (): Promise => { let route = stardust.route('dataset.update', [props.dataset.id]); diff --git a/start/rules/array_contains_types.ts b/start/rules/array_contains_types.ts index fdb05ed..1fe5994 100644 --- a/start/rules/array_contains_types.ts +++ b/start/rules/array_contains_types.ts @@ -44,20 +44,20 @@ async function arrayContainsTypes(value: unknown, options: Options, field: Field if (field.getFieldPath() === 'titles') { // For titles we expect one main and minimum one translated title. if (!hasTypeA && !hasTypeB) { - errorMessage = 'For titles, define one main title and minimum one translated title.'; + errorMessage = 'For titles, define at least one main title and at least one Translated title as MAIN TITLE.'; } else if (!hasTypeA) { - errorMessage = 'For titles, define one main title.'; + errorMessage = 'For titles, define at least one main title.'; } else if (!hasTypeB) { - errorMessage = 'For titles, define minimum one translated title.'; + errorMessage = 'For Titles, define at least one Translated title as MAIN TITLE.'; } } else if (field.getFieldPath() === 'descriptions') { // For descriptions we expect one abstracts description and minimum one translated description. if (!hasTypeA && !hasTypeB) { - errorMessage = 'For descriptions, define one abstract description and minimum one translated description.'; + errorMessage = 'For descriptions, define at least one abstract and at least one Translated description as MAIN ABSTRACT.'; } else if (!hasTypeA) { - errorMessage = 'For descriptions, define one abstract description.'; + errorMessage = 'For descriptions, define at least one abstract.'; } else if (!hasTypeB) { - errorMessage = 'For descriptions, define minimum one translated description.'; + errorMessage = 'For Descriptions, define at least one Translated description as MAIN ABSTRACT.'; } }