- added views and controller coder for reviewer role - added program logic for publishing a dataset by editor - added reviewer menu - adapted routes.ts for additional routes
This commit is contained in:
parent
c70fa4a0d8
commit
18635f77b3
17 changed files with 1224 additions and 393 deletions
|
@ -9,6 +9,7 @@ import { readFileSync } from 'fs';
|
|||
import { transform } from 'saxon-js';
|
||||
import type { ModelQueryBuilderContract } from '@ioc:Adonis/Lucid/Orm';
|
||||
import { schema, CustomMessages } from '@ioc:Adonis/Core/Validator';
|
||||
import { DateTime } from 'luxon';
|
||||
|
||||
// Create a new instance of the client
|
||||
const client = new Client({ node: 'http://localhost:9200' }); // replace with your OpenSearch endpoint
|
||||
|
@ -19,6 +20,7 @@ export default class DatasetsController {
|
|||
// 'required': '{{ field }} is required',
|
||||
// 'licenses.minLength': 'at least {{ options.minLength }} permission must be defined',
|
||||
'reviewer_id.required': 'reviewer_id must be defined',
|
||||
'publisher_name.required': 'publisher name must be defined',
|
||||
};
|
||||
|
||||
constructor() {
|
||||
|
@ -73,11 +75,11 @@ export default class DatasetsController {
|
|||
datasets: myDatasets.serialize(),
|
||||
filters: request.all(),
|
||||
can: {
|
||||
// create: await auth.user?.can(['dataset-submit']),
|
||||
receive: await auth.user?.can(['dataset-receive']),
|
||||
approve: await auth.user?.can(['dataset-approve']),
|
||||
edit: await auth.user?.can(['dataset-editor-edit']),
|
||||
edit: await auth.user?.can(['dataset-editor-update']),
|
||||
delete: await auth.user?.can(['dataset-editor-delete']),
|
||||
publish: await auth.user?.can(['dataset-publish']),
|
||||
},
|
||||
});
|
||||
}
|
||||
|
@ -211,6 +213,70 @@ export default class DatasetsController {
|
|||
}
|
||||
}
|
||||
|
||||
public async publish({ request, inertia, response }) {
|
||||
const id = request.param('id');
|
||||
|
||||
const dataset = await Dataset.query()
|
||||
.where('id', id)
|
||||
.preload('titles')
|
||||
.preload('authors')
|
||||
// .preload('persons', (builder) => {
|
||||
// builder.wherePivot('role', 'author')
|
||||
// })
|
||||
.firstOrFail();
|
||||
|
||||
const validStates = ['reviewed'];
|
||||
if (!validStates.includes(dataset.server_state)) {
|
||||
// session.flash('errors', 'Invalid server state!');
|
||||
return response
|
||||
.flash(
|
||||
'warning',
|
||||
`Invalid server state. Dataset with id ${id} cannot be published. Datset has server state ${dataset.server_state}.`,
|
||||
)
|
||||
.redirect()
|
||||
.back();
|
||||
}
|
||||
|
||||
return inertia.render('Editor/Dataset/Publish', {
|
||||
dataset,
|
||||
});
|
||||
}
|
||||
|
||||
public async publishUpdate({ request, response }) {
|
||||
const publishDatasetSchema = schema.create({
|
||||
publisher_name: schema.string({ trim: true }),
|
||||
});
|
||||
try {
|
||||
await request.validate({ schema: publishDatasetSchema, messages: this.messages });
|
||||
} catch (error) {
|
||||
// return response.badRequest(error.messages);
|
||||
throw error;
|
||||
}
|
||||
const id = request.param('id');
|
||||
const dataset = await Dataset.findOrFail(id);
|
||||
|
||||
// let test = await Dataset.getMax('publish_id');
|
||||
// const maxPublishId = await Database.from('documents').max('publish_id as max_publish_id').first();
|
||||
// const max = maxPublishId.max_publish_id;
|
||||
const max = await Dataset.getMax('publish_id');
|
||||
let publish_id = 0;
|
||||
if (max != null) {
|
||||
publish_id = max + 1;
|
||||
} else {
|
||||
publish_id = publish_id + 1;
|
||||
}
|
||||
dataset.publish_id = publish_id;
|
||||
dataset.server_state = 'published';
|
||||
dataset.server_date_published = DateTime.now();
|
||||
|
||||
const publisherName = request.input('publisher_name', 'Tethys');
|
||||
dataset.publisher_name = publisherName;
|
||||
|
||||
if (await dataset.save()) {
|
||||
return response.toRoute('editor.dataset.list').flash('message', 'You have successfully published the dataset!');
|
||||
}
|
||||
}
|
||||
|
||||
public async create({}: HttpContextContract) {}
|
||||
|
||||
public async store({}: HttpContextContract) {}
|
||||
|
|
267
app/Controllers/Http/Reviewer/DatasetController.ts
Normal file
267
app/Controllers/Http/Reviewer/DatasetController.ts
Normal file
|
@ -0,0 +1,267 @@
|
|||
import type { HttpContextContract } from '@ioc:Adonis/Core/HttpContext';
|
||||
import User from 'App/Models/User';
|
||||
import Dataset from 'App/Models/Dataset';
|
||||
import type { ModelQueryBuilderContract } from '@ioc:Adonis/Lucid/Orm';
|
||||
import Field from 'App/Library/Field';
|
||||
import BaseModel from 'App/Models/BaseModel';
|
||||
import { DateTime } from 'luxon';
|
||||
import { schema, CustomMessages, rules } from '@ioc:Adonis/Core/Validator';
|
||||
|
||||
export default class DatasetsController {
|
||||
public async index({ auth, request, inertia }: HttpContextContract) {
|
||||
const user = (await User.find(auth.user?.id)) as User;
|
||||
const page = request.input('page', 1);
|
||||
let datasets: ModelQueryBuilderContract<typeof Dataset, Dataset> = Dataset.query();
|
||||
|
||||
// if (request.input('search')) {
|
||||
// // users = users.whereRaw('name like %?%', [request.input('search')])
|
||||
// const searchTerm = request.input('search');
|
||||
// datasets.where('name', 'ilike', `%${searchTerm}%`);
|
||||
// }
|
||||
|
||||
if (request.input('sort')) {
|
||||
type SortOrder = 'asc' | 'desc' | undefined;
|
||||
let attribute = request.input('sort');
|
||||
let sortOrder: SortOrder = 'asc';
|
||||
|
||||
if (attribute.substr(0, 1) === '-') {
|
||||
sortOrder = 'desc';
|
||||
// attribute = substr(attribute, 1);
|
||||
attribute = attribute.substr(1);
|
||||
}
|
||||
datasets.orderBy(attribute, sortOrder);
|
||||
} else {
|
||||
// users.orderBy('created_at', 'desc');
|
||||
datasets.orderBy('id', 'asc');
|
||||
}
|
||||
|
||||
// const users = await User.query().orderBy('login').paginate(page, limit);
|
||||
const myDatasets = await datasets
|
||||
.where('server_state', 'approved')
|
||||
.where('reviewer_id', user.id)
|
||||
|
||||
.preload('titles')
|
||||
.preload('user', (query) => query.select('id', 'login'))
|
||||
.preload('editor', (query) => query.select('id', 'login'))
|
||||
.paginate(page, 10);
|
||||
|
||||
return inertia.render('Reviewer/Dataset/Index', {
|
||||
datasets: myDatasets.serialize(),
|
||||
filters: request.all(),
|
||||
can: {
|
||||
review: await auth.user?.can(['dataset-review']),
|
||||
reject: await auth.user?.can(['dataset-review-reject']),
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
public async review({ request, inertia, response }: HttpContextContract) {
|
||||
const id = request.param('id');
|
||||
const dataset = await Dataset.query()
|
||||
.where('id', id)
|
||||
// .preload('titles')
|
||||
// .preload('descriptions')
|
||||
.preload('user', (builder) => {
|
||||
builder.select('id', 'login');
|
||||
})
|
||||
.firstOrFail();
|
||||
|
||||
const validStates = ['approved'];
|
||||
if (!validStates.includes(dataset.server_state)) {
|
||||
// session.flash('errors', 'Invalid server state!');
|
||||
return response
|
||||
.flash(
|
||||
'warning',
|
||||
`Invalid server state. Dataset with id ${id} cannot be reviewed. Datset has server state ${dataset.server_state}.`,
|
||||
)
|
||||
.redirect()
|
||||
.toRoute('reviewer.dataset.list');
|
||||
}
|
||||
|
||||
const fieldnames: Array<string> = await dataset.describe();
|
||||
const fields = {};
|
||||
for (const fieldName of fieldnames) {
|
||||
const field: Field = dataset.getField(fieldName) as Field;
|
||||
const modelClass = field.getValueModelClass();
|
||||
let fieldValues = field.getValue();
|
||||
let value = '';
|
||||
|
||||
if (fieldValues === null || fieldValues == undefined) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (modelClass === null) {
|
||||
if (typeof fieldValues === 'number') {
|
||||
// If the field values are a number, use them as is
|
||||
value = fieldValues.toString();
|
||||
} else {
|
||||
// If the field values are not a number, use the replace() function to remove non-printable characters
|
||||
value = fieldValues.replace(/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]/g, '\xEF\xBF\xBD ');
|
||||
}
|
||||
} else {
|
||||
if (!Array.isArray(fieldValues)) {
|
||||
fieldValues = [fieldValues];
|
||||
}
|
||||
|
||||
for (const fieldValue of fieldValues) {
|
||||
if (fieldValue === null) {
|
||||
continue;
|
||||
}
|
||||
if (modelClass.prototype instanceof BaseModel) {
|
||||
// this.mapModelAttributes(fieldValue, childNode);
|
||||
value = '<ul>';
|
||||
Object.keys(fieldValue).forEach((prop) => {
|
||||
let modelValue = fieldValue[prop];
|
||||
// console.log(`${prop}: ${value}`);
|
||||
if (modelValue != null) {
|
||||
if (modelValue instanceof DateTime) {
|
||||
modelValue = modelValue.toFormat('yyyy-MM-dd HH:mm:ss').trim();
|
||||
} else {
|
||||
modelValue = modelValue.toString().trim();
|
||||
}
|
||||
|
||||
// Replace invalid XML-1.0-Characters by UTF-8 replacement character.
|
||||
modelValue = modelValue.replace(/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]/g, '\xEF\xBF\xBD ');
|
||||
|
||||
value = value + '<li>' + prop + ' : ' + modelValue + '</li>';
|
||||
}
|
||||
});
|
||||
value = value + '</ul>';
|
||||
} else if (modelClass instanceof DateTime) {
|
||||
// console.log('Value is a luxon date');
|
||||
// this.mapDateAttributes(fieldValue, childNode);
|
||||
value = value + ' Year ' + modelClass.year.toString();
|
||||
value = value + ' Month ' + modelClass.month.toString();
|
||||
value = value + ' Day ' + modelClass.day.toString();
|
||||
value = value + ' Hour ' + modelClass.hour.toString();
|
||||
value = value + ' Minute ' + modelClass.minute.toString();
|
||||
value = value + ' Second ' + modelClass.second.toString();
|
||||
value = value + ' UnixTimestamp ' + modelClass.toUnixInteger().toString();
|
||||
let zoneName = modelClass.zoneName ? modelClass.zoneName : '';
|
||||
value = value + ' Timezone ' + zoneName;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (value != '') {
|
||||
fields[fieldName] = value;
|
||||
}
|
||||
}
|
||||
|
||||
return inertia.render('Reviewer/Dataset/Review', {
|
||||
dataset,
|
||||
fields: fields,
|
||||
});
|
||||
}
|
||||
|
||||
public async reviewUpdate({ request, response }) {
|
||||
const id = request.param('id');
|
||||
// const { id } = params;
|
||||
const dataset = await Dataset.findOrFail(id);
|
||||
|
||||
const validStates = ['approved'];
|
||||
if (!validStates.includes(dataset.server_state)) {
|
||||
// throw new Error('Invalid server state!');
|
||||
// return response.flash('warning', 'Invalid server state. Dataset cannot be released to editor').redirect().back();
|
||||
return response
|
||||
.flash(
|
||||
'warning',
|
||||
`Invalid server state. Dataset with id ${id} cannot be reviewed. Datset has server state ${dataset.server_state}.`,
|
||||
)
|
||||
.redirect()
|
||||
.toRoute('reviewer.dataset.list');
|
||||
}
|
||||
|
||||
dataset.server_state = 'reviewed';
|
||||
|
||||
try {
|
||||
// await dataset.related('editor').associate(user); // speichert schon ab
|
||||
await dataset.save();
|
||||
return response.toRoute('reviewer.dataset.list').flash('message', `You have successfully reviewed dataset ${dataset.id}!`);
|
||||
} catch (error) {
|
||||
// Handle any errors
|
||||
console.error(error);
|
||||
return response.status(500).json({ error: 'An error occurred while reviewing the data.' });
|
||||
}
|
||||
}
|
||||
|
||||
public async reject({ request, inertia, response }: HttpContextContract) {
|
||||
const id = request.param('id');
|
||||
const dataset = await Dataset.query()
|
||||
.where('id', id)
|
||||
// .preload('titles')
|
||||
// .preload('descriptions')
|
||||
.preload('user', (builder) => {
|
||||
builder.select('id', 'login');
|
||||
})
|
||||
.firstOrFail();
|
||||
|
||||
const validStates = ['approved'];
|
||||
if (!validStates.includes(dataset.server_state)) {
|
||||
// session.flash('errors', 'Invalid server state!');
|
||||
return response
|
||||
.flash(
|
||||
'warning',
|
||||
`Invalid server state. Dataset with id ${id} cannot be rejected. Datset has server state ${dataset.server_state}.`,
|
||||
)
|
||||
.redirect()
|
||||
.toRoute('reviewer.dataset.list');
|
||||
}
|
||||
|
||||
return inertia.render('Reviewer/Dataset/Reject', {
|
||||
dataset,
|
||||
});
|
||||
}
|
||||
|
||||
public async rejectUpdate({ request, response }) {
|
||||
const id = request.param('id');
|
||||
const dataset = await Dataset.query()
|
||||
.where('id', id)
|
||||
.preload('editor', (builder) => {
|
||||
builder.select('id', 'login');
|
||||
})
|
||||
.firstOrFail();
|
||||
|
||||
const newSchema = schema.create({
|
||||
server_state: schema.string({ trim: true }),
|
||||
reject_reviewer_note: schema.string({ trim: true }, [rules.minLength(10), rules.maxLength(500)]),
|
||||
});
|
||||
|
||||
try {
|
||||
await request.validate({ schema: newSchema });
|
||||
} catch (error) {
|
||||
// return response.badRequest(error.messages);
|
||||
throw error;
|
||||
}
|
||||
|
||||
const validStates = ['approved'];
|
||||
if (!validStates.includes(dataset.server_state)) {
|
||||
// throw new Error('Invalid server state!');
|
||||
// return response.flash('warning', 'Invalid server state. Dataset cannot be released to editor').redirect().back();
|
||||
return response
|
||||
.flash(
|
||||
'warning',
|
||||
`Invalid server state. Dataset with id ${id} cannot be rejected. Datset has server state ${dataset.server_state}.`,
|
||||
)
|
||||
.redirect()
|
||||
.toRoute('reviewer.dataset.list');
|
||||
}
|
||||
|
||||
// dataset.server_state = 'reviewed';
|
||||
dataset.server_state = 'rejected_reviewer';
|
||||
const rejectReviewerNote = request.input('reject_reviewer_note', '');
|
||||
dataset.reject_reviewer_note = rejectReviewerNote;
|
||||
|
||||
try {
|
||||
// await dataset.related('editor').associate(user); // speichert schon ab
|
||||
await dataset.save();
|
||||
return response
|
||||
.toRoute('reviewer.dataset.list')
|
||||
.flash('message', `You have rejected dataset ${dataset.id}! to editor ${dataset.editor.login}`);
|
||||
} catch (error) {
|
||||
// Handle any errors
|
||||
console.error(error);
|
||||
return response.status(500).json({ error: 'An error occurred while reviewing the data.' });
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Add table
editor.link_modal.header
Reference in a new issue