- small adaption for OpenAire inside OaiController.ts
Some checks failed
CI Pipeline / japa-tests (push) Failing after 59s
Some checks failed
CI Pipeline / japa-tests (push) Failing after 59s
- validate abstratct for max 2500 characters - small changes inside page for releasing a dataset - npm updates - adapted validating messages
This commit is contained in:
parent
005df2e454
commit
49ea0fc967
|
@ -216,6 +216,7 @@ export default class OaiController {
|
||||||
|
|
||||||
const sets: { [key: string]: string } = {
|
const sets: { [key: string]: string } = {
|
||||||
'open_access': 'Set for open access licenses',
|
'open_access': 'Set for open access licenses',
|
||||||
|
'openaire_data': "OpenAIRE",
|
||||||
'doc-type:ResearchData': 'Set for document type ResearchData',
|
'doc-type:ResearchData': 'Set for document type ResearchData',
|
||||||
...(await this.getSetsForDatasetTypes()),
|
...(await this.getSetsForDatasetTypes()),
|
||||||
...(await this.getSetsForCollections()),
|
...(await this.getSetsForCollections()),
|
||||||
|
|
|
@ -202,7 +202,7 @@ export default class DatasetController {
|
||||||
descriptions: vine
|
descriptions: vine
|
||||||
.array(
|
.array(
|
||||||
vine.object({
|
vine.object({
|
||||||
value: vine.string().trim().minLength(3).maxLength(255),
|
value: vine.string().trim().minLength(3).maxLength(2500),
|
||||||
type: vine.enum(Object.values(DescriptionTypes)),
|
type: vine.enum(Object.values(DescriptionTypes)),
|
||||||
language: vine
|
language: vine
|
||||||
.string()
|
.string()
|
||||||
|
@ -279,7 +279,7 @@ export default class DatasetController {
|
||||||
descriptions: vine
|
descriptions: vine
|
||||||
.array(
|
.array(
|
||||||
vine.object({
|
vine.object({
|
||||||
value: vine.string().trim().minLength(3).maxLength(255),
|
value: vine.string().trim().minLength(3).maxLength(2500),
|
||||||
type: vine.enum(Object.values(DescriptionTypes)),
|
type: vine.enum(Object.values(DescriptionTypes)),
|
||||||
language: vine
|
language: vine
|
||||||
.string()
|
.string()
|
||||||
|
@ -635,6 +635,7 @@ export default class DatasetController {
|
||||||
'titles.*.language.translatedLanguage': 'The language of the translated title must be different from the language of the dataset',
|
'titles.*.language.translatedLanguage': 'The language of the translated title must be different from the language of the dataset',
|
||||||
|
|
||||||
'descriptions.0.value.minLength': 'Main Abstract must be at least {{ min }} characters long',
|
'descriptions.0.value.minLength': 'Main Abstract must be at least {{ min }} characters long',
|
||||||
|
'descriptions.0.value.maxLength': 'Main Abstract must be less than {{ max }} characters long',
|
||||||
'descriptions.0.value.required': 'Main Abstract is required',
|
'descriptions.0.value.required': 'Main Abstract is required',
|
||||||
'descriptions.*.value.required': 'Additional description is required, if defined',
|
'descriptions.*.value.required': 'Additional description is required, if defined',
|
||||||
'descriptions.*.type.required': 'Additional description type is required',
|
'descriptions.*.type.required': 'Additional description type is required',
|
||||||
|
@ -644,6 +645,7 @@ export default class DatasetController {
|
||||||
|
|
||||||
'authors.array.minLength': 'at least {{ min }} author must be defined',
|
'authors.array.minLength': 'at least {{ min }} author must be defined',
|
||||||
'authors.distinct': 'The {{ field }} array must have unique values based on the {{ fields }} attribute.',
|
'authors.distinct': 'The {{ field }} array must have unique values based on the {{ fields }} attribute.',
|
||||||
|
'authors.*.email.isUnique': 'the email of the new creator already exists in the database',
|
||||||
'contributors.*.pivot_contributor_type.required': 'contributor type is required, if defined',
|
'contributors.*.pivot_contributor_type.required': 'contributor type is required, if defined',
|
||||||
'contributors.distinct': 'The {{ field }} array must have unique values based on the {{ fields }} attribute.',
|
'contributors.distinct': 'The {{ field }} array must have unique values based on the {{ fields }} attribute.',
|
||||||
|
|
||||||
|
|
43
app/middleware/normalize_newlines_middleware.ts
Normal file
43
app/middleware/normalize_newlines_middleware.ts
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
/*
|
||||||
|
* This middleware class normalizes newlines in the request input data by replacing
|
||||||
|
* all occurrences of '\r\n' with '\n' recursively for strings, arrays, and objects.
|
||||||
|
*/
|
||||||
|
import type { HttpContext } from '@adonisjs/core/http';
|
||||||
|
import type { NextFn } from '@adonisjs/core/types/http';
|
||||||
|
|
||||||
|
export default class NormalizeNewlinesMiddleware {
|
||||||
|
async handle(ctx: HttpContext, next: NextFn) {
|
||||||
|
// Function to recursively normalize newlines
|
||||||
|
const normalizeNewlines = (input: any): any => {
|
||||||
|
if (typeof input === 'string') {
|
||||||
|
return input.replace(/\r\n/g, '\n');
|
||||||
|
} else if (Array.isArray(input)) {
|
||||||
|
return input.map((item) => normalizeNewlines(item));
|
||||||
|
} else if (typeof input === 'object' && input !== null) {
|
||||||
|
for (const key in input) {
|
||||||
|
input[key] = normalizeNewlines(input[key]);
|
||||||
|
}
|
||||||
|
return input;
|
||||||
|
}
|
||||||
|
return input;
|
||||||
|
};
|
||||||
|
/**
|
||||||
|
* Middleware logic goes here (before the next call)
|
||||||
|
*/
|
||||||
|
// console.log(ctx)
|
||||||
|
// Get all request input
|
||||||
|
const input = ctx.request.all();
|
||||||
|
|
||||||
|
// Normalize newlines in text inputs
|
||||||
|
const normalizedInput = normalizeNewlines(input);
|
||||||
|
|
||||||
|
// Replace request input with normalized data
|
||||||
|
ctx.request.updateBody(normalizedInput);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Call next method in the pipeline and return its output
|
||||||
|
*/
|
||||||
|
const output = await next();
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
}
|
|
@ -43,7 +43,7 @@ export const createDatasetValidator = vine.compile(
|
||||||
descriptions: vine
|
descriptions: vine
|
||||||
.array(
|
.array(
|
||||||
vine.object({
|
vine.object({
|
||||||
value: vine.string().trim().minLength(3).maxLength(255),
|
value: vine.string().trim().minLength(3).maxLength(2500),
|
||||||
type: vine.enum(Object.values(DescriptionTypes)),
|
type: vine.enum(Object.values(DescriptionTypes)),
|
||||||
language: vine
|
language: vine
|
||||||
.string()
|
.string()
|
||||||
|
@ -164,7 +164,7 @@ export const updateDatasetValidator = vine.compile(
|
||||||
titles: vine
|
titles: vine
|
||||||
.array(
|
.array(
|
||||||
vine.object({
|
vine.object({
|
||||||
value: vine.string().trim().minLength(3).maxLength(255),
|
value: vine.string().trim().minLength(3).maxLength(2500),
|
||||||
type: vine.enum(Object.values(TitleTypes)),
|
type: vine.enum(Object.values(TitleTypes)),
|
||||||
language: vine
|
language: vine
|
||||||
.string()
|
.string()
|
||||||
|
@ -302,6 +302,7 @@ let messagesProvider = new SimpleMessagesProvider({
|
||||||
'titles.*.language.translatedLanguage': 'The language of the translated title must be different from the language of the dataset',
|
'titles.*.language.translatedLanguage': 'The language of the translated title must be different from the language of the dataset',
|
||||||
|
|
||||||
'descriptions.0.value.minLength': 'Main Abstract must be at least {{ min }} characters long',
|
'descriptions.0.value.minLength': 'Main Abstract must be at least {{ min }} characters long',
|
||||||
|
'descriptions.0.value.maxLength': 'Main Abstract must be less than {{ max }} characters long',
|
||||||
'descriptions.0.value.required': 'Main Abstract is required',
|
'descriptions.0.value.required': 'Main Abstract is required',
|
||||||
'descriptions.*.value.required': 'Additional description is required, if defined',
|
'descriptions.*.value.required': 'Additional description is required, if defined',
|
||||||
'descriptions.*.type.required': 'Additional description type is required',
|
'descriptions.*.type.required': 'Additional description type is required',
|
||||||
|
@ -311,6 +312,7 @@ let messagesProvider = new SimpleMessagesProvider({
|
||||||
|
|
||||||
'authors.array.minLength': 'at least {{ min }} author must be defined',
|
'authors.array.minLength': 'at least {{ min }} author must be defined',
|
||||||
'authors.distinct': 'The {{ field }} array must have unique values based on the {{ fields }} attribute.',
|
'authors.distinct': 'The {{ field }} array must have unique values based on the {{ fields }} attribute.',
|
||||||
|
'authors.*.email.isUnique': 'the email of the new creator already exists in the database',
|
||||||
'contributors.*.pivot_contributor_type.required': 'contributor type is required, if defined',
|
'contributors.*.pivot_contributor_type.required': 'contributor type is required, if defined',
|
||||||
'contributors.distinct': 'The {{ field }} array must have unique values based on the {{ fields }} attribute.',
|
'contributors.distinct': 'The {{ field }} array must have unique values based on the {{ fields }} attribute.',
|
||||||
|
|
||||||
|
|
891
package-lock.json
generated
891
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
|
@ -85,5 +85,6 @@
|
||||||
"assets/images/marker-icon.png": "http://localhost:8080/assets/images/marker-icon.2b3e1faf.png",
|
"assets/images/marker-icon.png": "http://localhost:8080/assets/images/marker-icon.2b3e1faf.png",
|
||||||
"assets/images/layers-2x.png": "http://localhost:8080/assets/images/layers-2x.8f2c4d11.png",
|
"assets/images/layers-2x.png": "http://localhost:8080/assets/images/layers-2x.8f2c4d11.png",
|
||||||
"assets/images/layers.png": "http://localhost:8080/assets/images/layers.416d9136.png",
|
"assets/images/layers.png": "http://localhost:8080/assets/images/layers.416d9136.png",
|
||||||
"assets/images/Close.svg": "http://localhost:8080/assets/images/Close.e4887675.svg"
|
"assets/images/Close.svg": "http://localhost:8080/assets/images/Close.e4887675.svg",
|
||||||
|
"assets/vendors-node_modules_vue-facing-decorator_dist_esm_index_js-node_modules_vue-facing-decorator-818045.js": "http://localhost:8080/assets/vendors-node_modules_vue-facing-decorator_dist_esm_index_js-node_modules_vue-facing-decorator-818045.js"
|
||||||
}
|
}
|
|
@ -374,6 +374,9 @@
|
||||||
<setSpec>
|
<setSpec>
|
||||||
<xsl:text>open_access</xsl:text>
|
<xsl:text>open_access</xsl:text>
|
||||||
</setSpec>
|
</setSpec>
|
||||||
|
<setSpec>
|
||||||
|
<xsl:text>openaire_data</xsl:text>
|
||||||
|
</setSpec>
|
||||||
<setSpec>
|
<setSpec>
|
||||||
<xsl:text>doc-type:ResearchData</xsl:text>
|
<xsl:text>doc-type:ResearchData</xsl:text>
|
||||||
</setSpec>
|
</setSpec>
|
||||||
|
|
|
@ -43,6 +43,14 @@ const props = defineProps({
|
||||||
type: [String, Number, Boolean, Array, Object],
|
type: [String, Number, Boolean, Array, Object],
|
||||||
default: '',
|
default: '',
|
||||||
},
|
},
|
||||||
|
showCharCount: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
maxInputLength: {
|
||||||
|
type: Number,
|
||||||
|
default: null,
|
||||||
|
},
|
||||||
required: Boolean,
|
required: Boolean,
|
||||||
borderless: Boolean,
|
borderless: Boolean,
|
||||||
transparent: Boolean,
|
transparent: Boolean,
|
||||||
|
@ -110,36 +118,25 @@ if (props.ctrlKFocus) {
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="relative">
|
<div class="relative">
|
||||||
<select v-if="computedType === 'select'" :id="id" v-model="computedValue" :name="name" :class="inputElClass" :disabled="isReadOnly">
|
<select v-if="computedType === 'select'" :id="id" v-model="computedValue" :name="name" :class="inputElClass"
|
||||||
|
:disabled="isReadOnly">
|
||||||
<option v-if="placeholder" class="text-opacity-25" value="" disabled selected>{{ placeholder }}</option>
|
<option v-if="placeholder" class="text-opacity-25" value="" disabled selected>{{ placeholder }}</option>
|
||||||
<option v-for="(option, index) in options" :key="index" :value="option.value ?? index">
|
<option v-for="(option, index) in options" :key="index" :value="option.value ?? index">
|
||||||
{{ option.label ?? option }}
|
{{ option.label ?? option }}
|
||||||
</option>
|
</option>
|
||||||
</select>
|
</select>
|
||||||
<textarea
|
<textarea v-else-if="computedType === 'textarea'" :id="id" v-model="computedValue" :class="inputElClass"
|
||||||
v-else-if="computedType === 'textarea'"
|
:name="name" :placeholder="placeholder" :required="required" />
|
||||||
:id="id"
|
<input v-else :id="id" ref="inputEl" v-model="computedValue" :name="name" :inputmode="inputmode"
|
||||||
v-model="computedValue"
|
:autocomplete="autocomplete" :required="required" :placeholder="placeholder" :type="computedType"
|
||||||
:class="inputElClass"
|
:class="inputElClass" :readonly="isReadOnly" />
|
||||||
:name="name"
|
|
||||||
:placeholder="placeholder"
|
|
||||||
:required="required"
|
|
||||||
/>
|
|
||||||
<input
|
|
||||||
v-else
|
|
||||||
:id="id"
|
|
||||||
ref="inputEl"
|
|
||||||
v-model="computedValue"
|
|
||||||
:name="name"
|
|
||||||
:inputmode="inputmode"
|
|
||||||
:autocomplete="autocomplete"
|
|
||||||
:required="required"
|
|
||||||
:placeholder="placeholder"
|
|
||||||
:type="computedType"
|
|
||||||
:class="inputElClass"
|
|
||||||
:readonly="isReadOnly"
|
|
||||||
/>
|
|
||||||
<FormControlIcon v-if="icon" :icon="icon" :h="controlIconH" />
|
<FormControlIcon v-if="icon" :icon="icon" :h="controlIconH" />
|
||||||
<slot />
|
<slot />
|
||||||
|
<span v-if="showCharCount" class="message-counter" :class="{ 'text-red-500': maxInputLength && maxInputLength < computedValue.length }">
|
||||||
|
{{ computedValue.length }}
|
||||||
|
<template v-if="maxInputLength">
|
||||||
|
/ {{ maxInputLength }}
|
||||||
|
</template>
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -669,7 +669,7 @@ Removes a selected keyword
|
||||||
:class="{ 'text-red-400': form.errors['descriptions.0.value'] }"
|
:class="{ 'text-red-400': form.errors['descriptions.0.value'] }"
|
||||||
class="w-full mx-2 flex-1">
|
class="w-full mx-2 flex-1">
|
||||||
<FormControl required v-model="form.descriptions[0].value" type="textarea"
|
<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"
|
<div class="text-red-400 text-sm"
|
||||||
v-if="form.errors['descriptions.0.value'] && Array.isArray(form.errors['descriptions.0.value'])">
|
v-if="form.errors['descriptions.0.value'] && Array.isArray(form.errors['descriptions.0.value'])">
|
||||||
{{ form.errors['descriptions.0.value'].join(', ') }}
|
{{ form.errors['descriptions.0.value'].join(', ') }}
|
||||||
|
@ -701,7 +701,7 @@ Removes a selected keyword
|
||||||
:class="{ 'text-red-400': form.errors[`descriptions.${index}.value`] }"
|
:class="{ 'text-red-400': form.errors[`descriptions.${index}.value`] }"
|
||||||
class="w-full mx-2 flex-1">
|
class="w-full mx-2 flex-1">
|
||||||
<FormControl required v-model="form.descriptions[index].value" type="text"
|
<FormControl required v-model="form.descriptions[index].value" type="text"
|
||||||
placeholder="[enter additional description]">
|
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`] &&
|
<div class="text-red-400 text-sm" v-if="form.errors[`descriptions.${index}.value`] &&
|
||||||
Array.isArray(form.errors[`descriptions.${index}.value`])
|
Array.isArray(form.errors[`descriptions.${index}.value`])
|
||||||
">
|
">
|
||||||
|
|
|
@ -65,15 +65,15 @@ const handleSubmit = async (e: Event) => {
|
||||||
</SectionTitleLineWithButton>
|
</SectionTitleLineWithButton>
|
||||||
<CardBox form @submit.prevent="handleSubmit">
|
<CardBox form @submit.prevent="handleSubmit">
|
||||||
<FormValidationErrors v-bind:errors="errors" />
|
<FormValidationErrors v-bind:errors="errors" />
|
||||||
<div class="lex flex-col md:flex-row mb-3">
|
<div class="lex flex-col md:flex-row mb-3">
|
||||||
<label for="elevation-option-one" class="pure-radio">
|
|
||||||
<input id="elevation-option-one" type="radio" v-model="form.preferation" value="yes_preferation" />
|
|
||||||
preferred reviewer
|
|
||||||
</label>
|
|
||||||
<label for="elevation-option-two" class="pure-radio">
|
<label for="elevation-option-two" class="pure-radio">
|
||||||
<input id="elevation-option-two" type="radio" v-model="form.preferation" value="no_preferation" />
|
<input id="elevation-option-two" type="radio" v-model="form.preferation" value="no_preferation" />
|
||||||
no preferred reviewer
|
no preferred reviewer
|
||||||
</label>
|
</label>
|
||||||
|
<label for="elevation-option-one" class="pure-radio">
|
||||||
|
<input id="elevation-option-one" type="radio" v-model="form.preferation" value="yes_preferation" />
|
||||||
|
preferred reviewer
|
||||||
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="isPreferationRequired == true">
|
<div v-if="isPreferationRequired == true">
|
||||||
<FormField label="preferred reviewer" :class="{ 'text-red-400': form.errors.preferred_reviewer }">
|
<FormField label="preferred reviewer" :class="{ 'text-red-400': form.errors.preferred_reviewer }">
|
||||||
|
|
|
@ -11,7 +11,7 @@ import { darkModeKey, styleKey } from '@/config';
|
||||||
// import type { DefineComponent } from 'vue';
|
// import type { DefineComponent } from 'vue';
|
||||||
// import { resolvePageComponent } from '@adonisjs/inertia/helpers';
|
// import { resolvePageComponent } from '@adonisjs/inertia/helpers';
|
||||||
const pinia = createPinia();
|
const pinia = createPinia();
|
||||||
import i18n from './i18n';
|
// import i18n from './i18n';
|
||||||
import { EmitterPlugin } from '@/EmitterDirective';
|
import { EmitterPlugin } from '@/EmitterDirective';
|
||||||
|
|
||||||
import { initRoutes } from '@eidellev/adonis-stardust/client/index.js';
|
import { initRoutes } from '@eidellev/adonis-stardust/client/index.js';
|
||||||
|
@ -63,7 +63,7 @@ createInertiaApp({
|
||||||
createApp({ render: () => h(App, props) })
|
createApp({ render: () => h(App, props) })
|
||||||
.use(plugin)
|
.use(plugin)
|
||||||
.use(pinia)
|
.use(pinia)
|
||||||
.use(i18n)
|
// .use(i18n)
|
||||||
.use(EmitterPlugin)
|
.use(EmitterPlugin)
|
||||||
// .component('inertia-link', Link)
|
// .component('inertia-link', Link)
|
||||||
.mount(el);
|
.mount(el);
|
||||||
|
|
|
@ -37,7 +37,7 @@ router.use([
|
||||||
// () => import('@adonisjs/inertia/inertia_middleware'),
|
// () => import('@adonisjs/inertia/inertia_middleware'),
|
||||||
() => import('@adonisjs/auth/initialize_auth_middleware'),
|
() => import('@adonisjs/auth/initialize_auth_middleware'),
|
||||||
() => import('#middleware/stardust_middleware'),
|
() => import('#middleware/stardust_middleware'),
|
||||||
// () => import('@eidellev/adonis-stardust/build/middleware/Stardust.js'),
|
() => import('#middleware/normalize_newlines_middleware'),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Reference in New Issue
Block a user