forked from geolba/tethys.backend
- add methods for releasing datasets from submitter
- npm updates - side menu with child items - flash messages via HttpContext response (extended via macro)
This commit is contained in:
parent
e0ff71b117
commit
f403c3109f
37 changed files with 1020 additions and 482 deletions
|
@ -17,8 +17,68 @@ import { TransactionClientContract } from '@ioc:Adonis/Lucid/Database';
|
|||
import Subject from 'App/Models/Subject';
|
||||
import CreateDatasetValidator from 'App/Validators/CreateDatasetValidator';
|
||||
import { TitleTypes, DescriptionTypes } from 'Contracts/enums';
|
||||
import type { ModelQueryBuilderContract } from '@ioc:Adonis/Lucid/Orm';
|
||||
|
||||
export default class DatasetController {
|
||||
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 sort_order: SortOrder = 'asc';
|
||||
|
||||
if (attribute.substr(0, 1) == '-') {
|
||||
sort_order = 'desc';
|
||||
// attribute = substr(attribute, 1);
|
||||
attribute = attribute.substr(1);
|
||||
}
|
||||
datasets.orderBy(attribute, sort_order);
|
||||
} else {
|
||||
// users.orderBy('created_at', 'desc');
|
||||
datasets.orderBy('id', 'asc');
|
||||
}
|
||||
|
||||
// const users = await User.query().orderBy('login').paginate(page, limit);
|
||||
const myDatasets = await datasets
|
||||
.whereIn('server_state', [
|
||||
'inprogress',
|
||||
'released',
|
||||
'editor_accepted',
|
||||
'approved',
|
||||
'reviewed',
|
||||
'rejected_editor',
|
||||
'rejected_reviewer',
|
||||
])
|
||||
.where('account_id', user.id)
|
||||
.preload('titles')
|
||||
.preload('user', (query) => query.select('id', 'login'))
|
||||
// .preload('titles', (builder) => {
|
||||
// // pull the actual preload data
|
||||
|
||||
// builder.where('type', 'Main');
|
||||
// })
|
||||
.paginate(page, 10);
|
||||
|
||||
return inertia.render('Submitter/Dataset/Index', {
|
||||
// testing: 'this is a test',
|
||||
datasets: myDatasets.serialize(),
|
||||
filters: request.all(),
|
||||
can: {
|
||||
// create: await auth.user?.can(['user-create']),
|
||||
edit: await auth.user?.can(['dataset-edit']),
|
||||
delete: await auth.user?.can(['dataset-delete']),
|
||||
},
|
||||
});
|
||||
}
|
||||
public async create({ inertia }: HttpContextContract) {
|
||||
const licenses = await License.query().select('id', 'name_long').pluck('name_long', 'id');
|
||||
|
||||
|
@ -423,4 +483,89 @@ export default class DatasetController {
|
|||
'files.*.size': 'file size is to big',
|
||||
'files.extnames': 'file extension is not supported',
|
||||
};
|
||||
|
||||
// public async release({ params, view }) {
|
||||
public async release({ request, inertia }: HttpContextContract) {
|
||||
const id = request.param('id');
|
||||
|
||||
const dataset = await Dataset.query()
|
||||
.preload('user', (builder) => {
|
||||
builder.select('id', 'login');
|
||||
})
|
||||
.where('id', id)
|
||||
.firstOrFail();
|
||||
|
||||
// const editors = await User.query()
|
||||
// .whereHas('roles', (builder) => {
|
||||
// builder.where('name', 'editor');
|
||||
// })
|
||||
// .pluck('login', 'id');
|
||||
|
||||
return inertia.render('Submitter/Dataset/Release', {
|
||||
dataset,
|
||||
});
|
||||
}
|
||||
|
||||
public async releaseUpdate({ request, response }: HttpContextContract) {
|
||||
const id = request.param('id');
|
||||
const dataset = await Dataset.query().preload('files').where('id', id).firstOrFail();
|
||||
if (dataset.files.length === 0) {
|
||||
return response.flash('message', 'At least minimum one file is required.').redirect('back');
|
||||
}
|
||||
|
||||
const preferation = request.input('preferation', '');
|
||||
const preferredReviewer = request.input('preferred_reviewer');
|
||||
const preferredReviewerEmail = request.input('preferred_reviewer_email');
|
||||
|
||||
if (preferation === 'yes_preferation') {
|
||||
const newSchema = schema.create({
|
||||
preferred_reviewer: schema.string({ trim: true }, [rules.minLength(3), rules.maxLength(255)]),
|
||||
preferred_reviewer_email: schema.string([rules.email()]),
|
||||
});
|
||||
|
||||
try {
|
||||
await request.validate({ schema: newSchema });
|
||||
} catch (error) {
|
||||
// return response.badRequest(error.messages);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
const input = {
|
||||
preferred_reviewer: preferredReviewer || null,
|
||||
preferred_reviewer_email: preferredReviewerEmail || null,
|
||||
server_state: 'released',
|
||||
editor_id: null,
|
||||
reviewer_id: null,
|
||||
reject_editor_note: null,
|
||||
reject_reviewer_note: null,
|
||||
};
|
||||
|
||||
// Clear editor_id if it exists
|
||||
if (dataset.editor_id !== null) {
|
||||
input.editor_id = null;
|
||||
}
|
||||
|
||||
// Clear reject_editor_note if it exists
|
||||
if (dataset.reject_editor_note !== null) {
|
||||
input.reject_editor_note = null;
|
||||
}
|
||||
|
||||
// Clear reviewer_id if it exists
|
||||
if (dataset.reviewer_id !== null) {
|
||||
input.reviewer_id = null;
|
||||
}
|
||||
|
||||
// Clear reject_reviewer_note if it exists
|
||||
if (dataset.reject_reviewer_note !== null) {
|
||||
input.reject_reviewer_note = null;
|
||||
}
|
||||
|
||||
// if (await dataset.merge(input).save()) {
|
||||
// return response.redirect().route('publish.workflow.submit.index').flash('flash_message', 'You have released your dataset!');
|
||||
// }
|
||||
return response.toRoute('dataset.list').flash('message', 'You have released your dataset');
|
||||
|
||||
// throw new GeneralException(trans('exceptions.publish.release.update_error'));
|
||||
}
|
||||
}
|
||||
|
|
34
app/FlashResponse.ts
Normal file
34
app/FlashResponse.ts
Normal file
|
@ -0,0 +1,34 @@
|
|||
import { Response } from '@adonisjs/http-server/build/src/Response';
|
||||
import { ServerResponse, IncomingMessage } from 'http';
|
||||
import { RouterContract } from '@ioc:Adonis/Core/Route';
|
||||
import { EncryptionContract } from '@ioc:Adonis/Core/Encryption';
|
||||
import { ResponseConfig, ResponseContract } from '@ioc:Adonis/Core/Response';
|
||||
|
||||
class FlashResponse extends Response implements ResponseContract {
|
||||
protected static macros = {};
|
||||
protected static getters = {};
|
||||
constructor(
|
||||
public request: IncomingMessage,
|
||||
public response: ServerResponse,
|
||||
flashEncryption: EncryptionContract,
|
||||
flashConfig: ResponseConfig,
|
||||
flashRouter: RouterContract,
|
||||
) {
|
||||
super(request, response, flashEncryption, flashConfig, flashRouter);
|
||||
}
|
||||
nonce: string;
|
||||
|
||||
public flash(key: string, message: any): this {
|
||||
// Store the flash message in the session
|
||||
this.ctx?.session.flash(key, message);
|
||||
return this;
|
||||
}
|
||||
|
||||
public toRoute(route: string): this {
|
||||
// Redirect to the specified route
|
||||
super.redirect().toRoute(route);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
export default FlashResponse;
|
|
@ -8,14 +8,17 @@ import {
|
|||
BelongsTo,
|
||||
hasMany,
|
||||
HasMany,
|
||||
computed,
|
||||
} from '@ioc:Adonis/Lucid/Orm';
|
||||
import { DateTime } from 'luxon';
|
||||
import dayjs from 'dayjs';
|
||||
import Person from './Person';
|
||||
import User from './User';
|
||||
import Title from './Title';
|
||||
import Description from './Description';
|
||||
import License from './License';
|
||||
import Subject from './Subject';
|
||||
import File from './File';
|
||||
|
||||
export default class Dataset extends BaseModel {
|
||||
public static namingStrategy = new SnakeCaseNamingStrategy();
|
||||
|
@ -47,10 +50,29 @@ export default class Dataset extends BaseModel {
|
|||
@column({})
|
||||
public account_id: number | null = null;
|
||||
|
||||
@column({})
|
||||
public editor_id: number | null = null;
|
||||
|
||||
@column({})
|
||||
public reviewer_id: number | null = null;
|
||||
|
||||
@column({})
|
||||
public reject_editor_note: string;
|
||||
|
||||
@column({})
|
||||
public reject_reviewer_note: string;
|
||||
|
||||
@column.dateTime({ columnName: 'server_date_published' })
|
||||
public serverDatePublished: DateTime;
|
||||
|
||||
@column.dateTime({ autoCreate: true, columnName: 'created_at' })
|
||||
// @column.dateTime({ autoCreate: true, columnName: 'created_at' })
|
||||
@column.dateTime({
|
||||
serialize: (value: Date | null) => {
|
||||
return value ? dayjs(value).format('MMMM D YYYY HH:mm a') : value;
|
||||
},
|
||||
autoCreate: true,
|
||||
columnName: 'created_at',
|
||||
})
|
||||
public createdAt: DateTime;
|
||||
|
||||
@column.dateTime({ autoCreate: true, autoUpdate: true, columnName: 'server_date_modified' })
|
||||
|
@ -100,9 +122,17 @@ export default class Dataset extends BaseModel {
|
|||
})
|
||||
public subjects: ManyToMany<typeof Subject>;
|
||||
|
||||
// async save(): Promise<this> {
|
||||
// // Call the parent save method to persist changes to the database
|
||||
// await super.save();
|
||||
// return this;
|
||||
// }
|
||||
@hasMany(() => File, {
|
||||
foreignKey: 'document_id',
|
||||
})
|
||||
public files: HasMany<typeof File>;
|
||||
|
||||
@computed({
|
||||
serializeAs: 'main_title',
|
||||
})
|
||||
public get mainTitle() {
|
||||
// return `${this.firstName} ${this.lastName}`;
|
||||
const mainTitle = this.titles?.find((title) => title.type === 'Main');
|
||||
return mainTitle ? mainTitle.value : null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,11 +4,14 @@ import {
|
|||
BaseModel,
|
||||
hasMany,
|
||||
HasMany,
|
||||
belongsTo,
|
||||
BelongsTo,
|
||||
// manyToMany,
|
||||
// ManyToMany,
|
||||
SnakeCaseNamingStrategy,
|
||||
} from '@ioc:Adonis/Lucid/Orm';
|
||||
import HashValue from './HashValue';
|
||||
import Dataset from './Dataset';
|
||||
|
||||
export default class File extends BaseModel {
|
||||
public static namingStrategy = new SnakeCaseNamingStrategy();
|
||||
|
@ -21,6 +24,9 @@ export default class File extends BaseModel {
|
|||
})
|
||||
public id: number;
|
||||
|
||||
@column({})
|
||||
public document_id: number;
|
||||
|
||||
@column({})
|
||||
public pathName: string;
|
||||
|
||||
|
@ -51,10 +57,14 @@ export default class File extends BaseModel {
|
|||
@column.dateTime({ autoCreate: true, autoUpdate: true })
|
||||
public updatedAt: DateTime;
|
||||
|
||||
// public function hashvalues()
|
||||
// public function dataset()
|
||||
// {
|
||||
// return $this->hasMany(HashValue::class, 'file_id', 'id');
|
||||
// return $this->belongsTo(Dataset::class, 'document_id', 'id');
|
||||
// }
|
||||
@belongsTo(() => Dataset, {
|
||||
foreignKey: 'document_id',
|
||||
})
|
||||
public dataset: BelongsTo<typeof Dataset>;
|
||||
|
||||
@hasMany(() => HashValue, {
|
||||
foreignKey: 'file_id',
|
||||
|
|
Loading…
Add table
editor.link_modal.header
Reference in a new issue