Client: Kunden-Datenhaltung auf Server-REST-Endpunkte umgestellt
In-Memory-Datenhaltung (kundenDaten, getNewKundeId, addKunde, updateKunde, getKunden) aus kunde.ts entfernt. Die Kundenliste und das Formular nutzen jetzt fetchKunden/createKundeREST/updateKundeREST asynchron vom Server. projekt.ts, kontakt.ts, call_log.ts: getKunden() durch asynchrones fetchKunden() im oninit ersetzt, Kundenliste im Closure-State gehalten. Generated by Mistral Vibe. Co-Authored-By: Mistral Vibe <vibe@mistral.ai>
This commit is contained in:
1 parent
13eaaec9c1
commit
15d4e2ac48
5 files changed
+58
-78
No files matched your search
@@ -4,7 +4,7 @@ import { Input, iInput, Textarea, iTextarea} from "./widgets/inputs"
|
||||
import {Select, iSelect, iSelectOption} from "./widgets/select"
|
||||
import {Treenode, iTreenode, Treetable, iTreetable, TopbarButton, iTopbarButton} from "./widgets/Treetable_V2"
|
||||
import {iCallLog, getCallLogsByProjektId, getNewCallLogId, addCallLogData, updateCallLogData} from "../models/call_log"
|
||||
import {iKunde, getKunden} from "../models/kunde"
|
||||
import {iKunde, fetchKunden} from "../models/kunde"
|
||||
import {getProjekteByKundenId, getProjektById} from "../models/projekt"
|
||||
import {getKontaktadressenByProjektId, getKontaktadresseById} from "../models/kontaktadresse"
|
||||
|
||||
@@ -190,6 +190,8 @@ export const Call_Log: m.ClosureComponent = (vnode) => {
|
||||
// ohne Redraw aktualisieren kann (ein Redraw würde die übrigen Felder
|
||||
// mit den veralteten currentLog-Werten überschreiben).
|
||||
let dauerInput: HTMLInputElement | null = null
|
||||
// Kundenliste asynchron vom Server laden, für Select-Optionen.
|
||||
let kundenListe: iKunde[] = []
|
||||
|
||||
/**
|
||||
* Formatiert verstrichene Sekunden als mm:ss (Minuten:Sekunden).
|
||||
@@ -246,6 +248,10 @@ export const Call_Log: m.ClosureComponent = (vnode) => {
|
||||
}, DAUER_UPDATE_INTERVALL)
|
||||
}
|
||||
}
|
||||
// Kundenliste asynchron vom Server laden.
|
||||
fetchKunden().then((result) => {
|
||||
kundenListe = result
|
||||
})
|
||||
},
|
||||
onremove: (vnode) => {
|
||||
// Timer stoppen, damit er nach Verlassen des Views nicht weiterläuft.
|
||||
@@ -253,7 +259,7 @@ export const Call_Log: m.ClosureComponent = (vnode) => {
|
||||
},
|
||||
view: (vnode) => {
|
||||
// Select-Optionen aus Kunden- und Projektliste aufbauen.
|
||||
const kundenOptionen: iSelectOption[] = getKunden().map((k: iKunde) => {
|
||||
const kundenOptionen: iSelectOption[] = kundenListe.map((k: iKunde) => {
|
||||
return {value: k.id, label: k.name}
|
||||
})
|
||||
// Projekt-Optionen sind vom gewählten Kunden abhängig.
|
||||
|
||||
@@ -4,7 +4,7 @@ import { Input, iInput, Textarea, iTextarea} from "./widgets/inputs"
|
||||
import {Select, iSelect, iSelectOption} from "./widgets/select"
|
||||
import {Treenode, iTreenode, Treetable, iTreetable, TopbarButton, iTopbarButton} from "./widgets/Treetable_V2"
|
||||
import {iKontakt, getKontakteByKundenId, getNewKontaktId, addKontakt, updateKontakt} from "../models/kontakt"
|
||||
import {iKunde, getKunden} from "../models/kunde"
|
||||
import {iKunde, fetchKunden} from "../models/kunde"
|
||||
|
||||
function createKontaktTreenodes(kundenId: number | null = null): iTreenode[] {
|
||||
let filteredKontakte = getKontakteByKundenId(kundenId)
|
||||
@@ -18,6 +18,9 @@ export const kontaktliste: m.ClosureComponent = (vnode) => {
|
||||
let treenodes: iTreenode[] = createKontaktTreenodes()
|
||||
let selectedNode: iTreenode | null = null
|
||||
let filterKundenId: number | null = null
|
||||
// Kundenliste asynchron vom Server laden, für die Kundenauflösung
|
||||
// beim Anlegen eines neuen Kontakts.
|
||||
let kundenListe: iKunde[] = []
|
||||
|
||||
const handleRowMarked = (node: iTreenode) => {
|
||||
selectedNode = node
|
||||
@@ -35,7 +38,7 @@ export const kontaktliste: m.ClosureComponent = (vnode) => {
|
||||
}
|
||||
// Nur bei kundengefilterter Liste den Kunden vorbelegen.
|
||||
if (filterKundenId !== null) {
|
||||
const kunde = getKunden().find((k: iKunde) => k.id === filterKundenId)
|
||||
const kunde = kundenListe.find((k: iKunde) => k.id === filterKundenId)
|
||||
if (kunde) {
|
||||
params.kundenId = kunde.id
|
||||
params.kundenname = kunde.name
|
||||
@@ -91,6 +94,10 @@ export const kontaktliste: m.ClosureComponent = (vnode) => {
|
||||
filterKundenId = null
|
||||
}
|
||||
treenodes = createKontaktTreenodes(filterKundenId)
|
||||
// Kundenliste asynchron vom Server laden.
|
||||
fetchKunden().then((result) => {
|
||||
kundenListe = result
|
||||
})
|
||||
},
|
||||
view: (vnode) => {
|
||||
return m("div.w3-container.w3-auto", {
|
||||
@@ -145,6 +152,9 @@ export const Kontakt: m.ClosureComponent = (vnode) => {
|
||||
}
|
||||
// Ist der Kunde voreingestellt (gefilterte Kontaktliste)?
|
||||
let kundeVoreingestellt: boolean = false
|
||||
// Kundenliste asynchron vom Server laden, für Select-Optionen und
|
||||
// Namensauflösung im submit-Handler.
|
||||
let kundenListe: iKunde[] = []
|
||||
|
||||
return {
|
||||
oninit: (vnode) => {
|
||||
@@ -164,13 +174,16 @@ export const Kontakt: m.ClosureComponent = (vnode) => {
|
||||
notiz: routeParams.notiz || ""
|
||||
}
|
||||
}
|
||||
fetchKunden().then((result) => {
|
||||
kundenListe = result
|
||||
})
|
||||
},
|
||||
view: (vnode) => {
|
||||
const submit = (form: HTMLFormElement): boolean => {
|
||||
const formData = new FormData(form)
|
||||
const kundenId = parseInt(formData.get("kundenId") as string)
|
||||
// Kundennamen zur gewählten kundenId auflösen.
|
||||
const kunde = getKunden().find((k: iKunde) => k.id === kundenId)
|
||||
const kunde = kundenListe.find((k: iKunde) => k.id === kundenId)
|
||||
const gespeicherterKontakt: iKontakt = {
|
||||
id: currentKontakt.id,
|
||||
kundenId: kundenId,
|
||||
@@ -195,7 +208,7 @@ export const Kontakt: m.ClosureComponent = (vnode) => {
|
||||
m.route.set("/kontaktliste")
|
||||
}
|
||||
// Select-Optionen aus der Kundenliste aufbauen.
|
||||
const kundenOptionen: iSelectOption[] = getKunden().map((k: iKunde) => {
|
||||
const kundenOptionen: iSelectOption[] = kundenListe.map((k: iKunde) => {
|
||||
return {value: k.id, label: k.name}
|
||||
})
|
||||
return m("div.w3-container.w3-auto.form-view-container",
|
||||
|
||||
+12
-19
@@ -2,7 +2,7 @@ import m from "mithril"
|
||||
import {Form, iForm} from "./widgets/form"
|
||||
import { Input, iInput} from "./widgets/inputs"
|
||||
import {Treenode, iTreenode, Treetable, iTreetable, TopbarButton, iTopbarButton} from "./widgets/Treetable_V2"
|
||||
import {iKunde, kundenDaten, getNewKundeId, addKunde, updateKunde} from "../models/kunde"
|
||||
import {iKunde, fetchKunden, createKundeREST, updateKundeREST} from "../models/kunde"
|
||||
|
||||
export const kunde: m.ClosureComponent = (vnode) => {
|
||||
let currentKunde: iKunde = {
|
||||
@@ -40,12 +40,10 @@ export const kunde: m.ClosureComponent = (vnode) => {
|
||||
land: (formData.get("land") as string) || ""
|
||||
}
|
||||
if (currentKunde.id === -1) {
|
||||
gespeicherterKunde.id = getNewKundeId()
|
||||
addKunde(gespeicherterKunde)
|
||||
createKundeREST(gespeicherterKunde).then(() => m.route.set("/kundenliste"))
|
||||
} else {
|
||||
updateKunde(gespeicherterKunde)
|
||||
updateKundeREST(gespeicherterKunde).then(() => m.route.set("/kundenliste"))
|
||||
}
|
||||
m.route.set("/kundenliste")
|
||||
return true
|
||||
}
|
||||
const cancel = (e: Event) => {
|
||||
@@ -74,22 +72,10 @@ export const kunde: m.ClosureComponent = (vnode) => {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Erzeugt aus der Kundendatenliste die Treenode-Struktur für die Treetable der
|
||||
* Kundenliste. Jeder Kunde wird zu einem expandierten Treenode ohne Kinder
|
||||
* (expand=true, children=[]) - d.h. ein Blattknoten, der sofort in der
|
||||
* Tabelle sichtbar ist und sich nicht weiter aufklappen lässt.
|
||||
*/
|
||||
function createKundenTreenodes(): iTreenode[] {
|
||||
return kundenDaten.map((kunde: iKunde) => {
|
||||
return new Treenode(kunde, true, [])
|
||||
})
|
||||
}
|
||||
|
||||
export const kundenliste: m.ClosureComponent = (vnode) => {
|
||||
let treenodes: iTreenode[] = createKundenTreenodes()
|
||||
let treenodes: iTreenode[] = []
|
||||
let selectedNode: iTreenode | null = null
|
||||
|
||||
|
||||
const handleRowMarked = (node: iTreenode) => {
|
||||
selectedNode = node
|
||||
}
|
||||
@@ -141,6 +127,13 @@ export const kundenliste: m.ClosureComponent = (vnode) => {
|
||||
}
|
||||
|
||||
return {
|
||||
oninit: (vnode) => {
|
||||
// Kundenliste asynchron vom Server laden. m.request löst nach
|
||||
// Promise-Auflösung automatisch ein Redraw aus.
|
||||
fetchKunden().then((kunden: iKunde[]) => {
|
||||
treenodes = kunden.map((kunde: iKunde) => new Treenode(kunde, true, []))
|
||||
})
|
||||
},
|
||||
view: (vnode) => {
|
||||
return m("div.w3-container.w3-auto", {
|
||||
style: {
|
||||
|
||||
@@ -4,7 +4,7 @@ import { Input, iInput} from "./widgets/inputs"
|
||||
import {Select, iSelect, iSelectOption} from "./widgets/select"
|
||||
import {Treenode, iTreenode, Treetable, iTreetable, TopbarButton, iTopbarButton} from "./widgets/Treetable_V2"
|
||||
import {iProjekt, getProjekteByKundenId, getNewProjektId, addProjekt, updateProjekt} from "../models/projekt"
|
||||
import {iKunde, getKunden} from "../models/kunde"
|
||||
import {iKunde, fetchKunden} from "../models/kunde"
|
||||
|
||||
function createProjektTreenodes(kundenId: number | null = null): iTreenode[] {
|
||||
let filteredProjekte = getProjekteByKundenId(kundenId)
|
||||
@@ -18,7 +18,10 @@ export const projektliste: m.ClosureComponent = (vnode) => {
|
||||
let treenodes: iTreenode[] = createProjektTreenodes()
|
||||
let selectedNode: iTreenode | null = null
|
||||
let filterKundenId: number | null = null
|
||||
|
||||
// Kundenliste asynchron vom Server laden, für die Kundenauflösung
|
||||
// beim Anlegen eines neuen Projekts.
|
||||
let kundenListe: iKunde[] = []
|
||||
|
||||
const handleRowMarked = (node: iTreenode) => {
|
||||
selectedNode = node
|
||||
}
|
||||
@@ -34,7 +37,7 @@ export const projektliste: m.ClosureComponent = (vnode) => {
|
||||
}
|
||||
// Nur bei kundengefilterter Liste den Kunden vorbelegen.
|
||||
if (filterKundenId !== null) {
|
||||
const kunde = getKunden().find((k: iKunde) => k.id === filterKundenId)
|
||||
const kunde = kundenListe.find((k: iKunde) => k.id === filterKundenId)
|
||||
if (kunde) {
|
||||
params.kundenId = kunde.id
|
||||
params.kundenname = kunde.name
|
||||
@@ -125,6 +128,10 @@ export const projektliste: m.ClosureComponent = (vnode) => {
|
||||
filterKundenId = null
|
||||
}
|
||||
treenodes = createProjektTreenodes(filterKundenId)
|
||||
// Kundenliste asynchron vom Server laden.
|
||||
fetchKunden().then((result) => {
|
||||
kundenListe = result
|
||||
})
|
||||
},
|
||||
view: (vnode) => {
|
||||
return m("div.w3-container.w3-auto", {
|
||||
@@ -175,6 +182,9 @@ export const Projekt: m.ClosureComponent = (vnode) => {
|
||||
}
|
||||
// Ist der Kunde voreingestellt (gefilterte Projektliste)?
|
||||
let kundeVoreingestellt: boolean = false
|
||||
// Kundenliste asynchron vom Server laden, für Select-Optionen und
|
||||
// Namensauflösung im submit-Handler.
|
||||
let kundenListe: iKunde[] = []
|
||||
|
||||
return {
|
||||
oninit: (vnode) => {
|
||||
@@ -192,13 +202,16 @@ export const Projekt: m.ClosureComponent = (vnode) => {
|
||||
startdatum: routeParams.startdatum || ""
|
||||
}
|
||||
}
|
||||
fetchKunden().then((result) => {
|
||||
kundenListe = result
|
||||
})
|
||||
},
|
||||
view: (vnode) => {
|
||||
const submit = (form: HTMLFormElement): boolean => {
|
||||
const formData = new FormData(form)
|
||||
const kundenId = parseInt(formData.get("kundenId") as string)
|
||||
// Kundennamen zur gewählten kundenId auflösen.
|
||||
const kunde = getKunden().find((k: iKunde) => k.id === kundenId)
|
||||
const kunde = kundenListe.find((k: iKunde) => k.id === kundenId)
|
||||
const gespeichertesProjekt: iProjekt = {
|
||||
id: currentProjekt.id,
|
||||
kundenId: kundenId,
|
||||
@@ -221,7 +234,7 @@ export const Projekt: m.ClosureComponent = (vnode) => {
|
||||
m.route.set("/projektliste")
|
||||
}
|
||||
// Select-Optionen aus der Kundenliste aufbauen.
|
||||
const kundenOptionen: iSelectOption[] = getKunden().map((k: iKunde) => {
|
||||
const kundenOptionen: iSelectOption[] = kundenListe.map((k: iKunde) => {
|
||||
return {value: k.id, label: k.name}
|
||||
})
|
||||
return m("div.w3-container.w3-auto.form-view-container",
|
||||
|
||||
Reference in new issue
Block a user