feat: enhance user management, mimetype creation, and validation
Some checks failed
CI Pipeline / japa-tests (push) Failing after 1m8s
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:
parent
2235f3905a
commit
49bd96ee77
24 changed files with 1548 additions and 945 deletions
|
@ -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>
|
||||
|
|
|
@ -79,7 +79,7 @@
|
|||
<FormField label="Main Title *" help="required: main title"
|
||||
:class="{ 'text-red-400': form.errors['titles.0.value'] }" class="w-full mr-1 flex-1">
|
||||
<FormControl required v-model="form.titles[0].value" type="text"
|
||||
placeholder="[enter main title]">
|
||||
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(', ') }}
|
||||
|
@ -163,7 +163,7 @@
|
|||
:class="{ 'text-red-400': form.errors['descriptions.0.value'] }"
|
||||
class="w-full mr-1 flex-1">
|
||||
<FormControl required v-model="form.descriptions[0].value" type="textarea"
|
||||
placeholder="[enter main abstract]">
|
||||
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(', ') }}
|
||||
|
|
|
@ -92,7 +92,7 @@ const formatServerState = (state: string) => {
|
|||
|
||||
<!-- table -->
|
||||
<CardBox class="mb-6" has-table>
|
||||
<table class="">
|
||||
<table class="w-full table-fixed">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col" class="py-3 text-left text-xs font-medium uppercase tracking-wider">
|
||||
|
@ -114,13 +114,13 @@ const formatServerState = (state: string) => {
|
|||
|
||||
<tbody class="bg-white divide-y divide-gray-200">
|
||||
<tr v-for="dataset in props.datasets.data" :key="dataset.id" :class="getRowClass(dataset)">
|
||||
<td data-label="Login" class="py-4 whitespace-nowrap text-gray-700 dark:text-white">
|
||||
<td data-label="Login" class="py-4 whitespace-nowrap text-gray-700 dark:text-white table-title">
|
||||
<!-- <Link v-bind:href="stardust.route('settings.user.show', [user.id])"
|
||||
class="no-underline hover:underline text-cyan-600 dark:text-cyan-400">
|
||||
{{ user.login }}
|
||||
</Link> -->
|
||||
<!-- {{ user.id }} -->
|
||||
{{ dataset.main_title }}
|
||||
{{ dataset.main_title }}
|
||||
</td>
|
||||
<td class="py-4 whitespace-nowrap text-gray-700 dark:text-white">
|
||||
{{ formatServerState(dataset.server_state) }}
|
||||
|
@ -156,44 +156,55 @@ const formatServerState = (state: string) => {
|
|||
</LayoutAuthenticated>
|
||||
</template>
|
||||
|
||||
<!-- <style scoped lang="css">
|
||||
.pure-table tr.released {
|
||||
background-color: rgb(52 211 153);
|
||||
color: gray;
|
||||
<style scoped lang="css">
|
||||
|
||||
.table-title {
|
||||
max-width: 200px; /* set a maximum width */
|
||||
overflow: hidden; /* hide overflow */
|
||||
text-overflow: ellipsis; /* show ellipsis for overflowed text */
|
||||
white-space: nowrap; /* prevent wrapping */
|
||||
}
|
||||
.table-fixed {
|
||||
table-layout: fixed;
|
||||
}
|
||||
|
||||
.pure-table tr.inprogress {
|
||||
/* .pure-table tr.released {
|
||||
background-color: rgb(52 211 153);
|
||||
color: gray;
|
||||
} */
|
||||
|
||||
/* .pure-table tr.inprogress {
|
||||
padding: 0.8em;
|
||||
background-color: rgb(94 234 212);
|
||||
color: gray;
|
||||
}
|
||||
} */
|
||||
|
||||
.pure-table tr.editor_accepted {
|
||||
/* .pure-table tr.editor_accepted {
|
||||
background-color: rgb(125 211 252);
|
||||
color: gray;
|
||||
}
|
||||
} */
|
||||
|
||||
.pure-table tr.rejected_reviewer {
|
||||
/* .pure-table tr.rejected_reviewer {
|
||||
padding: 0.8em;
|
||||
background-color: orange;
|
||||
color: gray;
|
||||
}
|
||||
} */
|
||||
|
||||
.pure-table tr.rejected_editor {
|
||||
/* .pure-table tr.rejected_editor {
|
||||
background-color: orange;
|
||||
color: gray;
|
||||
}
|
||||
} */
|
||||
|
||||
.pure-table tr.reviewed {
|
||||
/* .pure-table tr.reviewed {
|
||||
background-color: yellow;
|
||||
color: gray;
|
||||
}
|
||||
} */
|
||||
|
||||
.pure-table tr.approved {
|
||||
/* .pure-table tr.approved {
|
||||
background-color: rgb(86, 86, 241);
|
||||
color: whitesmoke;
|
||||
color: whitesmoke;
|
||||
|
||||
}
|
||||
}*/
|
||||
|
||||
|
||||
</style> -->
|
||||
</style>
|
||||
|
|
Loading…
Add table
editor.link_modal.header
Reference in a new issue