feat: enhance user management, mimetype creation, and validation
Some checks failed
CI Pipeline / japa-tests (push) Failing after 1m8s

- **AdminuserController.ts**: enable editing `first_name` and `last_name` for user creation and updates
- **MimetypeController.ts**: add creation support for mimetypes with selectable extensions
- **Models**: add `Mimetype` model (mime_type.ts); add `SnakeCaseNamingStrategy` for User model
- **Validators**:
  - **updateDatasetValidator**: increase title length to 255 and description length to 2500
  - **User Validators**: refine `createUserValidator` and `updateUserValidator` to include `first_name` and `last_name`
- **vanilla_error_reporter**: improve error reporting for wildcard fields
- **SKOS Query**: refine keyword request in `SearchCategoryAutocomplete.vue`
- **UI Enhancements**:
  - improve icon design in wizard (Wizard.vue)
  - add components for mimetype creation (Create.vue and button in Index.vue)
- **Routes**: update `routes.ts` to include new AdonisJS routes
This commit is contained in:
Kaimbacher 2024-10-31 11:02:36 +01:00
parent 2235f3905a
commit 49bd96ee77
24 changed files with 1548 additions and 945 deletions

View file

@ -85,7 +85,7 @@ export default class AdminuserController {
// return response.badRequest(error.messages);
throw error;
}
const input = request.only(['login', 'email', 'password']);
const input = request.only(['login', 'email', 'password', 'first_name', 'last_name']);
const user = await User.create(input);
if (request.input('roles')) {
const roles: Array<number> = request.input('roles');
@ -141,9 +141,9 @@ export default class AdminuserController {
// password is optional
let input;
if (request.input('password')) {
input = request.only(['login', 'email', 'password']);
input = request.only(['login', 'email', 'password', 'first_name', 'last_name']);
} else {
input = request.only(['login', 'email']);
input = request.only(['login', 'email', 'first_name', 'last_name']);
}
await user.merge(input).save();
// await user.save();

View file

@ -1,34 +1,124 @@
import type { HttpContext } from '@adonisjs/core/http';
import MimeType from '#models/mime_type';
import vine, { SimpleMessagesProvider } from '@vinejs/vine';
export default class MimetypeController {
public async index({ auth, inertia }: HttpContext) {
const direction = 'asc'; // or 'desc'
const mimetypes = await MimeType.query().orderBy('name', direction).exec();
const mimetypes = await MimeType.query().orderBy('name', direction).exec();
return inertia.render('Admin/Mimetype/Index', {
mimetypes: mimetypes,
can: {
create: await auth.user?.can(['settings']),
edit: await auth.user?.can(['settings']),
},
});
}
public async create({ inertia }: HttpContext) {
// const permissions = await Permission.query().select('id', 'name').pluck('name', 'id');
return inertia.render('Admin/Mimetype/Create', {});
}
public async store({ request, response, session }: HttpContext) {
const newDatasetSchema = vine.object({
name: vine.string().trim().isUnique({ table: 'mime_types', column: 'name' }),
file_extension: vine.array(vine.string()).minLength(1), // define at least one extension for the new mimetype
enabled: vine.boolean(),
});
// await request.validate({ schema: newDatasetSchema, messages: this.messages });
try {
// Step 2 - Validate request body against the schema
// await request.validate({ schema: newDatasetSchema, messages: this.messages });
const validator = vine.compile(newDatasetSchema);
validator.messagesProvider = new SimpleMessagesProvider(this.messages);
await request.validateUsing(validator);
} catch (error) {
// Step 3 - Handle errors
// return response.badRequest(error.messages);
throw error;
}
const input = request.only(['name', 'enabled', 'file_extension']);
// Concatenate the file_extensions array into a string with '|' as the separator
if (Array.isArray(input.file_extension)) {
input.file_extension = input.file_extension.join('|');
}
await MimeType.create(input);
// if (request.input('roles')) {
// const roles: Array<number> = request.input('roles');
// await user.related('roles').attach(roles);
// }
session.flash('message', 'MimeType has been created successfully');
return response.redirect().toRoute('settings.mimetype.index');
}
public messages = {
'minLength': '{{ field }} must be at least {{ min }} characters long',
'maxLength': '{{ field }} must be less then {{ max }} characters long',
'isUnique': '{{ field }} must be unique, and this value is already taken',
'required': '{{ field }} is required',
'file_extension.minLength': 'at least {{ min }} mimetypes must be defined',
'file_extension.*.string': 'Each file extension must be a valid string', // Adjusted to match the type
};
public async edit({ request, inertia }: HttpContext) {
const id = request.param('id');
const mimetype = await MimeType.query().where('id', id).firstOrFail();
// const permissions = await Permission.query().pluck('name', 'id');
// // const userHasRoles = user.roles;
// const rolerHasPermissions = await role.related('permissions').query().orderBy('name').pluck('id');
return inertia.render('Admin/Mimetype/Edit', {
mimetype: mimetype,
});
}
// public async update({ request, response, session }: HttpContext) {
// // node ace make:validator UpdateUser
// const id = request.param('id');
// const role = await Role.query().where('id', id).firstOrFail();
// // validate update form
// // await request.validate(UpdateRoleValidator);
// await request.validateUsing(updateRoleValidator, {
// meta: {
// roleId: role.id,
// },
// });
// // password is optional
// const input = request.only(['name', 'description']);
// await role.merge(input).save();
// // await user.save();
// if (request.input('permissions')) {
// const permissions: Array<number> = request.input('permissions');
// await role.related('permissions').sync(permissions);
// }
// session.flash('message', 'Role has been updated successfully');
// return response.redirect().toRoute('settings.role.index');
// }
public async down({ request, response }: HttpContext) {
const id = request.param('id');
const mimetype = await MimeType.findOrFail(id);
const mimetype = await MimeType.findOrFail(id);
mimetype.enabled = false;
await mimetype .save();
await mimetype.save();
// session.flash({ message: 'person has been deactivated!' });
return response.flash('mimetype has been deactivated!', 'message').toRoute('settings.mimetype.index')
return response.flash('mimetype has been deactivated!', 'message').toRoute('settings.mimetype.index');
}
public async up({ request, response }: HttpContext) {
const id = request.param('id');
const mimetype = await MimeType.findOrFail(id);
const mimetype = await MimeType.findOrFail(id);
mimetype.enabled = true;
await mimetype .save();
await mimetype.save();
// session.flash({ message: 'person has been activated!' });
return response.flash('mimetype has been activated!', 'message').toRoute('settings.mimetype.index');