Webapp: basic start: loading concepts and allowing user to enter a (ignored) value

This commit is contained in:
Francesco 2022-04-24 17:42:24 +02:00
parent dde10918c0
commit 00ecab72e6
6 changed files with 111 additions and 15 deletions

View File

@ -26,3 +26,7 @@ coverage
*.njsproj *.njsproj
*.sln *.sln
*.sw? *.sw?
# Puzzle-related data
public/entities.json
public/concepts.json

View File

@ -0,0 +1,5 @@
export class Concept {
elements: Array<string> = []
extensionalDistance = 0
properSize = 0
}

View File

@ -0,0 +1,5 @@
export class NamedEntity {
name = "";
type = "";
uri = "";
}

View File

@ -0,0 +1,8 @@
export function fetchJSON(url: string): Promise<unknown> {
return fetch(url)
.then((response) => {
if (!response.ok)
throw new Error(`Error fetching ${url}: ${response.status} - ${response.statusText}`);
return response.json();
});
}

View File

@ -1,3 +0,0 @@
{
"test": "hello"
}

View File

@ -1,29 +1,106 @@
<template> <template>
<p>{{ value }}</p> <div v-if="fetchErrors" class="error">
<a :href="jsonURL">Test</a> <div v-for="err in fetchErrors" :key="err">
{{ err }}<br />
</div>
</div>
<form v-if="entities.length > 0" @submit.prevent="submitGuess">
Enter a guess: <input type="text" v-model="guessFieldValue" /> <br />
<div v-if="guessError" class="error">{{ guessError }} <br /></div>
<span class="possibleTypes">It can be any {{ [...entityTypes].join(", ") }}.</span>
</form>
</template> </template>
<script lang="ts"> <script lang="ts">
import jsonURL from "../assets/test.json?url";
import { defineComponent } from "vue"; import { defineComponent } from "vue";
import type { NamedEntity } from "@/NamedEntity";
import type { Concept } from "@/Concept";
import { fetchJSON } from "@/Utils";
const entitiesURL = "/entities.json";
const conceptsURL = "/concepts.json";
export default defineComponent({ export default defineComponent({
name: "MainComponent", name: "MainComponent",
data() { data() {
return { return {
value: "Test", guessFieldValue: "",
jsonURL: jsonURL, fetchErrors: [] as Array<string>,
guessError: null as string | null,
entities: [] as Array<NamedEntity>,
concepts: [] as Array<Concept>,
target: null as string | null,
}; };
}, },
mounted() { computed: {
fetch(jsonURL) entityTypes(): Set<string> {
.then((v) => v.json()) let result: Set<string> = new Set();
.then((json) => { this.entities
console.log(json); .map(e => e.type)
this.value = json; .forEach(t => result.add(t));
return result;
},
entitiesByLowerName(): Map<string, Array<NamedEntity>> {
let result: Map<string, Array<NamedEntity>> = new Map();
this.entities.forEach(e => {
const lowerName = e.name.toLowerCase();
const entitiesWithName = result.get(lowerName) ?? [];
entitiesWithName.push(e);
result.set(lowerName, entitiesWithName);
}); });
return result;
},
entitiesByUri(): Map<string, NamedEntity> {
let result: Map<string, NamedEntity> = new Map();
this.entities.forEach(e => result.set(e.uri, e));
return result;
},
},
created() {
this.fetchErrors = [];
fetchJSON(entitiesURL)
.then(json => this.entities = json as Array<NamedEntity>)
.catch(this.fetchErrors.push);
fetchJSON(conceptsURL)
.then(json => {
this.concepts = (json as any).concepts as Array<Concept>; // eslint-disable-line @typescript-eslint/no-explicit-any
this.target = (json as any).target as string; // eslint-disable-line @typescript-eslint/no-explicit-any
});
},
methods: {
submitGuess() {
this.guessError = null;
if (!this.entitiesByLowerName.has(this.guessFieldValue.toLowerCase())) {
this.guessError = `${(this.guessFieldValue)} is unknown to me...`;
return;
}
const matchingEntities = this.entitiesByLowerName.get(this.guessFieldValue.toLowerCase()) as NamedEntity[];
const matchingUris = new Set(matchingEntities.map(e => e.uri));
console.debug(matchingUris);
const matchingConcept = this.concepts.find(concept => concept.elements.some(uri => matchingUris.has(uri)));
if (typeof matchingConcept == "undefined") {
this.guessError = "Entity is known but concept can't be found: this should not happen...";
return;
}
console.info("Found matching guess concept");
console.info(matchingConcept);
this.guessFieldValue = "";
},
}, },
}); });
</script> </script>
<style scoped></style> <style scoped lang="scss">
.error {
color: red;
font-style: italic;
margin-bottom: 2em;
}
.possibleTypes {
font-style: italic;
font-size: small;
}
</style>