- Implemented dataset editing functionality for editor roles, including fetching, updating, and categorizing datasets. - Added routes and controller actions for editing, updating, and categorizing datasets within the editor interface. - Integrated UI components for managing dataset metadata, subjects, references, and files. - Enhanced keyword management with features for adding, editing, and deleting keywords, including handling keywords used by multiple datasets. - Improved reference management with features for adding, editing, and deleting dataset references. - Added validation for dataset updates using the `updateEditorDatasetValidator`. - Updated the dataset edit form to include components for managing titles, descriptions, authors, contributors, licenses, coverage, subjects, references, and files. - Implemented transaction management for dataset updates to ensure data consistency. - Added a download route for files associated with datasets. - Improved the UI for displaying and interacting with datasets in the editor index view, including adding edit and categorize buttons. - Fixed an issue where the file size was not correctly calculated. - Added a tooltip to the keyword value column in the TableKeywords component to explain the editability of keywords. - Added a section to display keywords that are marked for deletion. - Added a section to display references that are marked for deletion. - Added a restore button to the references to delete section to restore references. - Updated the SearchCategoryAutocomplete component to support read-only mode. - Updated the FormControl component to support read-only mode. - Added icons and styling improvements to various components. - Added a default value for subjectsToDelete and referencesToDelete in the dataset model. - Updated the FooterBar component to use the JustboilLogo component. - Updated the app.ts file to fetch chart data without a year parameter. - Updated the Login.vue file to invert the logo in dark mode. - Updated the AccountInfo.vue file to add a Head component.
427 lines
21 KiB
Vue
427 lines
21 KiB
Vue
<template>
|
|
<div class="relative">
|
|
<div class="flex">
|
|
<!-- <label for="search-dropdown" class="mb-2 text-sm font-medium text-gray-900 sr-only dark:text-white">Your Email</label> -->
|
|
<div class="relative" data-te-dropdown-ref>
|
|
<button id="states-button" data-dropdown-toggle="dropdown-states"
|
|
class="whitespace-nowrap h-12 z-10 inline-flex items-center py-2.5 px-4 text-sm font-medium text-center text-gray-500 bg-gray-100 border border-gray-300 rounded-l-lg hover:bg-gray-200 focus:ring-4 focus:outline-none focus:ring-gray-100 dark:bg-gray-700 dark:hover:bg-gray-600 dark:focus:ring-gray-700 dark:text-white dark:border-gray-600"
|
|
type="button" :disabled="isReadOnly" @click.prevent="showStates">
|
|
<!-- <svg aria-hidden="true" class="h-3 mr-2" viewBox="0 0 15 12" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
<rect x="0.5" width="14" height="12" rx="2" fill="white" />
|
|
<mask id="mask0_12694_49953" style="mask-type: alpha" maskUnits="userSpaceOnUse" x="0" y="0" width="15" height="12">
|
|
<rect x="0.5" width="14" height="12" rx="2" fill="white" />
|
|
</mask>
|
|
<g mask="url(#mask0_12694_49953)">
|
|
<path
|
|
fill-rule="evenodd"
|
|
clip-rule="evenodd"
|
|
d="M14.5 0H0.5V0.8H14.5V0ZM14.5 1.6H0.5V2.4H14.5V1.6ZM0.5 3.2H14.5V4H0.5V3.2ZM14.5 4.8H0.5V5.6H14.5V4.8ZM0.5 6.4H14.5V7.2H0.5V6.4ZM14.5 8H0.5V8.8H14.5V8ZM0.5 9.6H14.5V10.4H0.5V9.6ZM14.5 11.2H0.5V12H14.5V11.2Z"
|
|
fill="#D02F44"
|
|
/>
|
|
<rect x="0.5" width="6" height="5.6" fill="#46467F" />
|
|
<g filter="url(#filter0_d_12694_49953)">
|
|
<path
|
|
fill-rule="evenodd"
|
|
clip-rule="evenodd"
|
|
d="M1.83317 1.20005C1.83317 1.42096 1.68393 1.60005 1.49984 1.60005C1.31574 1.60005 1.1665 1.42096 1.1665 1.20005C1.1665 0.979135 1.31574 0.800049 1.49984 0.800049C1.68393 0.800049 1.83317 0.979135 1.83317 1.20005ZM3.1665 1.20005C3.1665 1.42096 3.01727 1.60005 2.83317 1.60005C2.64908 1.60005 2.49984 1.42096 2.49984 1.20005C2.49984 0.979135 2.64908 0.800049 2.83317 0.800049C3.01727 0.800049 3.1665 0.979135 3.1665 1.20005ZM4.1665 1.60005C4.3506 1.60005 4.49984 1.42096 4.49984 1.20005C4.49984 0.979135 4.3506 0.800049 4.1665 0.800049C3.98241 0.800049 3.83317 0.979135 3.83317 1.20005C3.83317 1.42096 3.98241 1.60005 4.1665 1.60005ZM5.83317 1.20005C5.83317 1.42096 5.68393 1.60005 5.49984 1.60005C5.31574 1.60005 5.1665 1.42096 5.1665 1.20005C5.1665 0.979135 5.31574 0.800049 5.49984 0.800049C5.68393 0.800049 5.83317 0.979135 5.83317 1.20005ZM2.1665 2.40005C2.3506 2.40005 2.49984 2.22096 2.49984 2.00005C2.49984 1.77913 2.3506 1.60005 2.1665 1.60005C1.98241 1.60005 1.83317 1.77913 1.83317 2.00005C1.83317 2.22096 1.98241 2.40005 2.1665 2.40005ZM3.83317 2.00005C3.83317 2.22096 3.68393 2.40005 3.49984 2.40005C3.31574 2.40005 3.1665 2.22096 3.1665 2.00005C3.1665 1.77913 3.31574 1.60005 3.49984 1.60005C3.68393 1.60005 3.83317 1.77913 3.83317 2.00005ZM4.83317 2.40005C5.01726 2.40005 5.1665 2.22096 5.1665 2.00005C5.1665 1.77913 5.01726 1.60005 4.83317 1.60005C4.64908 1.60005 4.49984 1.77913 4.49984 2.00005C4.49984 2.22096 4.64908 2.40005 4.83317 2.40005ZM5.83317 2.80005C5.83317 3.02096 5.68393 3.20005 5.49984 3.20005C5.31574 3.20005 5.1665 3.02096 5.1665 2.80005C5.1665 2.57914 5.31574 2.40005 5.49984 2.40005C5.68393 2.40005 5.83317 2.57914 5.83317 2.80005ZM4.1665 3.20005C4.3506 3.20005 4.49984 3.02096 4.49984 2.80005C4.49984 2.57914 4.3506 2.40005 4.1665 2.40005C3.98241 2.40005 3.83317 2.57914 3.83317 2.80005C3.83317 3.02096 3.98241 3.20005 4.1665 3.20005ZM3.1665 2.80005C3.1665 3.02096 3.01727 3.20005 2.83317 3.20005C2.64908 3.20005 2.49984 3.02096 2.49984 2.80005C2.49984 2.57914 2.64908 2.40005 2.83317 2.40005C3.01727 2.40005 3.1665 2.57914 3.1665 2.80005ZM1.49984 3.20005C1.68393 3.20005 1.83317 3.02096 1.83317 2.80005C1.83317 2.57914 1.68393 2.40005 1.49984 2.40005C1.31574 2.40005 1.1665 2.57914 1.1665 2.80005C1.1665 3.02096 1.31574 3.20005 1.49984 3.20005ZM2.49984 3.60005C2.49984 3.82096 2.3506 4.00005 2.1665 4.00005C1.98241 4.00005 1.83317 3.82096 1.83317 3.60005C1.83317 3.37913 1.98241 3.20005 2.1665 3.20005C2.3506 3.20005 2.49984 3.37913 2.49984 3.60005ZM3.49984 4.00005C3.68393 4.00005 3.83317 3.82096 3.83317 3.60005C3.83317 3.37913 3.68393 3.20005 3.49984 3.20005C3.31574 3.20005 3.1665 3.37913 3.1665 3.60005C3.1665 3.82096 3.31574 4.00005 3.49984 4.00005ZM5.1665 3.60005C5.1665 3.82096 5.01726 4.00005 4.83317 4.00005C4.64908 4.00005 4.49984 3.82096 4.49984 3.60005C4.49984 3.37913 4.64908 3.20005 4.83317 3.20005C5.01726 3.20005 5.1665 3.37913 5.1665 3.60005ZM5.49984 4.80005C5.68393 4.80005 5.83317 4.62096 5.83317 4.40005C5.83317 4.17913 5.68393 4.00005 5.49984 4.00005C5.31574 4.00005 5.1665 4.17913 5.1665 4.40005C5.1665 4.62096 5.31574 4.80005 5.49984 4.80005ZM4.49984 4.40005C4.49984 4.62096 4.3506 4.80005 4.1665 4.80005C3.98241 4.80005 3.83317 4.62096 3.83317 4.40005C3.83317 4.17913 3.98241 4.00005 4.1665 4.00005C4.3506 4.00005 4.49984 4.17913 4.49984 4.40005ZM2.83317 4.80005C3.01727 4.80005 3.1665 4.62096 3.1665 4.40005C3.1665 4.17913 3.01727 4.00005 2.83317 4.00005C2.64908 4.00005 2.49984 4.17913 2.49984 4.40005C2.49984 4.62096 2.64908 4.80005 2.83317 4.80005ZM1.83317 4.40005C1.83317 4.62096 1.68393 4.80005 1.49984 4.80005C1.31574 4.80005 1.1665 4.62096 1.1665 4.40005C1.1665 4.17913 1.31574 4.00005 1.49984 4.00005C1.68393 4.00005 1.83317 4.17913 1.83317 4.40005Z"
|
|
fill="url(#paint0_linear_12694_49953)"
|
|
/>
|
|
</g>
|
|
</g>
|
|
<defs>
|
|
<filter
|
|
id="filter0_d_12694_49953"
|
|
x="1.1665"
|
|
y="0.800049"
|
|
width="4.6665"
|
|
height="5"
|
|
filterUnits="userSpaceOnUse"
|
|
color-interpolation-filters="sRGB"
|
|
>
|
|
<feFlood flood-opacity="0" result="BackgroundImageFix" />
|
|
<feColorMatrix
|
|
in="SourceAlpha"
|
|
type="matrix"
|
|
values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"
|
|
result="hardAlpha"
|
|
/>
|
|
<feOffset dy="1" />
|
|
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.06 0" />
|
|
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_12694_49953" />
|
|
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_12694_49953" result="shape" />
|
|
</filter>
|
|
<linearGradient
|
|
id="paint0_linear_12694_49953"
|
|
x1="1.1665"
|
|
y1="0.800049"
|
|
x2="1.1665"
|
|
y2="4.80005"
|
|
gradientUnits="userSpaceOnUse"
|
|
>
|
|
<stop stop-color="white" />
|
|
<stop offset="1" stop-color="#F0F0F0" />
|
|
</linearGradient>
|
|
</defs>
|
|
</svg> -->
|
|
<!-- eng -->
|
|
{{ language }}
|
|
<svg aria-hidden="true" class="w-4 h-4 ml-1" fill="currentColor" viewBox="0 0 20 20" v-if="!isReadOnly"
|
|
xmlns="http://www.w3.org/2000/svg">
|
|
<path fill-rule="evenodd"
|
|
d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z"
|
|
clip-rule="evenodd"></path>
|
|
</svg>
|
|
</button>
|
|
<!-- class="w-full overflow-visible z-10 bg-white divide-y divide-gray-100 rounded-lg shadow w-44 dark:bg-gray-700"-->
|
|
<div id="dropdown-states" v-show="statesToggle"
|
|
class="absolute z-[1000] float-left m-0 min-w-max list-none overflow-hidden rounded-lg border-none bg-white bg-clip-padding text-left text-base shadow-lg dark:bg-neutral-700">
|
|
<ul class="py-2 text-sm text-gray-700 dark:text-gray-200" aria-labelledby="states-button">
|
|
<li v-for="(item, index) in dropDownStates" :key="index" @click.prevent="setLanguage(item)">
|
|
<button type="button"
|
|
class="inline-flex w-full px-4 py-2 text-sm text-gray-700 hover:bg-gray-100 dark:text-gray-400 dark:hover:bg-gray-600 dark:hover:text-white">
|
|
<div class="inline-flex items-center">
|
|
<span v-html="item.svg"></span>
|
|
{{ item.name }}
|
|
</div>
|
|
</button>
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="w-full relative">
|
|
<!-- :class="inputElClass" -->
|
|
<!-- 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 dark:placeholder-gray-400 dark:text-white dark:focus:border-blue-500" -->
|
|
<input v-model="computedValue" type="text" :name="props.name" autocomplete="off" :class="inputElClass"
|
|
placeholder="Search Keywords..." required @input="handleInput" :readonly="isReadOnly" />
|
|
<!-- v-model="data.search" -->
|
|
<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">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
|
d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" />
|
|
</svg>
|
|
|
|
<svg class="w-4 h-4 absolute left-2.5 top-3.5" v-show="computedValue.length >= 2 && !isReadOnly"
|
|
xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" @click="() => {
|
|
computedValue = '';
|
|
data.isOpen = false;
|
|
}
|
|
">
|
|
<path stroke-linecap="round" stroke-linejoin="round" d="M6 18L18 6M6 6l12 12" />
|
|
</svg>
|
|
</div>
|
|
<slot />
|
|
</div>
|
|
<ul v-if="data.isOpen"
|
|
class="absolute absolute z-[1000] float-left m-0 list-none bg-white dark:bg-slate-800 m-0 max-h-32 overflow-y-auto scroll-smooth min-w-full">
|
|
<li class="leading-3 pl-4 py-3 border-b-2 line border-gray-100 relative cursor-pointer hover:bg-yellow-50 hover:text-gray-900"
|
|
v-for="(item, index) in data.results" @click.prevent="setResult(item)" :key="index">
|
|
<!-- <a href="${BASE}?uri=${a.s.value}&lang=${USER_LANG}"> -->
|
|
<strong class="text-sm"> {{ item.title.value }}</strong>
|
|
<!-- </a> -->
|
|
<br />
|
|
<!-- <span class="searchPropTyp">URI: </span>
|
|
<span class="searchResultURI text-info"> {{ item.s.value }} </span> -->
|
|
<br />
|
|
<!-- <p class="searchResultText">{{ createSearchResultsText(item.text.value, searchText) }}</p> -->
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import { reactive, ref, computed, Ref } from 'vue';
|
|
import axios from 'axios';
|
|
|
|
let props = defineProps({
|
|
name: {
|
|
type: String,
|
|
required: false,
|
|
default: 'autocomplete',
|
|
},
|
|
// source: {
|
|
// type: [String, Array, Function],
|
|
// required: true,
|
|
// default: '',
|
|
// },
|
|
label: {
|
|
type: String,
|
|
required: false,
|
|
default: 'name',
|
|
},
|
|
responseProperty: {
|
|
type: String,
|
|
required: false,
|
|
default: 'name',
|
|
},
|
|
placeholder: {
|
|
type: String,
|
|
default: null,
|
|
},
|
|
icon: {
|
|
type: String,
|
|
default: null,
|
|
},
|
|
modelValue: {
|
|
type: String,
|
|
default: '',
|
|
},
|
|
isReadOnly: {
|
|
type: Boolean,
|
|
default: false,
|
|
},
|
|
required: Boolean,
|
|
borderless: Boolean,
|
|
transparent: Boolean,
|
|
ctrlKFocus: Boolean,
|
|
});
|
|
|
|
const emit = defineEmits(['update:modelValue', 'subject']);
|
|
let computedValue = computed({
|
|
get: () => props.modelValue,
|
|
set: (value) => {
|
|
// props.modelValue = value;
|
|
emit('update:modelValue', value);
|
|
},
|
|
});
|
|
|
|
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
|
|
// dark:placeholder-gray-400 dark:text-white dark:focus:border-blue-500"
|
|
const base = [
|
|
'block p-2.5 w-full z-20 text-sm text-gray-900 bg-gray-50 rounded-r-lg',
|
|
'dark:placeholder-gray-400 dark:text-white dark:focus:border-blue-500',
|
|
'h-12',
|
|
props.borderless ? 'border-0' : 'border',
|
|
props.transparent && 'bg-transparent',
|
|
// props.isReadOnly ? 'bg-gray-50 dark:bg-slate-600' : 'bg-white dark:bg-slate-800',
|
|
];
|
|
// if (props.icon) {
|
|
base.push('pl-10');
|
|
if (props.isReadOnly) {
|
|
// Read-only: no focus ring, grayed-out text and border, and disabled cursor.
|
|
base.push('bg-gray-50', 'dark:bg-slate-600', 'border', 'border-gray-300', 'dark:border-slate-600', 'text-gray-500', 'cursor-not-allowed', 'focus:outline-none', 'focus:ring-0', 'focus:border-gray-300');
|
|
} else {
|
|
// Actionable field: focus ring, white/dark background, and darker border.
|
|
base.push('bg-white dark:bg-slate-800', 'focus:ring focus:outline-none', 'border', 'border-gray-700');
|
|
}
|
|
// }
|
|
return base;
|
|
});
|
|
|
|
// let search = ref('');
|
|
let data = reactive({
|
|
// search: search,
|
|
isOpen: false,
|
|
results: [] as Array<any>,
|
|
});
|
|
let error = ref('');
|
|
// let selectedIndex: Ref<number> = ref(0);
|
|
// const ul: Ref<Array<HTMLLIElement>> = ref([]);
|
|
|
|
let dropDownStates = reactive([
|
|
{
|
|
name: 'English',
|
|
label: 'en',
|
|
svg: `
|
|
<svg aria-hidden="true" class="h-3.5 w-3.5 rounded-full mr-2" xmlns="http://www.w3.org/2000/svg" id="flag-icons-us" viewBox="0 0 512 512">
|
|
<path fill="#bd3d44" d="M0 0h640v480H0"/>
|
|
<path stroke="#fff" stroke-width="37" d="M0 55.3h640M0 129h640M0 203h640M0 277h640M0 351h640M0 425h640"/>
|
|
<path fill="#192f5d" d="M0 0h364.8v258.5H0"/>
|
|
<marker id="a" markerHeight="30" markerWidth="30">
|
|
<path fill="#fff" d="m14 0 9 27L0 10h28L5 27z"/>
|
|
</marker>
|
|
<path fill="none" marker-mid="url(#a)" d="m0 0 16 11h61 61 61 61 60L47 37h61 61 60 61L16 63h61 61 61 61 60L47 89h61 61 60 61L16 115h61 61 61 61 60L47 141h61 61 60 61L16 166h61 61 61 61 60L47 192h61 61 60 61L16 218h61 61 61 61 60L0 0"/>
|
|
</svg>`,
|
|
},
|
|
{
|
|
name: 'German',
|
|
label: 'de',
|
|
svg: `
|
|
<svg aria-hidden="true" class="h-3.5 w-3.5 rounded-full mr-2" xmlns="http://www.w3.org/2000/svg" id="flag-icons-at" viewBox="0 0 512 512">
|
|
<g fill-rule="evenodd">
|
|
<path fill="#fff" d="M640 480H0V0h640z"/>
|
|
<path fill="#c8102e" d="M640 480H0V320h640zm0-319.9H0V.1h640z"/>
|
|
</g>
|
|
</svg>`,
|
|
},
|
|
]);
|
|
let statesToggle: Ref<boolean> = ref(false);
|
|
const showStates = () => {
|
|
// let map: Map = this.mapService.getMap(this.mapId);
|
|
// const bounds: LatLngBoundsExpression = toLatLngBounds(this.southWest, this.northEast);
|
|
// map.fitBounds(bounds);
|
|
|
|
// if (_enabled.value == true) {
|
|
// disable();
|
|
// } else {
|
|
// enable();
|
|
// }
|
|
statesToggle.value = !statesToggle.value;
|
|
};
|
|
let language = ref('de');
|
|
const setLanguage = (item) => {
|
|
language.value = item.label;
|
|
// console.log(language.value);
|
|
// close selection list
|
|
statesToggle.value = false;
|
|
|
|
// data.search = '';
|
|
computedValue.value = '';
|
|
data.isOpen = false;
|
|
};
|
|
|
|
const ENDPOINT = 'https://resource.geolba.ac.at/PoolParty/sparql/keyword';
|
|
// const USER_LANG = 'de';
|
|
|
|
// watch(search, async () => {
|
|
// await onChange();
|
|
// });
|
|
|
|
async function handleInput(e: Event) {
|
|
// const target = <HTMLInputElement>e.target;
|
|
// console.log(target.value);
|
|
if (computedValue.value.length >= 2) {
|
|
data.isOpen = true;
|
|
return await request(ENDPOINT, computedValue.value);
|
|
} else {
|
|
data.results = [];
|
|
data.isOpen = false;
|
|
}
|
|
}
|
|
|
|
// async function onChange() {
|
|
// if (!data.search) return false;
|
|
|
|
// // selectedIndex.value = 0;
|
|
|
|
// if (data.search.length >= 2) {
|
|
// data.isOpen = true;
|
|
// return await request(ENDPOINT, data.search);
|
|
// } else {
|
|
// data.results = [];
|
|
// data.isOpen = false;
|
|
// }
|
|
// }
|
|
|
|
// Function to execute the SPARQL query against the endpoint
|
|
async function request(url: string, param: string) {
|
|
try {
|
|
// Create SPARQL query to search for concepts by keyword
|
|
let query = encodeURIComponent(`
|
|
PREFIX dcterms:<http://purl.org/dc/terms/>
|
|
PREFIX skos:<http://www.w3.org/2004/02/skos/core#>
|
|
SELECT DISTINCT ?s ?title ?text
|
|
WHERE {
|
|
VALUES ?n {"${sparqlEncode(param.toLowerCase())}"}
|
|
VALUES ?p { skos:prefLabel skos:altLabel }
|
|
|
|
?s a skos:Concept; ?p ?lEN .
|
|
FILTER((lang(?lEN)="en"))
|
|
|
|
# New filter added to restrict the URIs to 'ncl/geoera/keyword'
|
|
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"))
|
|
|
|
# Exclude "(category)" in titles
|
|
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)
|
|
BIND(CONCAT(STR(?p), "|", STR(?L)) AS ?text)
|
|
BIND(IF(?p = skos:prefLabel, 1, 2) AS ?sort)
|
|
}
|
|
ORDER BY ?sort
|
|
LIMIT 100`);
|
|
|
|
let response = await searchTerm(url + '?query=' + query + '&format=application/json'); // Execute query
|
|
error.value = '';
|
|
data.results = getResults(response); // Process results and store them
|
|
} catch (error) {
|
|
error.value = error.message; // Handle any errors in fetching the data
|
|
}
|
|
}
|
|
|
|
|
|
// 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 searchTerm(term: string): Promise<any> {
|
|
let res = await axios.get(term);
|
|
// console.log(res.data);
|
|
return res.data; //.response;//.docs;
|
|
}
|
|
|
|
function getResults(response) {
|
|
if (Array.isArray(response.results.bindings)) {
|
|
return response.results.bindings;
|
|
}
|
|
return [];
|
|
}
|
|
|
|
function sparqlEncode(str: string) {
|
|
var hex, i;
|
|
str = str.toLowerCase();
|
|
var result = '';
|
|
for (i = 0; i < str.length; i++) {
|
|
hex = str.charCodeAt(i);
|
|
if (hex < 32 || hex > 128) result += '\\u' + ('000' + hex.toString(16)).slice(-4);
|
|
else result += str.charAt(i);
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
function setResult(item) {
|
|
// search.value = item.title.value;
|
|
computedValue.value = item.title.value;
|
|
clear();
|
|
// this.$emit('person', person);
|
|
emit('subject', {
|
|
language: language.value,
|
|
uri: item.s.value
|
|
});
|
|
}
|
|
|
|
function clear() {
|
|
// data.search = '';
|
|
data.isOpen = false;
|
|
data.results = [];
|
|
error.value = '';
|
|
// this.$emit("clear");
|
|
}
|
|
|
|
</script>
|