diff --git a/package.json b/package.json index 94b99bdbc6a655024ab0e7edcd09bb288089ef57..84c7882e8beb70162b3c731e034e989a722e2b86 100644 --- a/package.json +++ b/package.json @@ -28,6 +28,7 @@ "dependencies": { "@coscine/api-client": "^2.9.2", "@zazuko/rdf-vocabularies": "^2022.6.29", + "axios": "^1.3.5", "bootstrap": "4.6.1", "bootstrap-vue": "^2.22.0", "rdf-ext": "^2.0.1", diff --git a/src/FormGenerator.vue b/src/FormGenerator.vue index c61cb0d23b9c87555c1bb4b4d5e92040f1b07c58..4ba6241b52a0c835a4441e2c95ba918cbc7152db 100644 --- a/src/FormGenerator.vue +++ b/src/FormGenerator.vue @@ -37,7 +37,7 @@ import locale from '@/locale'; import VueI18n from 'vue-i18n'; -import { MetadataApi, UserApi } from '@coscine/api-client'; +import { UserApi } from '@coscine/api-client'; import type { Dataset, Quad, Quad_Object, Quad_Subject } from 'rdf-js'; import factory from 'rdf-ext'; @@ -47,13 +47,13 @@ import LinkedDataHandler from '@/base/LinkedDataHandler'; import { prefixes } from '@zazuko/rdf-vocabularies'; import type { UserObject } from '@coscine/api-client/dist/types/Coscine.Api.User'; -import type { BilingualLabels } from '@coscine/api-client/dist/types/Coscine.Api.Metadata'; import type { FixedValueObject, FixedValues, ValueType, } from '@/types/fixedValues'; import type DatasetExt from 'rdf-ext/lib/Dataset'; +import { retrieveChildren } from './util/linkedData'; if (Vue) { Vue.use(VueI18n); @@ -124,13 +124,8 @@ export default defineComponent({ type: String, }, classReceiver: { - default: () => async (classUrl: string) => { - const response = await MetadataApi.metadataGetClassInstances(classUrl); - return response.data; - }, - type: Function as PropType< - (classUrl: string) => Promise<BilingualLabels> - >, + default: () => retrieveChildren, + type: Function as PropType<typeof retrieveChildren>, }, userReceiver: { default: () => async () => { diff --git a/src/base/LinkedDataHandler.ts b/src/base/LinkedDataHandler.ts index ee9e9956800db3a3bb46a721ba3f36559a1d5f8c..cb4e61814a7df08c9efd580fb6eab0aaa360d6a7 100644 --- a/src/base/LinkedDataHandler.ts +++ b/src/base/LinkedDataHandler.ts @@ -5,16 +5,8 @@ import SHACLValidator from 'rdf-validate-shacl'; import rdfParser from 'rdf-parse'; import { Readable } from 'stream'; import { prefixes } from '@zazuko/rdf-vocabularies'; -import type { - DataFactory, - Dataset, - DatasetCore, - DatasetCoreFactory, - Quad, - Quad_Object, - Quad_Subject, -} from 'rdf-js'; -import type ValidationReport from 'rdf-validate-shacl/src/validation-report'; +import type { Dataset, Quad, Quad_Object, Quad_Subject } from 'rdf-js'; +import type { ValidationType } from '@/types/validationTypes'; export default defineComponent({ data() { @@ -25,20 +17,7 @@ export default defineComponent({ }; }, methods: { - fillResults( - currentResults: Array< - ValidationReport.ValidationResult< - DataFactory<Quad, Quad> & - DatasetCoreFactory<Quad, Quad, DatasetCore<Quad, Quad>> - > - >, - results: Array< - ValidationReport.ValidationResult< - DataFactory<Quad, Quad> & - DatasetCoreFactory<Quad, Quad, DatasetCore<Quad, Quad>> - > - > - ) { + fillResults(currentResults: ValidationType, results: ValidationType) { for (const currentResult of currentResults) { results.push(currentResult); if (currentResult.detail) { @@ -48,12 +27,7 @@ export default defineComponent({ }, setErrorMessages( metadata: Dataset, - results: Array< - ValidationReport.ValidationResult< - DataFactory<Quad, Quad> & - DatasetCoreFactory<Quad, Quad, DatasetCore<Quad, Quad>> - > - >, + results: ValidationType, subjectNode: Quad_Subject ) { for (const result of results) { @@ -148,12 +122,7 @@ export default defineComponent({ this.$emit('isValid', report, clonedValidationContext); this.errorMessages = {}; - const results: Array< - ValidationReport.ValidationResult< - DataFactory<Quad, Quad> & - DatasetCoreFactory<Quad, Quad, DatasetCore<Quad, Quad>> - > - > = []; + const results: ValidationType = []; this.fillResults(report.results, results); this.setErrorMessages(clonedMetadata, results, subjectNode); diff --git a/src/components/InputCombobox.vue b/src/components/InputCombobox.vue index 9937b225e6a3e729d61a3aa9327797f0d13a4ef9..36e8636e80be62301173ff1bbe3a7125ce34dfaa 100644 --- a/src/components/InputCombobox.vue +++ b/src/components/InputCombobox.vue @@ -29,12 +29,10 @@ if (Vue) { // TODO: Deal with Vue 3 } -import type { - BilingualLabels, - Label, -} from '@coscine/api-client/dist/types/Coscine.Api.Metadata'; +import type { Label } from '@coscine/api-client/dist/types/Coscine.Api.Metadata'; import type { NamedNode, Quad_Object } from 'rdf-js'; import factory from 'rdf-ext'; +import { retrieveChildren } from '@/util/linkedData'; const i18n = new VueI18n({ locale: 'en', @@ -71,12 +69,8 @@ export default defineComponent({ type: Object as PropType<NamedNode<string>>, }, classReceiver: { - default: () => { - return async () => ({} as BilingualLabels); - }, - type: Function as PropType< - (classUrl: string) => Promise<BilingualLabels> - >, + default: () => retrieveChildren, + type: Function as PropType<typeof retrieveChildren>, }, }, data() { @@ -129,10 +123,22 @@ export default defineComponent({ } }, async retrieveLabels() { + let classReceiver: + | typeof retrieveChildren + | (() => typeof retrieveChildren) = this.classReceiver; + // Deal with weird behavior during dev builds try { - const bilingualLabels = await this.classReceiver( - this.classObject.value - ); + // If the function has no arguments, it's not the retrieveChildren one + if (classReceiver.length === 0) { + classReceiver = ( + classReceiver as unknown as () => typeof retrieveChildren + )(); + } + } catch (e) { + // Ignore + } + try { + const bilingualLabels = await classReceiver(this.classObject.value); if (this.languageCode === 'en' && bilingualLabels.en) { this.list = bilingualLabels.en; } else if (this.languageCode === 'de' && bilingualLabels.de) { diff --git a/src/components/InputList.vue b/src/components/InputList.vue index d537f48cd776ad2f0e7097c916cd2a7787e2ab11..32f8a08c2e483c98b6e252a68d51bb74b48d813b 100644 --- a/src/components/InputList.vue +++ b/src/components/InputList.vue @@ -29,10 +29,7 @@ if (Vue) { // TODO: Deal with Vue 3 } -import type { - BilingualLabels, - Label, -} from '@coscine/api-client/dist/types/Coscine.Api.Metadata'; +import type { Label } from '@coscine/api-client/dist/types/Coscine.Api.Metadata'; import type { Quad_Object } from 'rdf-js'; import factory from 'rdf-ext'; @@ -70,14 +67,6 @@ export default defineComponent({ required: true, type: Array as PropType<Array<string>>, }, - classReceiver: { - default: () => { - return async () => ({} as BilingualLabels); - }, - type: Function as PropType< - (classUrl: string) => Promise<BilingualLabels> - >, - }, }, data() { return { diff --git a/src/components/InputShape.vue b/src/components/InputShape.vue index a07a9bae5dbbeba0923bd5dbfa1d199663c4b7a4..8513f7852e426d44821fbd38d5f146b5c1efb206 100644 --- a/src/components/InputShape.vue +++ b/src/components/InputShape.vue @@ -34,8 +34,8 @@ import type { Dataset, Quad_Object } from 'rdf-js'; import factory from 'rdf-ext'; import { BCard } from 'bootstrap-vue'; import { type FixedValues } from '@/types/fixedValues'; -import { type BilingualLabels } from '@coscine/api-client/dist/types/Coscine.Api.Metadata'; import { type UserObject } from '@coscine/api-client/dist/types/Coscine.Api.User'; +import { retrieveChildren } from '@/util/linkedData'; const i18n = new VueI18n({ locale: 'en', @@ -91,12 +91,8 @@ export default defineComponent({ type: Boolean, }, classReceiver: { - default: () => { - return async () => ({} as BilingualLabels); - }, - type: Function as PropType< - (classUrl: string) => Promise<BilingualLabels> - >, + default: () => retrieveChildren, + type: Function as PropType<typeof retrieveChildren>, }, userReceiver: { default: () => { diff --git a/src/components/WrapperInput.vue b/src/components/WrapperInput.vue index bc7824dc0bd921285fab22923dc28e86eeafa555..df8026939083d9e9d4e9d27a5b2a7d1a86506865 100644 --- a/src/components/WrapperInput.vue +++ b/src/components/WrapperInput.vue @@ -164,12 +164,15 @@ const i18n = new VueI18n({ silentFallbackWarn: true, }); -import type { BilingualLabels } from '@coscine/api-client/dist/types/Coscine.Api.Metadata'; import type { UserObject } from '@coscine/api-client/dist/types/Coscine.Api.User'; import type { Dataset, NamedNode, Quad_Object, Quad_Subject } from 'rdf-js'; import { prefixes } from '@zazuko/rdf-vocabularies'; import factory from 'rdf-ext'; -import { getObject, getObjectStringList } from '@/util/linkedData'; +import { + getObject, + getObjectStringList, + retrieveChildren, +} from '@/util/linkedData'; import type { FixedValueObject, FixedValues, @@ -228,12 +231,8 @@ export default defineComponent({ type: Object as PropType<{ [nodeName: string]: Quad_Object[] }>, }, classReceiver: { - default: () => { - return async () => ({} as BilingualLabels); - }, - type: Function as PropType< - (classUrl: string) => Promise<BilingualLabels> - >, + default: () => retrieveChildren, + type: Function as PropType<typeof retrieveChildren>, }, userReceiver: { default: () => { diff --git a/src/types/terminologyResponse.d.ts b/src/types/terminologyResponse.d.ts new file mode 100644 index 0000000000000000000000000000000000000000..f973165cf5a64cc26391a5532b5c7e83497567b7 --- /dev/null +++ b/src/types/terminologyResponse.d.ts @@ -0,0 +1,80 @@ +export interface TerminologyResponse { + responseHeader: ResponseHeader; + response: Response; + facet_counts: FacetCounts; + highlighting: { [key: string]: FacetDates }; +} + +export interface FacetCounts { + facet_queries: FacetDates; + facet_fields: FacetFields; + facet_dates: FacetDates; + facet_ranges: FacetDates; + facet_intervals: FacetDates; + facet_heatmaps: FacetDates; +} + +// eslint-disable-next-line @typescript-eslint/no-empty-interface +export interface FacetDates {} + +export interface FacetFields { + ontology_name: Array<number | string>; + ontology_prefix: Array<number | string>; + type: Array<number | string>; + subset: Array<number | string>; + is_defining_ontology: Array<number | string>; + is_obsolete: Array<number | string>; +} + +export interface Response { + numFound: number; + start: number; + docs: Doc[]; +} + +export interface Doc { + id: string; + iri: string; + short_form: string; + label: string; + ontology_name: Ontology; + ontology_prefix: Ontology; + type: Type; + is_defining_ontology: boolean; + obo_id?: string; + description?: string[]; +} + +export enum Ontology { + DR = 'dr', + Premis3 = 'premis3', +} + +export enum Type { + Class = 'class', + Individual = 'individual', +} + +export interface ResponseHeader { + status: number; + QTime: number; + params: Params; +} + +export interface Params { + 'facet.field': string[]; + hl: string; + fl: string; + start: string; + fq: string[]; + rows: string; + 'hl.simple.pre': string; + bq: string; + q: string; + defType: string; + 'hl.simple.post': string; + qf: string; + 'hl.fl': string[]; + facet: string; + wt: string; +} diff --git a/src/types/validationTypes.d.ts b/src/types/validationTypes.d.ts new file mode 100644 index 0000000000000000000000000000000000000000..87269e19964f53c3dc9f295d37f3847aa2bc7695 --- /dev/null +++ b/src/types/validationTypes.d.ts @@ -0,0 +1,14 @@ +import type ValidationReport from 'rdf-validate-shacl/src/validation-report'; +import type { + DataFactory, + DatasetCore, + DatasetCoreFactory, + Quad, +} from 'rdf-js'; + +export type ValidationType = Array< + ValidationReport.ValidationResult< + DataFactory<Quad, Quad> & + DatasetCoreFactory<Quad, Quad, DatasetCore<Quad, Quad>> + > +>; diff --git a/src/util/linkedData.ts b/src/util/linkedData.ts index 97f3cf8e9e869ffb01adb7fee79f28190e87eee1..4f8d9075d284d1c89744bd239db5645d05e20fa8 100644 --- a/src/util/linkedData.ts +++ b/src/util/linkedData.ts @@ -1,5 +1,8 @@ import { prefixes } from '@zazuko/rdf-vocabularies'; import factory from 'rdf-ext'; +import axios from 'axios'; +import type { TerminologyResponse } from '@/types/terminologyResponse'; +import type { BilingualLabels } from '@coscine/api-client/dist/types/Coscine.Api.Metadata'; import type { Dataset, Literal, @@ -70,3 +73,22 @@ export function getObjectStringList( .filter((quad) => quad.predicate.equals(rdfFirstNode)) .map((quad) => quad.object.value); } + +export async function retrieveChildren( + classUrl: string +): Promise<BilingualLabels> { + const response = await axios.get( + `https://service.tib.eu/ts4tib/api/search?q=*&obsoletes=false&local=false&groupField=iri&childrenOf=${classUrl}&format=json` + ); + const tibResponse: TerminologyResponse = response.data; + const de = tibResponse.response.docs.map((doc) => { + return { + name: doc.label, + value: doc.iri, + }; + }); + return { + de, + en: de, + }; +} diff --git a/yarn.lock b/yarn.lock index 929d614c2f70bec10be92dc8a68a014f3238287f..59389f54675a846ee81b10ff30ae43cdfeb9456a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -351,6 +351,7 @@ __metadata: "@vue/eslint-config-typescript": ^11.0.1 "@vue/test-utils": ^1.3.0 "@zazuko/rdf-vocabularies": ^2022.6.29 + axios: ^1.3.5 bootstrap: 4.6.1 bootstrap-vue: ^2.22.0 conventional-changelog-eslint: 3.0.9 @@ -2094,6 +2095,17 @@ __metadata: languageName: node linkType: hard +"axios@npm:^1.3.5": + version: 1.3.5 + resolution: "axios@npm:1.3.5" + dependencies: + follow-redirects: ^1.15.0 + form-data: ^4.0.0 + proxy-from-env: ^1.1.0 + checksum: 4d6bcf933b1cdff86d4993752aaeeeedc4a7f7a4b1c942847f6884bb13fc6106610ff826b076acf0b08d8ced55dee9344bb9a11f3624c3e70ab1da1a40bb5506 + languageName: node + linkType: hard + "balanced-match@npm:^1.0.0": version: 1.0.2 resolution: "balanced-match@npm:1.0.2" @@ -4367,7 +4379,7 @@ __metadata: languageName: node linkType: hard -"follow-redirects@npm:^1.14.0, follow-redirects@npm:^1.5.1": +"follow-redirects@npm:^1.14.0, follow-redirects@npm:^1.15.0, follow-redirects@npm:^1.5.1": version: 1.15.2 resolution: "follow-redirects@npm:1.15.2" peerDependenciesMeta: @@ -7912,6 +7924,13 @@ __metadata: languageName: node linkType: hard +"proxy-from-env@npm:^1.1.0": + version: 1.1.0 + resolution: "proxy-from-env@npm:1.1.0" + checksum: ed7fcc2ba0a33404958e34d95d18638249a68c430e30fcb6c478497d72739ba64ce9810a24f53a7d921d0c065e5b78e3822759800698167256b04659366ca4d4 + languageName: node + linkType: hard + "pseudomap@npm:^1.0.2": version: 1.0.2 resolution: "pseudomap@npm:1.0.2"