feat(nav): Breadcrumb-Navigation für Hierarchie-Aufrufkette
Neue BreadcrumbBar-Widget-Komponente (breadcrumb.ts) zeigt die Aufrufkette als anklickbare Leiste. Der Route-Param bc (JSON-String) transportiert die Vorgänger-Ansichten durch alle Listen und Masken. Jede Ansicht hängt beim Weiternavigieren ihren eigenen Crumb an die Kette an; Masken reichen bc beim Speichern/Abbrechen zurück. Erfasst: kunde, projekt, kontaktadresse, call_log, kontakt. Generated by Mistral Vibe. Co-Authored-By: Mistral Vibe <vibe@mistral.ai>
This commit is contained in:
1 parent
f1e5938ae1
commit
fd30049a32
6 files changed
+316
-27
No files matched your search
@@ -3,6 +3,7 @@ import {Form, iForm} from "./widgets/form"
|
||||
import { Input, iInput, Textarea, iTextarea} from "./widgets/inputs"
|
||||
import {Select, iSelect, MultiSelect, iMultiSelect, iSelectOption} from "./widgets/select"
|
||||
import {Treenode, iTreenode, Treetable, iTreetable, TopbarButton, iTopbarButton} from "./widgets/Treetable_V2"
|
||||
import {BreadcrumbBar, iBreadcrumb, iBreadcrumbBar, parseBc, serializeBc} from "./widgets/breadcrumb"
|
||||
import {iCallLog, fetchCallLogs, fetchCallLogById, createCallLogREST, updateCallLogREST} from "../models/call_log"
|
||||
import {iKunde, fetchKunden} from "../models/kunde"
|
||||
import {iProjekt, fetchProjekte, fetchProjektById} from "../models/projekt"
|
||||
@@ -22,11 +23,20 @@ export const call_log_liste: m.ClosureComponent = (vnode) => {
|
||||
// da es nicht in den Route-Params enthalten ist.
|
||||
let projektName: string = ""
|
||||
let kundenName: string = ""
|
||||
// Breadcrumb-Kette der Vorgänger-Ansichten (aus Route-Param bc).
|
||||
let breadcrumbs: iBreadcrumb[] = []
|
||||
|
||||
const handleRowMarked = (node: iTreenode) => {
|
||||
selectedNode = node
|
||||
}
|
||||
|
||||
// Eigener Listen-Crumb für die Breadcrumb-Kette.
|
||||
const ownCrumb = (): iBreadcrumb => ({
|
||||
route: "/calllogliste",
|
||||
params: filterProjektId !== null ? {projekt_id: filterProjektId} : {},
|
||||
label: filterProjektId !== null ? "Notizen: " + projektName : "Gesprächsnotizen"
|
||||
})
|
||||
|
||||
const addCallLogRoute = () => {
|
||||
const now = new Date()
|
||||
const datum = now.toISOString().split('T')[0]
|
||||
@@ -51,6 +61,8 @@ export const call_log_liste: m.ClosureComponent = (vnode) => {
|
||||
params.return_projekt_id = filterProjektId
|
||||
params.return_projekt_name = projektName
|
||||
}
|
||||
// Breadcrumb-Kette um eigene Position erweitern.
|
||||
params.bc = serializeBc([...breadcrumbs, ownCrumb()])
|
||||
m.route.set("/call_log", params)
|
||||
}
|
||||
|
||||
@@ -61,6 +73,8 @@ export const call_log_liste: m.ClosureComponent = (vnode) => {
|
||||
params.return_projekt_id = filterProjektId
|
||||
params.return_projekt_name = projektName
|
||||
}
|
||||
// Breadcrumb-Kette um eigene Position erweitern.
|
||||
params.bc = serializeBc([...breadcrumbs, ownCrumb()])
|
||||
m.route.set("/call_log", params)
|
||||
}
|
||||
|
||||
@@ -118,6 +132,8 @@ export const call_log_liste: m.ClosureComponent = (vnode) => {
|
||||
filterProjektId = null
|
||||
projektName = ""
|
||||
}
|
||||
// Breadcrumb-Kette aus Route-Param parsen.
|
||||
breadcrumbs = parseBc(routeParams && routeParams.bc)
|
||||
// Gesprächsnotizen asynchron vom Server laden. Die Filterung
|
||||
// nach projekt_id erfolgt serverseitig, sofern ein Filter
|
||||
// gesetzt ist.
|
||||
@@ -143,6 +159,10 @@ export const call_log_liste: m.ClosureComponent = (vnode) => {
|
||||
height: 'inherit',
|
||||
'overflow-y': 'inherit'}},
|
||||
m("h1", projektName ? "Gesprächsnotizen für " + projektName : "Gesprächsnotizen"),
|
||||
m(BreadcrumbBar, {
|
||||
breadcrumbs: breadcrumbs,
|
||||
current: filterProjektId !== null ? "Notizen: " + projektName : "Gesprächsnotizen"
|
||||
} as iBreadcrumbBar),
|
||||
m("div", {style: {flex: '1', 'overflow-y': 'inherit'}},
|
||||
m(Treetable,
|
||||
{
|
||||
@@ -219,6 +239,8 @@ export const Call_Log: m.ClosureComponent = (vnode) => {
|
||||
// null bedeutet ungefiltert; ein Wert bedeutet projektgefiltert.
|
||||
let returnProjektId: number | null = null
|
||||
let returnProjektName: string = ""
|
||||
// Breadcrumb-Kette der Vorgänger-Ansichten (aus Route-Param bc).
|
||||
let breadcrumbs: iBreadcrumb[] = []
|
||||
|
||||
/**
|
||||
* Formatiert verstrichene Sekunden als mm:ss.
|
||||
@@ -240,6 +262,8 @@ export const Call_Log: m.ClosureComponent = (vnode) => {
|
||||
returnProjektId = parseInt(routeParams.return_projekt_id)
|
||||
returnProjektName = routeParams.return_projekt_name || ""
|
||||
}
|
||||
// Breadcrumb-Kette aus Route-Param parsen.
|
||||
breadcrumbs = parseBc(routeParams && routeParams.bc)
|
||||
if (id !== -1) {
|
||||
// Gesprächsnotiz frisch vom Server holen.
|
||||
fetchCallLogById(id).then((result) => {
|
||||
@@ -334,6 +358,11 @@ export const Call_Log: m.ClosureComponent = (vnode) => {
|
||||
params.projekt_id = currentLog.projekt_id
|
||||
params.projekt_name = currentLog.projekt_name
|
||||
}
|
||||
// Breadcrumb-Kette ohne das letzte Glied (die Notizliste
|
||||
// selbst) an die Liste durchreichen, damit diese die
|
||||
// Vorgänger-Ansichten wieder als Leiste anzeigen kann.
|
||||
const listBc = serializeBc(breadcrumbs.slice(0, -1))
|
||||
if (listBc) params.bc = listBc
|
||||
m.route.set("/calllogliste", params)
|
||||
}
|
||||
|
||||
@@ -367,6 +396,10 @@ export const Call_Log: m.ClosureComponent = (vnode) => {
|
||||
}
|
||||
return m("div.w3-container.w3-auto.form-view-container",
|
||||
m("h1", currentLog.id === -1 ? "Neue Gesprächsnotiz anlegen" : "Gesprächsnotiz"),
|
||||
m(BreadcrumbBar, {
|
||||
breadcrumbs: breadcrumbs,
|
||||
current: currentLog.id === -1 ? "Neue Gesprächsnotiz" : "Gesprächsnotiz"
|
||||
} as iBreadcrumbBar),
|
||||
m("div", {style: {flex: '1', 'min-height': '0'}},
|
||||
m(Form, {showButtons: true, onsubmit: submit, oncancel: cancel} as iForm, [
|
||||
m("input", {type: "hidden", name: "projekt_id", value: currentLog.projekt_id}),
|
||||
|
||||
Reference in new issue
Block a user