feat: Enhance dataset management and improve frontend components
Some checks failed
CI Pipeline / japa-tests (push) Failing after 1m0s

- Added preloads 'allowed_extensions_mimetypes' and 'dependent_array_min_length' in adonisrc.ts
- Updated @symfony/webpack-encore from ^4.6.1 to ^5.0.1
- AdminuserController: Implemented pagination for 10 records in index method
- Enabled reviewers to reject datasets to editors with email notifications (DatasetController.ts)
- Submitter DatasetController: Files now loaded in ascending order (sort_order) in edit mode
- file.ts: Removed serialization of fileData due to browser issues
- Modified FileUpload.vue to mark already uploaded files as deleted
- Improved keyword search in SearchCategoryAutocomplete.vue
- Started development on Category.vue for submitters to categorize DDC
- Added new route /dataset/categorize in routes.ts
- Introduced 2 new rules in start/rules: allowed_extensions_mimetypes.ts and dependent_array_min_length.ts
- Performed npm updates
This commit is contained in:
Kaimbacher 2024-11-29 15:46:26 +01:00
parent 49bd96ee77
commit f67b736a88
23 changed files with 2392 additions and 2759 deletions

View file

@ -45,7 +45,7 @@ export default class AdminuserController {
// .filter(qs)
// .preload('focusInterests')
// .preload('role')
.paginate(page, 5);
.paginate(page, 10);
// var test = request.all();

View file

@ -279,7 +279,7 @@ export default class DatasetsController {
let emailStatusMessage = '';
if (sendMail == true) {
if (dataset.user.email && validRecipientEmail) {
if (dataset.editor.email && validRecipientEmail) {
try {
await mail.send((message) => {
message.to(dataset.editor.email).subject('Dataset Rejection Notification').html(`

View file

@ -216,7 +216,13 @@ export default class DatasetController {
authors: vine
.array(
vine.object({
email: vine.string().trim().maxLength(255).email().normalizeEmail().isUniquePerson({ table: 'persons', column: 'email', idField: 'id' }),
email: vine
.string()
.trim()
.maxLength(255)
.email()
.normalizeEmail()
.isUniquePerson({ table: 'persons', column: 'email', idField: 'id' }),
first_name: vine.string().trim().minLength(3).maxLength(255),
last_name: vine.string().trim().minLength(3).maxLength(255),
}),
@ -226,14 +232,20 @@ export default class DatasetController {
contributors: vine
.array(
vine.object({
email: vine.string().trim().maxLength(255).email().normalizeEmail().isUniquePerson({ table: 'persons', column: 'email', idField: 'id' }),
email: vine
.string()
.trim()
.maxLength(255)
.email()
.normalizeEmail()
.isUniquePerson({ table: 'persons', column: 'email', idField: 'id' }),
first_name: vine.string().trim().minLength(3).maxLength(255),
last_name: vine.string().trim().minLength(3).maxLength(255),
pivot_contributor_type: vine.enum(Object.keys(ContributorTypes)),
}),
)
.distinct('email')
.optional(),
.optional(),
project_id: vine.number().optional(),
});
@ -293,7 +305,13 @@ export default class DatasetController {
authors: vine
.array(
vine.object({
email: vine.string().trim().maxLength(255).email().normalizeEmail().isUniquePerson({ table: 'persons', column: 'email', idField: 'id' }),
email: vine
.string()
.trim()
.maxLength(255)
.email()
.normalizeEmail()
.isUniquePerson({ table: 'persons', column: 'email', idField: 'id' }),
first_name: vine.string().trim().minLength(3).maxLength(255),
last_name: vine.string().trim().minLength(3).maxLength(255),
}),
@ -303,14 +321,20 @@ export default class DatasetController {
contributors: vine
.array(
vine.object({
email: vine.string().trim().maxLength(255).email().normalizeEmail().isUniquePerson({ table: 'persons', column: 'email', idField: 'id' }),
email: vine
.string()
.trim()
.maxLength(255)
.email()
.normalizeEmail()
.isUniquePerson({ table: 'persons', column: 'email', idField: 'id' }),
first_name: vine.string().trim().minLength(3).maxLength(255),
last_name: vine.string().trim().minLength(3).maxLength(255),
pivot_contributor_type: vine.enum(Object.keys(ContributorTypes)),
}),
)
.distinct('email')
.optional(),
.optional(),
// third step
project_id: vine.number().optional(),
// embargo_date: schema.date.optional({ format: 'yyyy-MM-dd' }, [rules.after(10, 'days')]),
@ -791,7 +815,9 @@ export default class DatasetController {
builder.orderBy('id', 'asc').withCount('datasets');
})
.preload('references')
.preload('files');
.preload('files', (query) => {
query.orderBy('sort_order', 'asc'); // Sort by sort_order column
});
const dataset = await datasetQuery.firstOrFail();
const validStates = ['inprogress', 'rejected_editor'];
@ -961,6 +987,18 @@ export default class DatasetController {
}
}
// save coverage
const coverageData = request.input('coverage');
if (coverageData) {
if (coverageData.id) {
const coverage = await Coverage.findOrFail(coverageData.id);
coverage.merge(coverageData);
if (coverage.$isDirty) {
await coverage.useTransaction(trx).save();
}
}
}
// Save already existing files
const files = request.input('fileInputs', []);
for (const fileData of files) {
@ -1016,6 +1054,14 @@ export default class DatasetController {
}
}
const filesToDelete = request.input('filesToDelete', []);
for (const fileData of filesToDelete) {
if (fileData.id) {
const file = await File.findOrFail(fileData.id);
await file.useTransaction(trx).delete();
}
}
// save collection
// const collection: Collection | null = await Collection.query().where('id', 21).first();
// collection && (await dataset.useTransaction(trx).related('collections').attach([collection.id]));
@ -1036,6 +1082,10 @@ export default class DatasetController {
await trx.commit();
console.log('Dataset and related models created successfully');
session.flash('message', 'Dataset has been updated successfully');
// return response.redirect().toRoute('user.index');
return response.redirect().toRoute('dataset.edit', [dataset.id]);
} catch (error) {
if (trx !== null) {
await trx.rollback();
@ -1044,10 +1094,6 @@ export default class DatasetController {
// throw new ValidationException(true, { 'upload error': `failed to create dataset and related models. ${error}` });
throw error;
}
session.flash('message', 'Dataset has been updated successfully');
// return response.redirect().toRoute('user.index');
return response.redirect().back();
}
private extractVariableNameAndSortOrder(inputString: string): { clientFileName: string; sortOrder?: number } {