feat: Enhance dataset management and improve frontend components
Some checks failed
CI Pipeline / japa-tests (push) Failing after 1m0s
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:
parent
49bd96ee77
commit
f67b736a88
23 changed files with 2392 additions and 2759 deletions
|
@ -45,7 +45,7 @@ export default class AdminuserController {
|
|||
// .filter(qs)
|
||||
// .preload('focusInterests')
|
||||
// .preload('role')
|
||||
.paginate(page, 5);
|
||||
.paginate(page, 10);
|
||||
|
||||
// var test = request.all();
|
||||
|
||||
|
|
|
@ -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(`
|
||||
|
|
|
@ -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 } {
|
||||
|
|
|
@ -46,7 +46,12 @@ export default class Dataset extends DatasetExtension {
|
|||
@column({ columnName: 'creating_corporation' })
|
||||
public creating_corporation: string;
|
||||
|
||||
@column.dateTime({ columnName: 'embargo_date' })
|
||||
@column.dateTime({
|
||||
columnName: 'embargo_date',
|
||||
serialize: (value: Date | null) => {
|
||||
return value ? dayjs(value).format('YYYY-MM-DD') : value;
|
||||
},
|
||||
})
|
||||
public embargo_date: DateTime;
|
||||
|
||||
@column({})
|
||||
|
|
|
@ -123,25 +123,25 @@ export default class File extends BaseModel {
|
|||
|
||||
readonly webkitRelativePath: string = '';
|
||||
|
||||
@computed({
|
||||
serializeAs: 'fileData',
|
||||
})
|
||||
public get fileData(): string {
|
||||
try {
|
||||
const fileContent: Buffer = fs.readFileSync(this.filePath);
|
||||
// Create a Blob from the file content
|
||||
// const blob = new Blob([fileContent], { type: this.type }); // Adjust
|
||||
// let fileSrc = URL.createObjectURL(blob);
|
||||
// return fileSrc;
|
||||
// @computed({
|
||||
// serializeAs: 'fileData',
|
||||
// })
|
||||
// public get fileData(): string {
|
||||
// try {
|
||||
// const fileContent: Buffer = fs.readFileSync(this.filePath);
|
||||
// // Create a Blob from the file content
|
||||
// // const blob = new Blob([fileContent], { type: this.type }); // Adjust
|
||||
// // let fileSrc = URL.createObjectURL(blob);
|
||||
// // return fileSrc;
|
||||
|
||||
// create a JSON string that contains the data in the property "blob"
|
||||
const json = JSON.stringify({ blob: fileContent.toString('base64') });
|
||||
return json;
|
||||
} catch (err) {
|
||||
// console.error(`Error reading file: ${err}`);
|
||||
return '';
|
||||
}
|
||||
}
|
||||
// // create a JSON string that contains the data in the property "blob"
|
||||
// const json = JSON.stringify({ blob: fileContent.toString('base64') });
|
||||
// return json;
|
||||
// } catch (err) {
|
||||
// // console.error(`Error reading file: ${err}`);
|
||||
// return '';
|
||||
// }
|
||||
// }
|
||||
|
||||
public async createHashValues(trx?: TransactionClientContract) {
|
||||
const hashtypes: string[] = ['md5', 'sha512'];
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
import vine, { SimpleMessagesProvider } from '@vinejs/vine';
|
||||
import { TitleTypes, DescriptionTypes, ContributorTypes, ReferenceIdentifierTypes, RelationTypes } from '#contracts/enums';
|
||||
import dayjs from 'dayjs';
|
||||
import MimeType from '#models/mime_type';
|
||||
// import MimeType from '#models/mime_type';
|
||||
|
||||
const enabledExtensions = await MimeType.query().select('file_extension').where('enabled', true).exec();
|
||||
const extensions = enabledExtensions
|
||||
.map((extension) => {
|
||||
return extension.file_extension.split('|');
|
||||
})
|
||||
.flat();
|
||||
// const enabledExtensions = await MimeType.query().select('file_extension').where('enabled', true).exec();
|
||||
// const extensions = enabledExtensions
|
||||
// .map((extension) => {
|
||||
// return extension.file_extension.split('|');
|
||||
// })
|
||||
// .flat();
|
||||
|
||||
/**
|
||||
* Validates the dataset's creation action
|
||||
|
@ -137,8 +137,9 @@ export const createDatasetValidator = vine.compile(
|
|||
vine
|
||||
.myfile({
|
||||
size: '512mb',
|
||||
extnames: extensions,
|
||||
//extnames: extensions,
|
||||
})
|
||||
.allowedMimetypeExtensions()
|
||||
.filenameLength({ clientNameSizeLimit: 100 })
|
||||
.fileScan({ removeInfected: true }),
|
||||
)
|
||||
|
@ -267,13 +268,25 @@ export const updateDatasetValidator = vine.compile(
|
|||
.minLength(3)
|
||||
.distinct('value'),
|
||||
// last step
|
||||
files: vine.array(
|
||||
vine.myfile({
|
||||
size: '512mb',
|
||||
extnames: extensions,
|
||||
}),
|
||||
files: vine
|
||||
.array(
|
||||
vine
|
||||
.myfile({
|
||||
size: '512mb',
|
||||
//extnames: extensions,
|
||||
})
|
||||
.allowedMimetypeExtensions()
|
||||
.filenameLength({ clientNameSizeLimit: 100 })
|
||||
.fileScan({ removeInfected: true }),
|
||||
).dependentArrayMinLength({ dependentArray: 'fileInputs', min: 1}),
|
||||
fileInputs: vine
|
||||
.array(
|
||||
vine
|
||||
.object({
|
||||
label: vine.string().trim().maxLength(100),
|
||||
//extnames: extensions,
|
||||
})
|
||||
),
|
||||
// .minLength(1),
|
||||
}),
|
||||
);
|
||||
|
||||
|
|
Loading…
Add table
editor.link_modal.header
Reference in a new issue