diff --git a/apps/ktb-static/script.js b/apps/ktb-static/script.js
index e1f41db..2dbe3f8 100644
--- a/apps/ktb-static/script.js
+++ b/apps/ktb-static/script.js
@@ -1,101 +1,192 @@
// script.js
document.addEventListener("alpine:init", () => {
- Alpine.store("dictionary", {
- search_results: {
- terms: 0,
- results: [
- {
- lemma_name: "wiigel",
- word_forms: [
- { word_form_id: 1262, word_form: "wijgeu", lect: { name: "ArekaDareka" } },
- { word_form_id: 1263, word_form: "wigl", lect: { name: "Anott" } },
- { word_form_id: 1264, word_form: "wijev", lect: { name: "Djin" } }
- ]
- }
- ]
- },
+ Alpine.store("dictionary", {
+ search_results: {
+ terms: 0,
+ results: [
+ {
+ lemma_name: "wiigel",
+ word_forms: [
+ {
+ word_form_id: 1262,
+ word_form: "wijgeu",
+ lect: { name: "ArekaDareka" },
+ },
+ {
+ word_form_id: 1263,
+ word_form: "wigl",
+ lect: { name: "Anott" },
+ },
+ {
+ word_form_id: 1264,
+ word_form: "wijev",
+ lect: { name: "Djin" },
+ },
+ ],
+ },
+ ],
+ },
- prefs: {
- colorSidebarBg: "#000",
- colorMainBg: "#eee",
- colorCardBg: "#fff",
- colorPrimary: "#0bf",
- colorSecondary: "#08e",
- colorText: "#333",
- colorTextSecondary: "#555",
- spaceMd: 1.5,
- shadowStrength: 0.1
- },
+ prefs: {
+ colorSidebarBg: "#000",
+ colorMainBg: "#eee",
+ colorCardBg: "#fff",
+ colorPrimary: "#0bf",
+ colorSecondary: "#08e",
+ colorText: "#333",
+ colorTextSecondary: "#555",
+ },
- updateCSSVariables() {
- document.documentElement.style.setProperty("--color-sidebar-bg", this.prefs.colorSidebarBg);
- document.documentElement.style.setProperty("--color-main-bg", this.prefs.colorMainBg);
- document.documentElement.style.setProperty("--color-card-bg", this.prefs.colorCardBg);
- document.documentElement.style.setProperty("--color-primary", this.prefs.colorPrimary);
- document.documentElement.style.setProperty("--color-secondary", this.prefs.colorSecondary);
- document.documentElement.style.setProperty("--color-text", this.prefs.colorText);
- document.documentElement.style.setProperty("--color-text-secondary", this.prefs.colorTextSecondary);
- document.documentElement.style.setProperty("--space-md", `${this.prefs.spaceMd}rem`);
- document.documentElement.style.setProperty("--color-shadow", `rgba(0, 0, 0, ${this.prefs.shadowStrength})`);
- },
+ update_css_variables() {
+ document.documentElement.style.setProperty(
+ "--color-sidebar-bg",
+ this.prefs.colorSidebarBg,
+ );
+ document.documentElement.style.setProperty(
+ "--color-main-bg",
+ this.prefs.colorMainBg,
+ );
+ document.documentElement.style.setProperty(
+ "--color-card-bg",
+ this.prefs.colorCardBg,
+ );
+ document.documentElement.style.setProperty(
+ "--color-primary",
+ this.prefs.colorPrimary,
+ );
+ document.documentElement.style.setProperty(
+ "--color-secondary",
+ this.prefs.colorSecondary,
+ );
+ document.documentElement.style.setProperty(
+ "--color-text",
+ this.prefs.colorText,
+ );
+ document.documentElement.style.setProperty(
+ "--color-text-secondary",
+ this.prefs.colorTextSecondary,
+ );
+ },
- loadPreferences() {
- const saved_prefs = localStorage.getItem("prefs");
- if (saved_prefs) {
- this.prefs = { ...this.prefs, ...JSON.parse(saved_prefs) };
- this.updateCSSVariables();
+ load_preferences() {
+ const saved_prefs = localStorage.getItem("prefs");
+ if (saved_prefs) {
+ this.prefs = { ...this.prefs, ...JSON.parse(saved_prefs) };
+ this.update_css_variables();
+ }
+ },
+
+ save_preferences() {
+ localStorage.setItem("prefs", JSON.stringify(this.prefs));
+ this.update_css_variables();
+ },
+
+ async fetch_all_lects() {
+ try {
+ const res = await axios.get("http://localhost:1225/lects");
+ console.log(JSON.stringify(res.data));
+ return res.data;
+ } catch (e) {
+ console.error(e);
}
},
- savePreferences() {
- localStorage.setItem("prefs", JSON.stringify(this.prefs));
- this.updateCSSVariables();
- },
+ async fetch_all_terms(search_term) {
+ try {
+ const res = await axios.get("http://localhost:1225/search", {
+ params: { search_term: search_term },
+ });
+ this.search_results = res.data;
+ } catch (e) {
+ console.error(e);
+ }
+ },
- async fetchAllTerms(searchTerm) {
- try {
- const res = await axios.get('http://localhost:1225/search', {
- params: { search_term: searchTerm }
- });
- this.search_results = res.data;
- } catch (e) { console.error(e); }
- },
+ async fetch_one_lemma_detail(lemma_name) {
+ try {
+ const res = await axios.get(
+ "http://localhost:1225/lemma-detail",
+ { params: { lemma_name } },
+ );
+ return res.data.lemma_detail;
+ } catch (e) {
+ console.error(e);
+ }
+ },
- async fetchOneLemmaDetail(lemma_name) {
- try {
- const res = await axios.get('http://localhost:1225/lemma-detail', {
- params: { lemma_name }
- });
- return res.data.lemma_detail;
- } catch (e) { console.error(e); }
- },
+ async put_definition(definition_id, definition_text, lemma_name) {
+ try {
+ const res = await axios.put(
+ "http://localhost:1225/definition",
+ { definition_id, definition_text, lemma_name },
+ );
+ return res.data.lemma_detail;
+ } catch (e) {
+ console.error(e);
+ }
+ },
- async postDefinition(definition_id, definition_text, lemma_name) {
- try {
- const res = await axios.put('http://localhost:1225/definition', {
- definition_id, definition_text, lemma_name
- });
- return res.data.lemma_detail;
- } catch (e) { console.error(e); }
- },
+ async put_example(example_id, example_text, lemma_name) {
+ try {
+ const res = await axios.put("http://localhost:1225/example", {
+ example_id,
+ example_text,
+ lemma_name,
+ });
+ return res.data.lemma_detail;
+ } catch (e) {
+ console.error(e);
+ }
+ },
- async postExample(example_id, example_text, lemma_name) {
- try {
- const res = await axios.put('http://localhost:1225/example', {
- example_id, example_text, lemma_name
- });
- return res.data.lemma_detail;
- } catch (e) { console.error(e); }
- },
+ async put_word_form_text(word_form_id, word_form_text) {
+ try {
+ const res = await axios.put("http://localhost:1225/word-form", {
+ word_form_id,
+ word_form_text,
+ });
+ return res.data.lemma_detail;
+ } catch (e) {
+ console.error(e);
+ }
+ },
- filterResults(searchTerm) {
- if (!searchTerm) return this.search_results.results;
- return this.search_results.results
- .filter( //item.lemma_name.toLowerCase().includes(searchTerm.toLowerCase())
- item => item.word_forms
- .map(wf => wf.word_form.toLowerCase())
- .join().includes(searchTerm.toLowerCase())
- );
- }
- });
+ async post_new_word_form(lemma_name, lect_name, word_form_text) {
+ try {
+ const res = await axios.post(
+ "http://localhost:1225/word-form",
+ { lemma_name, lect_name, word_form_text },
+ );
+ return res.data.lemma_detail;
+ } catch (e) {
+ console.error(e);
+ }
+ },
+
+ async delete_word_form(word_form_id, word_form_text) {
+ if (
+ window.confirm(`Du keshite kofal ${word_form_text}.\nPravda?`)
+ ) {
+ try {
+ const res = await axios.delete(
+ `http://localhost:1225/word-form/${word_form_id}`,
+ );
+ return res.data.lemma_detail;
+ } catch (e) {
+ console.error(e);
+ }
+ }
+ },
+
+ filter_results(search_term) {
+ if (!search_term) return this.search_results.results;
+ return this.search_results.results.filter(
+ (item) =>
+ item.word_forms
+ .map((wf) => wf.word_form.toLowerCase())
+ .join()
+ .includes(search_term.toLowerCase()),
+ );
+ },
+ });
});
diff --git a/apps/ktb-static/search.html b/apps/ktb-static/search.html
index 256d026..b85f973 100644
--- a/apps/ktb-static/search.html
+++ b/apps/ktb-static/search.html
@@ -12,11 +12,17 @@
+ x-init="$store.dictionary.fetch_all_lects().then((lects_response)=>{
+ if(!!lects_response.lects) {
+ lects = lects_response.lects;
+ }
+ });">
@@ -102,18 +78,18 @@
{
+ this.load_detail();
+ });
+ },
+ async post_new_word_form(lemma_name, lect_name, word_form_text){
+ $store.dictionary.post_new_word_form(lemma_name, lect_name, word_form_text).then(()=>{
+ this.load_detail();
+ });
+ },
+ async delete_word_form(word_form_id, word_form_text){
+ $store.dictionary.delete_word_form(word_form_id, word_form_text).then(()=>{
+ this.load_detail();
+ });
+ },
async put_definition(definition_id, definition_text){
- $store.dictionary.postDefinition(definition_id, definition_text, this.lemma_detail?.lemma_name).then(await this.load_detail());
+ $store.dictionary.put_definition(definition_id, definition_text, this.lemma_detail?.lemma_name).then(()=>{
+ this.load_detail();
+ });
},
async put_example(example_id, example_text){
- $store.dictionary.postExample(example_id, example_text, this.lemma_detail?.lemma_name).then(await this.load_detail());
+ $store.dictionary.put_example(example_id, example_text, this.lemma_detail?.lemma_name).then(()=>{
+ this.load_detail();
+ });
},
async toggle_expand() {
if(!this.lemma_detail){
@@ -150,7 +145,7 @@
this.expanded = !this.expanded;
},
async load_detail(){
- this.lemma_detail = await $store.dictionary.fetchOneLemmaDetail(item.lemma_name);
+ this.lemma_detail = await $store.dictionary.fetch_one_lemma_detail(item.lemma_name);
}
}">
@@ -171,33 +166,71 @@
+
Trofal
Imi
@@ -210,9 +243,12 @@
}" @click.outside="editing = false">
-
-
-
+
+
+
diff --git a/apps/ktb-static/styles.css b/apps/ktb-static/styles.css
index 2663ad0..afaf90a 100644
--- a/apps/ktb-static/styles.css
+++ b/apps/ktb-static/styles.css
@@ -3,6 +3,7 @@
--color-primary: #0bf;
--color-secondary: #08e;
--color-edit: #fb0;
+ --color-delete: #b10;
--color-main-bg: #eee;
--color-card-bg: #fff;
--color-text: #333;
@@ -120,13 +121,21 @@ button:disabled{
}
.edit {
- background-color: #fb0;
+ background-color: var(--color-edit);
}
.edit:hover {
background-color: #bb0;
}
+.delete {
+ background-color: var(--color-delete);
+}
+
+.delete:hover {
+ background-color: #f00;
+}
+
.hollow {
background-color: #00000000;
border-style: solid;
@@ -135,7 +144,14 @@ button:disabled{
.hollow.primary {
border-color: var(--color-primary);
-
+}
+
+.hollow.edit {
+ border-color: var(--color-edit);
+}
+
+.hollow.delete {
+ border-color: var(--color-delete);
}
.primary:not(.hollow) {
@@ -188,6 +204,7 @@ button:disabled{
display: flex;
flex-direction: column;
gap: var(--space-md);
+ resize: horizontal;
}
.sidebar-header {
diff --git a/apps/vdb-backend/src/index.ts b/apps/vdb-backend/src/index.ts
index c743efd..76fb12b 100644
--- a/apps/vdb-backend/src/index.ts
+++ b/apps/vdb-backend/src/index.ts
@@ -105,6 +105,8 @@ function initExpress() {
res.status(200).send({ lemma_detail });
});
+ /* Definitions */
+
app.put("/definition", async (_req, res) => {
const definition_text = _req.body.definition_text?.toString();
const definition_id = _req.body.definition_id ?? null;
@@ -123,7 +125,7 @@ function initExpress() {
return void res.status(400).send();
}
- var definition:Definition = new Definition();
+ let definition:Definition = new Definition();
definition.definition_text = definition_text;
definition.lemma = lemma;
if(definition_id){
@@ -132,7 +134,7 @@ function initExpress() {
Definition.save(definition)
- var lemma_detail = await Lemma.findOne({
+ let lemma_detail = await Lemma.findOne({
where: {
lemma_name: lemma_name
},
@@ -150,6 +152,8 @@ function initExpress() {
res.status(200).send({lemma_detail});
});
+ /* examples */
+
app.put("/example", async (_req, res) => {
const example_text = _req.body.example_text?.toString();
const example_id = _req.body.example_id ?? null;
@@ -195,6 +199,112 @@ function initExpress() {
res.status(200).send({lemma_detail});
});
+ /* word forms */
+
+ app.put("/word-form", async (_req, res) => {
+ const word_form_text = _req.body.word_form_text?.toString();
+ const word_form_id = _req.body.word_form_id ?? null;
+ const lemma_name = _req.body.lemma_name ?? null;
+
+ if(!word_form_text || /^\s*$/.test(word_form_text) || !word_form_id){
+ console.error(`Error: ${JSON.stringify({word_form_text:word_form_text, word_form_id:word_form_id})}`);
+ return void res.status(400).send();
+ }
+
+ let word_form = await WordForm.findOne({where:{
+ word_form_id: word_form_id
+ }, relations:{
+ lemma: true
+ }});
+
+ if(!word_form){
+ if(lemma_name){
+ word_form = new WordForm();
+ let lemma = await Lemma.findOne({where:{lemma_name}});
+ }
+ console.error(`Failed to find word form with ID ${word_form_id}`)
+ return void res.status(400).send();
+ }
+
+
+ word_form.word_form = word_form_text;
+
+ WordForm.save(word_form);
+
+ let lemma_detail = await Lemma.findOne({
+ where: {
+ lemma_name: word_form.lemma.lemma_name
+ },
+ relations: {
+ word_forms: {
+ lect: true
+ },
+ examples: true,
+ definitions: true,
+ media: true,
+ parts_of_speech: true
+ }
+ });
+
+ res.status(200).send({lemma_detail});
+ });
+
+ app.post("/word-form", async (_req, res) => {
+ const lemma_name = _req.body.lemma_name ?? null;
+ const lect_name = _req.body.lect_name ?? null;
+ const word_form_text = _req.body.word_form_text?.toString();
+
+ if(!word_form_text || /^\s*$/.test(word_form_text) || !lect_name || !lemma_name){
+ console.error(`Error: ${JSON.stringify(_req.body)}`);
+ return void res.status(400).send();
+ }
+
+ let word_form = new WordForm();
+ let lemma = await Lemma.findOne({where:{lemma_name}});
+ let lect = await Lect.findOne({where:{name:lect_name}});
+
+ if(!lect || !lemma){
+ console.error(`Error: ${JSON.stringify({lect:lect, lemma:lemma})}`);
+ return void res.status(400).send();
+ }
+
+ word_form.word_form = word_form_text;
+ word_form.lemma = lemma;
+ word_form.lect = lect;
+
+ WordForm.save(word_form);
+
+ let lemma_detail = await Lemma.findOne({
+ where: {
+ lemma_name: word_form.lemma.lemma_name
+ },
+ relations: {
+ word_forms: {
+ lect: true
+ },
+ examples: true,
+ definitions: true,
+ media: true,
+ parts_of_speech: true
+ }
+ });
+
+ res.status(200).send({lemma_detail});
+ });
+
+ app.delete("/word-form/:word_form_id", async (_req, res) =>{
+ const word_form_id:number = parseInt(_req.params.word_form_id);
+
+ if(!word_form_id){
+ console.error(`Error: Could not find word form ${JSON.stringify({word_form_id:word_form_id})}`);
+ return void res.status(400).send();
+ }
+
+ WordForm.delete({word_form_id: word_form_id});
+
+ res.status(200).send();
+ });
+
app.listen(PORT, () => {
console.log(`Backend started @ http://localhost:${PORT} !`);
console.log(SAMPLE);