WIP: ktb-static #5
4 changed files with 148 additions and 33 deletions
|
|
@ -2,7 +2,7 @@
|
||||||
document.addEventListener("alpine:init", () => {
|
document.addEventListener("alpine:init", () => {
|
||||||
Alpine.store("dictionary", {
|
Alpine.store("dictionary", {
|
||||||
search_results: {
|
search_results: {
|
||||||
terms: 0,
|
terms: 1,
|
||||||
results: [
|
results: [
|
||||||
{
|
{
|
||||||
lemma_name: "wiigel",
|
lemma_name: "wiigel",
|
||||||
|
|
@ -136,6 +136,20 @@ document.addEventListener("alpine:init", () => {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
async delete_definition(definition_id, definition_text) {
|
||||||
|
if (
|
||||||
|
window.confirm(`Du keshite imi ${definition_id}.\nPravda?`)
|
||||||
|
) {
|
||||||
|
try {
|
||||||
|
const res = await axios.delete(
|
||||||
|
`http://localhost:1225/definition/${definition_id}`,
|
||||||
|
);
|
||||||
|
} catch (e) {
|
||||||
|
console.error(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
async put_example(example_id, example_text, lemma_name) {
|
async put_example(example_id, example_text, lemma_name) {
|
||||||
try {
|
try {
|
||||||
const res = await axios.put("http://localhost:1225/example", {
|
const res = await axios.put("http://localhost:1225/example", {
|
||||||
|
|
@ -149,6 +163,20 @@ document.addEventListener("alpine:init", () => {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
async delete_example(example_id, example_text) {
|
||||||
|
if (
|
||||||
|
window.confirm(`Du keshite tato ${example_id}.\nPravda?`)
|
||||||
|
) {
|
||||||
|
try {
|
||||||
|
const res = await axios.delete(
|
||||||
|
`http://localhost:1225/example/${example_id}`,
|
||||||
|
);
|
||||||
|
} catch (e) {
|
||||||
|
console.error(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
async put_word_form_text(word_form_id, word_form_text) {
|
async put_word_form_text(word_form_id, word_form_text) {
|
||||||
try {
|
try {
|
||||||
const res = await axios.put("http://localhost:1225/word-form", {
|
const res = await axios.put("http://localhost:1225/word-form", {
|
||||||
|
|
@ -162,6 +190,12 @@ document.addEventListener("alpine:init", () => {
|
||||||
},
|
},
|
||||||
|
|
||||||
async post_new_word_form(lemma_name, lect_name, word_form_text) {
|
async post_new_word_form(lemma_name, lect_name, word_form_text) {
|
||||||
|
if(!lemma_name || !lect_name || !word_form_text) {
|
||||||
|
console.error(`Missing parameter:\n${JSON.stringify({
|
||||||
|
lemma_name, lect_name, word_form_text
|
||||||
|
})}`);
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const res = await axios.post(
|
const res = await axios.post(
|
||||||
"http://localhost:1225/word-form",
|
"http://localhost:1225/word-form",
|
||||||
|
|
@ -199,7 +233,7 @@ document.addEventListener("alpine:init", () => {
|
||||||
},
|
},
|
||||||
|
|
||||||
md(text){
|
md(text){
|
||||||
console.log(marked.parse(text));
|
console.debug(marked.parse(text));
|
||||||
return DOMPurify.sanitize(marked.parse(text), {ALLOWED_TAGS: ['br', 'em', 'strong', 'code', '#text']});
|
return DOMPurify.sanitize(marked.parse(text), {ALLOWED_TAGS: ['br', 'em', 'strong', 'code', '#text']});
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,8 @@
|
||||||
search_term: '',
|
search_term: '',
|
||||||
showPrefs: false,
|
showPrefs: false,
|
||||||
lects: [],
|
lects: [],
|
||||||
|
current_result_page: 0,
|
||||||
|
results_per_page: 30,
|
||||||
md(text){
|
md(text){
|
||||||
return $store.dictionary.md(text);
|
return $store.dictionary.md(text);
|
||||||
},
|
},
|
||||||
|
|
@ -92,9 +94,31 @@
|
||||||
@keydown.enter="$store.dictionary.fetch_all_terms(search_term)"
|
@keydown.enter="$store.dictionary.fetch_all_terms(search_term)"
|
||||||
placeholder="Tasta ko(tel) her..." />
|
placeholder="Tasta ko(tel) her..." />
|
||||||
</div>
|
</div>
|
||||||
|
<div class="flex-row"
|
||||||
|
x-data="{
|
||||||
|
page_count: 1,
|
||||||
|
item_count: 0
|
||||||
|
}"
|
||||||
|
x-effect="current_result_page = Math.min(current_result_page, page_count-1); page_count = Math.ceil($store.dictionary.search_results.terms/results_per_page); item_count = $store.dictionary.search_results.terms;">
|
||||||
|
<button
|
||||||
|
class="hollow primary"
|
||||||
|
x-show="item_count > results_per_page && current_result_page > 0"
|
||||||
|
@click="current_result_page-=1"><strong>←</strong></button>
|
||||||
|
<div x-text="`${current_result_page + 1} / ${page_count}`"></div>
|
||||||
|
<button
|
||||||
|
class="hollow primary"
|
||||||
|
x-show="item_count > results_per_page && current_result_page+1 < page_count"
|
||||||
|
@click="current_result_page+=1"><strong>→</strong></button>
|
||||||
|
<select x-model="results_per_page">
|
||||||
|
<option value="15">15</option>
|
||||||
|
<option value="30">30</option>
|
||||||
|
<option value="60">60</option>
|
||||||
|
<option value="120">120</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
<div class="cards-container">
|
<div class="cards-container">
|
||||||
<template
|
<template
|
||||||
x-for="item in $store.dictionary.filter_results(search_term)"
|
x-for="item in $store.dictionary.filter_results(search_term).slice(current_result_page*results_per_page, Math.min((current_result_page+1)*results_per_page, $store.dictionary.search_results.terms))"
|
||||||
:key="item.lemma_name">
|
:key="item.lemma_name">
|
||||||
<div
|
<div
|
||||||
class="card"
|
class="card"
|
||||||
|
|
@ -128,11 +152,21 @@
|
||||||
this.load_detail();
|
this.load_detail();
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
async delete_definition(definition_id, definition_text){
|
||||||
|
$store.dictionary.delete_definition(definition_id, definition_text).then(()=>{
|
||||||
|
this.load_detail();
|
||||||
|
});
|
||||||
|
},
|
||||||
async put_example(example_id, example_text){
|
async put_example(example_id, example_text){
|
||||||
$store.dictionary.put_example(example_id, example_text, this.lemma_detail?.lemma_name).then(()=>{
|
$store.dictionary.put_example(example_id, example_text, this.lemma_detail?.lemma_name).then(()=>{
|
||||||
this.load_detail();
|
this.load_detail();
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
async delete_example(example_id, example_text){
|
||||||
|
$store.dictionary.delete_example(example_id, example_text).then(()=>{
|
||||||
|
this.load_detail();
|
||||||
|
});
|
||||||
|
},
|
||||||
async toggle_expand() {
|
async toggle_expand() {
|
||||||
if(!this.lemma_detail){
|
if(!this.lemma_detail){
|
||||||
/* If there isn't a lemma detail loaded yet, get it then expand. */
|
/* If there isn't a lemma detail loaded yet, get it then expand. */
|
||||||
|
|
@ -221,30 +255,35 @@
|
||||||
new_lect_name:''
|
new_lect_name:''
|
||||||
}">
|
}">
|
||||||
|
|
||||||
<td colspan="3" x-show="!adding_word_form" style="width: 16em;">
|
<td colspan="3" x-show="!adding_word_form">
|
||||||
<button class="is-fullwidth hollow primary"
|
<button class="is-fullwidth hollow primary"
|
||||||
@click="adding_word_form = !adding_word_form">+</button>
|
@click="adding_word_form = !adding_word_form">+</button>
|
||||||
</td>
|
</td>
|
||||||
|
|
||||||
<td x-show="adding_word_form">
|
<td colspan="3" x-show="adding_word_form" style="width: 12em;">
|
||||||
<select name="vilgovor" x-model="selected_lect" x-show="!adding_lect">
|
<div style="display: flex; flex-direction: row; gap: 2em; justify-content: space-between;">
|
||||||
<template x-for="lect in lects">
|
<div>
|
||||||
<option :value="lect.name" x-text="lect.name"></option>
|
<select name="vilgovor" x-model="selected_lect" x-show="!adding_lect">
|
||||||
</template>
|
<option value="" selected disabled hidden>Sentaku...</option>
|
||||||
</select>
|
<template x-for="lect in lects">
|
||||||
<input type="text" x-show="adding_lect" x-model="new_lect_name">
|
<option :value="lect.name" x-text="lect.name"></option>
|
||||||
<button class="float-right tiny primary" x-show="!adding_lect" @click="adding_lect = true" title="neo govor">+</button>
|
</template>
|
||||||
<button class="float-right tiny edit" x-show="adding_lect" title="jame" @click="adding_lect = false">/</button>
|
</select>
|
||||||
|
<input type="text" x-show="adding_lect" x-model="new_lect_name">
|
||||||
|
<button class="float-right tiny primary" x-show="!adding_lect" @click="adding_lect = true" title="neo govor">+</button>
|
||||||
|
<button class="float-right tiny edit" x-show="adding_lect" title="jame" @click="adding_lect = false">/</button>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<input type="text" x-model="new_word_form_text">
|
||||||
|
</div>
|
||||||
|
<div class="float-right">
|
||||||
|
<button class="tiny edit" x-show="adding_word_form" title="jame" @click="adding_word_form = false">/</button>
|
||||||
|
<button class="tiny" x-show="adding_word_form" title="antaa"
|
||||||
|
@click="await post_new_word_form(item.lemma_name, adding_lect ? new_lect_name : selected_lect, new_word_form_text); adding_word_form = false">></button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
</td>
|
</td>
|
||||||
<td x-show="adding_word_form">
|
|
||||||
<input type="text" x-model="new_word_form_text">
|
|
||||||
</td>
|
|
||||||
<td x-show="adding_word_form">
|
|
||||||
<button class="tiny edit" x-show="adding_word_form" title="jame" @click="adding_word_form = false">/</button>
|
|
||||||
<button class="tiny" x-show="adding_word_form" title="antaa"
|
|
||||||
@click="await post_new_word_form(item.lemma_name, adding_lect ? new_lect_name : selected_lect, new_word_form_text); adding_word_form = false">></button>
|
|
||||||
</td>
|
|
||||||
|
|
||||||
</tr>
|
</tr>
|
||||||
</tfoot>
|
</tfoot>
|
||||||
</table>
|
</table>
|
||||||
|
|
@ -259,12 +298,16 @@
|
||||||
}" @click.outside="editing = false">
|
}" @click.outside="editing = false">
|
||||||
<span x-show="!editing" x-html="md(def.definition_text)" @click="editing = true"></span>
|
<span x-show="!editing" x-html="md(def.definition_text)" @click="editing = true"></span>
|
||||||
<input type="text" x-show="editing" x-model="edited_text">
|
<input type="text" x-show="editing" x-model="edited_text">
|
||||||
<button class="float-right tiny hollow primary" title="kawari" x-show="!editing"
|
<div class="float-right">
|
||||||
@click="editing = true">~</button>
|
<button class="tiny hollow primary" title="kawari" x-show="!editing"
|
||||||
<button class="float-right tiny edit" title="jame" x-show="editing"
|
@click="editing = true">~</button>
|
||||||
@click="editing = false">/</button>
|
<button class="tiny edit" title="jame" x-show="editing"
|
||||||
<button class="float-right tiny primary" title="antaa" x-show="editing"
|
@click="editing = false">/</button>
|
||||||
@click="await put_definition(def.definition_id, edited_text); editing = false">></button>
|
<button class="tiny primary" title="antaa" x-show="editing"
|
||||||
|
@click="await put_definition(def.definition_id, edited_text); editing = false">></button>
|
||||||
|
<button class="tiny hollow delete" x-show="!editing" title="keshite"
|
||||||
|
@click="await delete_definition(def.definition_id, def.definition_text)" >x</button>
|
||||||
|
</div>
|
||||||
</li>
|
</li>
|
||||||
</template>
|
</template>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
@ -281,7 +324,6 @@
|
||||||
/
|
/
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
class="align-self-right"
|
|
||||||
x-show="adding_definition"
|
x-show="adding_definition"
|
||||||
type="button"
|
type="button"
|
||||||
@click="put_definition(null, definition_text)
|
@click="put_definition(null, definition_text)
|
||||||
|
|
@ -310,9 +352,16 @@
|
||||||
@click.outside="editing = false">
|
@click.outside="editing = false">
|
||||||
<span x-show="!editing" x-html="md(ex.example_text)" @click="editing = true"></span>
|
<span x-show="!editing" x-html="md(ex.example_text)" @click="editing = true"></span>
|
||||||
<input type="text" x-show="editing" x-model="edited_text">
|
<input type="text" x-show="editing" x-model="edited_text">
|
||||||
<button class="float-right tiny hollow primary" x-show="!editing" @click="editing = true" title="kawari">~</button>
|
<div class="float-right">
|
||||||
<button class="float-right tiny edit" x-show="editing" @click="editing = false" title="jame">/</button>
|
<button class="tiny hollow primary" x-show="!editing"
|
||||||
<button class="float-right tiny" x-show="editing" type="button" @click="await put_example(ex.example_id, edited_text); editing = false" title="antaa">></button>
|
@click="editing = true" title="kawari">~</button>
|
||||||
|
<button class="tiny edit" x-show="editing"
|
||||||
|
@click="editing = false" title="jame">/</button>
|
||||||
|
<button class="tiny" x-show="editing" type="button"
|
||||||
|
@click="await put_example(ex.example_id, edited_text); editing = false" title="antaa">></button>
|
||||||
|
<button class="tiny hollow delete" x-show="!editing" title="keshite"
|
||||||
|
@click="await delete_example(ex.example_id, ex.example_text)">x</button>
|
||||||
|
</div>
|
||||||
</li>
|
</li>
|
||||||
</template>
|
</template>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
@ -322,7 +371,12 @@
|
||||||
placeholder="Tasta tatoeba..."
|
placeholder="Tasta tatoeba..."
|
||||||
x-model="example_text"></textarea>
|
x-model="example_text"></textarea>
|
||||||
<button
|
<button
|
||||||
class="is-fullwidth"
|
class="edit"
|
||||||
|
x-show="adding_example"
|
||||||
|
@click="adding_example = false">
|
||||||
|
/
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
x-show="adding_example"
|
x-show="adding_example"
|
||||||
type="button"
|
type="button"
|
||||||
@click="put_example(null, example_text)
|
@click="put_example(null, example_text)
|
||||||
|
|
|
||||||
|
|
@ -116,6 +116,7 @@ button:disabled{
|
||||||
}
|
}
|
||||||
|
|
||||||
.flex-row {
|
.flex-row {
|
||||||
|
gap: var(--space-md);
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -167,6 +167,19 @@ function initExpress() {
|
||||||
res.status(200).send({lemma_detail});
|
res.status(200).send({lemma_detail});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
app.delete("/definition/:definition_id", async (_req, res) =>{
|
||||||
|
const definition_id:number = parseInt(_req.params.definition_id);
|
||||||
|
|
||||||
|
if(!definition_id){
|
||||||
|
console.error(`Error: Could not find word form ${JSON.stringify({definition_id:definition_id})}`);
|
||||||
|
return void res.status(400).send();
|
||||||
|
}
|
||||||
|
|
||||||
|
Definition.delete({definition_id: definition_id});
|
||||||
|
|
||||||
|
res.status(200).send();
|
||||||
|
});
|
||||||
|
|
||||||
/* examples */
|
/* examples */
|
||||||
|
|
||||||
app.put("/example", async (_req, res) => {
|
app.put("/example", async (_req, res) => {
|
||||||
|
|
@ -214,6 +227,19 @@ function initExpress() {
|
||||||
res.status(200).send({lemma_detail});
|
res.status(200).send({lemma_detail});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
app.delete("/example/:example_id", async (_req, res) =>{
|
||||||
|
const example_id:number = parseInt(_req.params.example_id);
|
||||||
|
|
||||||
|
if(!example_id){
|
||||||
|
console.error(`Error: Could not find word form ${JSON.stringify({example_id:example_id})}`);
|
||||||
|
return void res.status(400).send();
|
||||||
|
}
|
||||||
|
|
||||||
|
Example.delete({example_id: example_id});
|
||||||
|
|
||||||
|
res.status(200).send();
|
||||||
|
});
|
||||||
|
|
||||||
/* word forms */
|
/* word forms */
|
||||||
|
|
||||||
app.put("/word-form", async (_req, res) => {
|
app.put("/word-form", async (_req, res) => {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue