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

@ -103,9 +103,9 @@
<svg class="w-4 h-4 absolute left-2.5 top-3.5" v-show="computedValue.length >= 2"
xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" @click="() => {
computedValue = '';
data.isOpen = false;
}
computedValue = '';
data.isOpen = false;
}
">
<path stroke-linecap="round" stroke-linejoin="round" d="M6 18L18 6M6 6l12 12" />
</svg>
@ -181,17 +181,6 @@ let computedValue = computed({
},
});
// const dropDownClass = computed(() => {
// const base = [
// 'z-10 bg-white divide-y divide-gray-100 rounded-lg shadow w-44 dark:bg-gray-700',
// props.borderless ? 'border-0' : 'border',
// props.transparent ? 'bg-transparent' : 'bg-white dark:bg-slate-800',
// // props.isReadOnly ? 'bg-gray-50 dark:bg-slate-600' : 'bg-white dark:bg-slate-800',
// statesToggle.value == true ? 'block' : 'hidden',
// ];
// return base;
// });
const inputElClass = computed(() => {
// class="block p-2.5 w-full z-20 text-sm text-gray-900 bg-gray-50 rounded-r-lg border-l-gray-50 border-l-2 border border-gray-300
// focus:ring-blue-500 focus:border-blue-500 dark:bg-gray-700 dark:border-l-gray-700 dark:border-gray-600
@ -272,7 +261,7 @@ const setLanguage = (item) => {
data.isOpen = false;
};
const ENDPOINT = 'https://resource.geolba.ac.at/PoolParty/sparql/geoera';
const ENDPOINT = 'https://resource.geolba.ac.at/PoolParty/sparql/keyword';
// const USER_LANG = 'de';
// watch(search, async () => {
@ -306,7 +295,34 @@ async function handleInput(e: Event) {
// }
// }
async function request(url, param) {
async function request(url: string, param: string) {
try {
let query = encodeURIComponent(`
PREFIX skos:<http://www.w3.org/2004/02/skos/core#>
select distinct (?label as ?title) ?s (strlen(str(?label)) as ?strlen)
where
{
VALUES ?n {"${sparqlEncode(param.toLowerCase())}"}
?s skos:prefLabel ?label .
filter(lang(?label)='${language.value}')
filter(regex(?label, ?n, "i")) # Case-insensitive regex match
}
order by ?label ?strlen
`);
let response = await searchTerm(url + '?query=' + query + '&format=application/json');
error.value = '';
data.results = getResults(response);
// // this.results = res.data;
// // this.loading = false;
} catch (error) {
error.value = error.message;
// this.loading = false;
}
}
async function requestOriginal(url: string, param: string) {
try {
let query = encodeURIComponent(`
PREFIX dcterms:<http://purl.org/dc/terms/>
@ -316,8 +332,15 @@ async function request(url, param) {
VALUES ?n {"${sparqlEncode(param.toLowerCase())}"}
VALUES ?p { skos:prefLabel skos:altLabel }
?s a skos:Concept; ?p ?lEN . FILTER((lang(?lEN)="en"))
# FILTER(regex(str(?s), 'ncl/geoera/keyword'))
OPTIONAL{?s ?p ?l . FILTER(lang(?l)="${language.value}")}
BIND(COALESCE(?l, ?lEN) AS ?L) . FILTER(regex(?L,?n,"i"))
FILTER(!regex(?L, "\(category\)", "i"))
FILTER(!regex(?L, "\(kategorie\)", "i"))
?s skos:prefLabel ?plEN . FILTER((lang(?plEN)="en"))
OPTIONAL{?s skos:prefLabel ?pl . FILTER(lang(?pl)="${language.value}")}
BIND(COALESCE(?pl, ?plEN) AS ?title)
@ -327,6 +350,7 @@ async function request(url, param) {
ORDER BY ?sort
LIMIT 100`);
let response = await searchTerm(url + '?query=' + query + '&format=application/json');
error.value = '';
data.results = getResults(response);
@ -351,7 +375,7 @@ function getResults(response) {
return [];
}
function sparqlEncode(str) {
function sparqlEncode(str: string) {
var hex, i;
str = str.toLowerCase();
var result = '';
@ -383,14 +407,4 @@ function clear() {
// this.$emit("clear");
}
// function onEnter() {
// if (Array.isArray(data.results) && data.results.length && selectedIndex.value !== -1 && selectedIndex.value < data.results.length) {
// //this.display = this.results[this.selectedIndex];
// const person = data.results[selectedIndex.value];
// // this.$emit('person', person);
// emit('person', person);
// clear();
// selectedIndex.value = -1;
// }
// }
</script>