feat: enhance user management, mimetype creation, and validation

- **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

@ -164,7 +164,7 @@ export const updateDatasetValidator = vine.compile(
titles: vine
.array(
vine.object({
value: vine.string().trim().minLength(3).maxLength(2500),
value: vine.string().trim().minLength(3).maxLength(255),
type: vine.enum(Object.values(TitleTypes)),
language: vine
.string()
@ -178,7 +178,7 @@ export const updateDatasetValidator = vine.compile(
descriptions: vine
.array(
vine.object({
value: vine.string().trim().minLength(3).maxLength(255),
value: vine.string().trim().minLength(3).maxLength(2500),
type: vine.enum(Object.values(DescriptionTypes)),
language: vine
.string()
@ -295,6 +295,7 @@ let messagesProvider = new SimpleMessagesProvider({
'rights.in': 'you must agree to continue',
'titles.0.value.minLength': 'Main Title must be at least {{ min }} characters long',
'titles.0.value.maxLength': 'Main Title must be less than {{ max }} characters long',
'titles.0.value.required': 'Main Title is required',
'titles.*.value.required': 'Additional title is required, if defined',
'titles.*.type.required': 'Additional title type is required',

View file

@ -56,7 +56,7 @@ let messagesProvider = new SimpleMessagesProvider({
// 'contacts.0.email.required': 'The primary email of the contact is required',
// 'contacts.*.email.required': 'Contact email is required',
'permissions.minLength': 'at least {{ options.minLength }} permission must be defined',
'permissions.minLength': 'at least {{min }} permission must be defined',
'permissions.*.number': 'Define permissions as valid numbers',
});

View file

@ -13,6 +13,8 @@ export const createUserValidator = vine.compile(
.maxLength(20)
.isUnique({ table: 'accounts', column: 'login' })
.regex(/^[a-zA-Z0-9]+$/), //Must be alphanumeric with hyphens or underscores
first_name: vine.string().trim().minLength(3).maxLength(255),
last_name: vine.string().trim().minLength(3).maxLength(255),
email: vine.string().maxLength(255).email().normalizeEmail().isUnique({ table: 'accounts', column: 'email' }),
password: vine.string().confirmed().trim().minLength(3).maxLength(60),
roles: vine.array(vine.number()).minLength(1), // define at least one role for the new user
@ -30,8 +32,10 @@ export const updateUserValidator = vine.withMetaData<{ objId: number }>().compil
.trim()
.minLength(3)
.maxLength(20)
.isUnique({ table: 'accounts', column: 'login', whereNot: (field) => field.meta.objId })
.regex(/^[a-zA-Z0-9]+$/), //Must be alphanumeric with hyphens or underscores
.isUnique({ table: 'accounts', column: 'login', whereNot: (field) => field.meta.objId }),
// .regex(/^[a-zA-Z0-9]+$/), //Must be alphanumeric with hyphens or underscores
first_name: vine.string().trim().minLength(3).maxLength(255),
last_name: vine.string().trim().minLength(3).maxLength(255),
email: vine
.string()
.maxLength(255)
@ -49,10 +53,10 @@ let messagesProvider = new SimpleMessagesProvider({
'unique': '{{ field }} must be unique, and this value is already taken',
'string': 'The value of {{ field }} field must be a string',
'email': 'The value is not a valid email address',
'minLength': '{{ field }} must be at least {{ options.minLength }} characters long',
'maxLength': '{{ field }} must be less then {{ options.maxLength }} characters long',
'minLength': '{{ field }} must be at least {{ min }} characters long',
'maxLength': '{{ field }} must be less then {{ max }} characters long',
'confirmed': 'Oops! The confirmation of {{ field }} is not correct. Please double-check and ensure they match.',
'roles.minLength': 'at least {{ options.minLength }} role must be defined',
'roles.minLength': 'at least {{ min }} role must be defined',
'roles.*.number': 'Define roles as valid numbers',
});

View file

@ -128,11 +128,12 @@ export class VanillaErrorReporter implements ErrorReporterContract {
const error: SimpleError = {
message,
rule,
field: field.getFieldPath(),
field: field.wildCardPath ?field.wildCardPath.split('.')[0] : field.getFieldPath(),
};
// field: 'titles.0.value'
// message: 'Main Title is required'
// rule: 'required' "required"
if (meta) {
error.meta = meta;
}
@ -140,10 +141,25 @@ export class VanillaErrorReporter implements ErrorReporterContract {
// error.index = field.name;
// }
this.hasErrors = true;
// this.errors.push(error);
if (this.errors[error.field]) {
this.errors[error.field]?.push(message);
// if (this.errors[error.field]) {
// this.errors[error.field]?.push(message);
// }
if (field.isArrayMember) {
// Check if the field has wildCardPath and if the error field already exists
if (this.errors[error.field] && field.wildCardPath) {
// Do nothing, as we don't want to push further messages
} else {
// If the error field already exists, push the message
if (this.errors[error.field]) {
this.errors[error.field].push(message);
} else {
this.errors[error.field] = [message];
}
}
} else {
// normal field
this.errors[error.field] = [message];
}