From ad24981a0bae72dea2f825ea4d270acbfc9e7222 Mon Sep 17 00:00:00 2001 From: Gerd Date: Tue, 1 Sep 2026 10:45:48 +0200 Subject: [PATCH] Listen: einheitliche Zeilen-Markierung und kompakte Aktions-Buttons MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Alle App-Listen (kundenliste, call_log_liste, kontaktliste, kontaktadresseliste, TagList) auf das isSelected-Callback der Treetable umgestellt — die Markierung erfolgt jetzt auf der gesamten -Zeile via w3-theme-l4 statt per-Zell-Inline-Style. In der kundenliste sind die 3 Aktions-Buttons (edit, Projekte, Kontakte) kompakt in einer Zelle zusammengefasst, analog zur projektliste. Auth-Listen unberührt. Generated by Mistral Vibe. Co-Authored-By: Mistral Vibe --- Client/Components/call_log.ts | 25 ++++++++++++------------- Client/Components/kontakt.ts | 17 ++++++++--------- Client/Components/kontaktadresse.ts | 19 +++++++++---------- Client/Components/kunde.ts | 27 ++++++++++++++------------- Client/Components/tags.ts | 17 ++++++++--------- 5 files changed, 51 insertions(+), 54 deletions(-) diff --git a/Client/Components/call_log.ts b/Client/Components/call_log.ts index 803c527..6f9a377 100644 --- a/Client/Components/call_log.ts +++ b/Client/Components/call_log.ts @@ -77,18 +77,16 @@ export const call_log_liste: m.ClosureComponent = (vnode) => { const columnmapper: (node: iTreenode) => any[] = (node: iTreenode) => { let log: iCallLog = node.nodevalue - const isSelected = selectedNode === node - const cellStyle = isSelected ? {backgroundColor: '#e6f7ff'} : {} - + return [ - m("div", {style: cellStyle}, m("strong", log.kundenName + ": " + log.projektName)), - m("span", {style: cellStyle}, log.datum), - m("span", {style: cellStyle}, log.uhrzeitBeginn), - m("span", {style: cellStyle}, log.dauer + " min"), - m("span", {style: cellStyle}, log.betreff), - m("span", {style: cellStyle}, log.wiedervorlageDatum), - m("span", {style: cellStyle}, log.erledigt ? "Erledigt" : "Offen"), - m("button.w3-button.w3-small", {style: cellStyle, onclick: (e: Event) => editCallLog(log, e)}, m("i.material-icons", "edit")) + m("div", m("strong", log.kundenName + ": " + log.projektName)), + m("span", log.datum), + m("span", log.uhrzeitBeginn), + m("span", log.dauer + " min"), + m("span", log.betreff), + m("span", log.wiedervorlageDatum), + m("span", log.erledigt ? "Erledigt" : "Offen"), + m("button.w3-button.w3-small", {style: {padding: '0 2px'}, onclick: (e: Event) => editCallLog(log, e)}, m("i.material-icons", "edit")) ] } @@ -124,12 +122,13 @@ export const call_log_liste: m.ClosureComponent = (vnode) => { 'overflow-y': 'inherit'}}, m("h1", "Gesprächsnotizen"), m("div", {style: {flex: '1', 'overflow-y': 'inherit'}}, - m(Treetable, + m(Treetable, { treenodes: treenodes, columnmapper: columnmapper, filter: filterFunction, - onRowMarked: handleRowMarked + onRowMarked: handleRowMarked, + isSelected: (node: iTreenode) => node === selectedNode } as iTreetable, m(TopbarButton, {onclick: addCallLogRoute, tooltip: "Neue Gesprächsnotiz anlegen"} as iTopbarButton, m("i.material-icons", "add_call") diff --git a/Client/Components/kontakt.ts b/Client/Components/kontakt.ts index cfff427..3e2717b 100644 --- a/Client/Components/kontakt.ts +++ b/Client/Components/kontakt.ts @@ -61,16 +61,14 @@ export const kontaktliste: m.ClosureComponent = (vnode) => { const columnmapper: (node: iTreenode) => any[] = (node: iTreenode) => { let kontakt: iKontakt = node.nodevalue - const isSelected = selectedNode === node - const cellStyle = isSelected ? {backgroundColor: '#e6f7ff'} : {} return [ - m("div", {style: cellStyle}, m("strong", kontakt.name)), - m("span", {style: cellStyle}, kontakt.position), - m("span", {style: cellStyle}, kontakt.telefon), - m("span", {style: cellStyle}, kontakt.email), - m("span", {style: cellStyle}, kontakt.kundenName), - m("button.w3-button.w3-small", {style: cellStyle, onclick: (e: Event) => editKontakt(kontakt, e)}, m("i.material-icons", "edit")) + m("div", m("strong", kontakt.name)), + m("span", kontakt.position), + m("span", kontakt.telefon), + m("span", kontakt.email), + m("span", kontakt.kundenName), + m("button.w3-button.w3-small", {style: {padding: '0 2px'}, onclick: (e: Event) => editKontakt(kontakt, e)}, m("i.material-icons", "edit")) ] } @@ -108,7 +106,8 @@ export const kontaktliste: m.ClosureComponent = (vnode) => { treenodes: treenodes, columnmapper: columnmapper, filter: filterFunction, - onRowMarked: handleRowMarked + onRowMarked: handleRowMarked, + isSelected: (node: iTreenode) => node === selectedNode } as iTreetable, m(TopbarButton, {onclick: addKontaktRoute, tooltip: "Neuen Kontakt anlegen"} as iTopbarButton, m("i.material-icons", "person_add") diff --git a/Client/Components/kontaktadresse.ts b/Client/Components/kontaktadresse.ts index 5640e87..e03d3f9 100644 --- a/Client/Components/kontaktadresse.ts +++ b/Client/Components/kontaktadresse.ts @@ -69,17 +69,15 @@ export const kontaktadresseliste: m.ClosureComponent = (vnode) => { const columnmapper: (node: iTreenode) => any[] = (node: iTreenode) => { let kontaktadresse: iKontaktadresse = node.nodevalue - const isSelected = selectedNode === node - const cellStyle = isSelected ? {backgroundColor: '#e6f7ff'} : {} return [ - m("div", {style: cellStyle}, m("strong", kontaktadresse.name)), - m("span", {style: cellStyle}, kontaktadresse.firma), - m("span", {style: cellStyle}, kontaktadresse.telefon), - m("span", {style: cellStyle}, kontaktadresse.email), - m("span", {style: cellStyle}, kontaktadresse.ort), - m("span", {style: cellStyle}, kontaktadresse.projektName), - m("button.w3-button.w3-small", {style: cellStyle, onclick: (e: Event) => editKontaktadresse(kontaktadresse, e)}, m("i.material-icons", "edit")) + m("div", m("strong", kontaktadresse.name)), + m("span", kontaktadresse.firma), + m("span", kontaktadresse.telefon), + m("span", kontaktadresse.email), + m("span", kontaktadresse.ort), + m("span", kontaktadresse.projektName), + m("button.w3-button.w3-small", {style: {padding: '0 2px'}, onclick: (e: Event) => editKontaktadresse(kontaktadresse, e)}, m("i.material-icons", "edit")) ] } @@ -118,7 +116,8 @@ export const kontaktadresseliste: m.ClosureComponent = (vnode) => { treenodes: treenodes, columnmapper: columnmapper, filter: filterFunction, - onRowMarked: handleRowMarked + onRowMarked: handleRowMarked, + isSelected: (node: iTreenode) => node === selectedNode } as iTreetable, m(TopbarButton, {onclick: addKontaktadresseRoute, tooltip: "Neue Kontaktadresse anlegen"} as iTopbarButton, m("i.material-icons", "person_add") diff --git a/Client/Components/kunde.ts b/Client/Components/kunde.ts index c5c0f2d..6a20ee9 100644 --- a/Client/Components/kunde.ts +++ b/Client/Components/kunde.ts @@ -115,18 +115,18 @@ export const kundenliste: m.ClosureComponent = (vnode) => { const columnmapper: (node: iTreenode) => any[] = (node: iTreenode) => { let kunde: iKunde = node.nodevalue - const isSelected = selectedNode === node - const cellStyle = isSelected ? {backgroundColor: 'lightgray'} : {} - + return [ - m("div", {style: cellStyle}, m("strong", kunde.name)), - m("span", {style: cellStyle}, kunde.strasse), - m("span", {style: cellStyle}, kunde.plz), - m("span", {style: cellStyle}, kunde.ort), - m("span", {style: cellStyle}, kunde.land), - m("button.w3-button.w3-small", {style: cellStyle, onclick: (e: Event) => editKunde(kunde, e)}, m("i.material-icons", "edit")), - m("button.w3-button.w3-small", {style: cellStyle, onclick: (e: Event) => showProjekte(kunde, e)}, m("i.material-icons", "library_books")), - m("button.w3-button.w3-small", {title: "Kontakte anzeigen", style: cellStyle, onclick: (e: Event) => showKontakte(kunde, e)}, m("i.material-icons", "contact_page")) + m("div", m("strong", kunde.name)), + m("span", kunde.strasse), + m("span", kunde.plz), + m("span", kunde.ort), + m("span", kunde.land), + m("div", {style: {display: 'flex', gap: '0', 'white-space': 'nowrap'}}, + m("button.w3-button.w3-small", {style: {padding: '0 2px'}, onclick: (e: Event) => editKunde(kunde, e)}, m("i.material-icons", "edit")), + m("button.w3-button.w3-small", {style: {padding: '0 2px'}, onclick: (e: Event) => showProjekte(kunde, e)}, m("i.material-icons", "library_books")), + m("button.w3-button.w3-small", {title: "Kontakte anzeigen", style: {padding: '0 2px'}, onclick: (e: Event) => showKontakte(kunde, e)}, m("i.material-icons", "contact_page")) + ) ] } @@ -150,12 +150,13 @@ export const kundenliste: m.ClosureComponent = (vnode) => { 'overflow-y': 'inherit'}}, m("h1", "Kundenliste"), m("div", {style: {flex: '1', 'overflow-y': 'inherit'}}, - m(Treetable, + m(Treetable, { treenodes: treenodes, columnmapper: columnmapper, filter: filterFunction, - onRowMarked: handleRowMarked + onRowMarked: handleRowMarked, + isSelected: (node: iTreenode) => node === selectedNode } as iTreetable, m(TopbarButton, {onclick: addKundeRoute, tooltip: "Neuen Kunden anlegen"} as iTopbarButton, m("i.material-icons", "person_add") diff --git a/Client/Components/tags.ts b/Client/Components/tags.ts index c7f71d8..1ffcce5 100644 --- a/Client/Components/tags.ts +++ b/Client/Components/tags.ts @@ -598,11 +598,9 @@ export const TagList: m.ClosureComponent = (vnode) => { const columnmapper: (node: iTreenode) => any[] = (node: iTreenode) => { let tag: iTag = node.nodevalue; - const isSelected = selectedNode === node; - const cellStyle = isSelected ? {backgroundColor: 'lightgray'} : {}; - + return [ - m("span", {style: cellStyle}, + m("span", m("span", { style: { backgroundColor: tag.color, @@ -615,9 +613,9 @@ export const TagList: m.ClosureComponent = (vnode) => { } }, tag.name) ), - m("span", {style: cellStyle}, tag.description), - m("div", {style: cellStyle}, - m("button.w3-button.w3-small", {onclick: (e: Event) => editTag(tag, e)}, + m("span", tag.description), + m("div", + m("button.w3-button.w3-small", {style: {padding: '0 2px'}, onclick: (e: Event) => editTag(tag, e)}, m("i.material-icons", "edit") ) ) @@ -647,12 +645,13 @@ export const TagList: m.ClosureComponent = (vnode) => { m("h1", "Tags"), m("p.w3-text-grey", "Hierarchie: Tags können beliebig verschachtelt werden (z. B. Backend → Python → Flask)."), m("div", {style: {flex: '1', 'overflow-y': 'inherit'}}, - m(Treetable, + m(Treetable, { treenodes: treenodes, columnmapper: columnmapper, filter: filterFunction, - onRowMarked: handleRowMarked + onRowMarked: handleRowMarked, + isSelected: (node: iTreenode) => node === selectedNode } as iTreetable ) )