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

@ -39,7 +39,8 @@ import { MainService } from '@/Stores/main';
import { notify } from '@/notiwind';
import MapComponent from '@/Components/Map/map.component.vue';
import { MapOptions } from '@/Components/Map/MapOptions';
import { LatLngBoundsExpression } from 'leaflet/src/geo/LatLngBounds';
// import { LatLngBoundsExpression } from 'leaflet/src/geo/LatLngBounds';
import { LatLngBoundsExpression } from 'leaflet';
import { LayerOptions } from '@/Components/Map/LayerOptions';
import TableKeywords from '@/Components/TableKeywords.vue';
import NotificationBar from '@/Components/NotificationBar.vue';
@ -277,7 +278,7 @@ const mapId = 'test';
// };
const nextStep = async () => {
let route ="";
let route = "";
if (formStep.value == 1) {
route = stardust.route('dataset.first.step');
} else if (formStep.value == 2) {
@ -504,7 +505,7 @@ Removes a selected keyword
<icon-mandatory></icon-mandatory>
</icon-wizard>
<icon-wizard :is-current="formStep == 3" :is-checked="formStep > 3" :label="'Recommendet'">
<icon-wizard :is-current="formStep == 3" :is-checked="formStep > 3" :label="'Recommended'">
<icon-recommendet></icon-recommendet>
</icon-wizard>
@ -595,7 +596,8 @@ Removes a selected keyword
:class="{ 'text-red-400': form.errors['titles.0.value'] }"
class="w-full mx-2 flex-1">
<FormControl required v-model="form.titles[0].value" type="textarea"
placeholder="[enter main title]" :show-char-count="true" :max-input-length="255">
placeholder="[enter main title]" :show-char-count="true"
:max-input-length="255">
<div class="text-red-400 text-sm"
v-if="form.errors['titles.0.value'] && Array.isArray(form.errors['titles.0.value'])">
{{ form.errors['titles.0.value'].join(', ') }}
@ -670,7 +672,8 @@ Removes a selected keyword
:class="{ 'text-red-400': form.errors['descriptions.0.value'] }"
class="w-full mx-2 flex-1">
<FormControl required v-model="form.descriptions[0].value" type="textarea"
placeholder="[enter main abstract]" :show-char-count="true" :max-input-length="2500">
placeholder="[enter main abstract]" :show-char-count="true"
:max-input-length="2500">
<div class="text-red-400 text-sm"
v-if="form.errors['descriptions.0.value'] && Array.isArray(form.errors['descriptions.0.value'])">
{{ form.errors['descriptions.0.value'].join(', ') }}
@ -702,7 +705,8 @@ Removes a selected keyword
:class="{ 'text-red-400': form.errors[`descriptions.${index}.value`] }"
class="w-full mx-2 flex-1">
<FormControl required v-model="form.descriptions[index].value" type="text"
placeholder="[enter additional description]" :show-char-count="true" :max-input-length="2500">
placeholder="[enter additional description]" :show-char-count="true"
:max-input-length="2500">
<div class="text-red-400 text-sm" v-if="form.errors[`descriptions.${index}.value`] &&
Array.isArray(form.errors[`descriptions.${index}.value`])
">
@ -744,7 +748,8 @@ Removes a selected keyword
<SearchAutocomplete source="/api/persons" :response-property="'first_name'"
placeholder="search in person table...." v-on:person="onAddAuthor"></SearchAutocomplete>
<TablePersons :errors="form.errors" :persons="form.authors" :relation="'authors'" v-if="form.authors.length > 0" />
<TablePersons :errors="form.errors" :persons="form.authors" :relation="'authors'"
v-if="form.authors.length > 0" />
<div class="text-red-400 text-sm" v-if="errors.authors && Array.isArray(errors.authors)">
{{ errors.authors.join(', ') }}
</div>
@ -762,8 +767,9 @@ Removes a selected keyword
placeholder="search in person table...." v-on:person="onAddContributor">
</SearchAutocomplete>
<TablePersons :persons="form.contributors" :relation="'contributors'" v-if="form.contributors.length > 0"
:contributortypes="contributorTypes" :errors="form.errors" />
<TablePersons :persons="form.contributors" :relation="'contributors'"
v-if="form.contributors.length > 0" :contributortypes="contributorTypes"
:errors="form.errors" />
<div class="text-red-400 text-sm"
v-if="form.errors.contributors && Array.isArray(form.errors.contributors)">
{{ form.errors.contributors.join(', ') }}
@ -807,8 +813,8 @@ Removes a selected keyword
<FormField label="Coverage X Min"
:class="{ 'text-red-400': form.errors['coverage.x_min'] }"
class="w-full mx-2 flex-1">
<FormControl required v-model="form.coverage.x_min" type="text" inputmode="numeric" pattern="\d*"
placeholder="[enter x_min]">
<FormControl required v-model="form.coverage.x_min" type="text" inputmode="numeric"
pattern="\d*" placeholder="[enter x_min]">
<div class="text-red-400 text-sm"
v-if="form.errors['coverage.x_min'] && Array.isArray(form.errors['coverage.x_min'])">
{{ form.errors['coverage.x_min'].join(', ') }}
@ -1066,6 +1072,7 @@ Removes a selected keyword
</div>
</div>
<template #footer>
<div class="flex p-2 mt-4">
<button v-if="formStep > 1" @click="prevStep"
@ -1087,11 +1094,30 @@ Removes a selected keyword
</button>
</div>
</div>
<progress v-if="form.progress" :value="form.progress.percentage" max="100">{{
form.progress.percentage
}}%</progress>
<progress v-if="form.progress" :value="form.progress.percentage" max="100">
{{ form.progress.percentage }}%
</progress>
</template>
</CardBox>
<!-- Loading Spinner -->
<div v-if="form.processing"
class="fixed inset-0 flex items-center justify-center bg-gray-500 bg-opacity-50 z-50">
<svg class="animate-spin h-12 w-12 text-white" xmlns="http://www.w3.org/2000/svg" fill="none"
viewBox="0 0 24 24">
<circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle>
<path class="opacity-75" fill="currentColor" d="M12 2a10 10 0 0110 10h-4a6 6 0 00-6-6V2z"></path>
</svg>
</div>
<!-- <div
class="fixed inset-0 flex items-center justify-center bg-gray-500 bg-opacity-50">
<svg class="animate-spin h-10 w-10 text-white" xmlns="http://www.w3.org/2000/svg" fill="none"
viewBox="0 0 24 24">
<circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle>
<path class="opacity-75" fill="currentColor"
d="M4 12a8 8 0 0116 0 8 8 0 01-16 0zm2 0a6 6 0 0112 0 6 6 0 01-12 0z"></path>
</svg>
</div> -->
</SectionMain>
</LayoutAuthenticated>
</template>