feat(crm): zentrale TagBadge-Komponente und Ergänzungen zur Workflow-Maske

- Position des Ansprechpartners in der Kopfzeile der Tagesworkflow-Maske anzeigen
- Neue TagBadge-Komponente (Farbchip, Name, Workflow-Icons: erledigend/
  Wiedervorlage) ersetzt die duplizierte Badge-Darstellung in Notiz-Liste,
  Workflow-Liste, Historie und Tag-Liste
- MultiSelect: optionale content-Option rendert ein fertiges Badge des
  Aufrufers statt Farbpunkt + Label im Auswahl-Modal; Suchfeld wird beim
  Öffnen des Modals fokussiert
- TagBadge-Attribut heißt tagData statt tag, da Mithril attrs-Objekte mit
  tag-Property als Vnode-Kinder behandelt (führte zu 'color' undefined)

Generated by Mistral Vibe.
Co-Authored-By: Mistral Vibe <vibe@mistral.ai>
This commit is contained in:
gg committed 2026-09-27 18:37:49 +02:00
1 parent 2ff4272ecd
commit bc9b337696
5 files changed
+156 -106

No files matched your search

+36 -11
View File
@@ -8,6 +8,11 @@ export interface iSelectOption {
value: any
/** Anzeige im Feld bzw. in der Dropdown-Liste (z.B. Kundenname). */
label: string
/** Optionaler fertiger Darstellungs-Content (z.B. eine Badge-Komponente),
* der im Auswahl-Modal des MultiSelect statt Farbpunkt und Label
* angezeigt wird. Das label bleibt davon unberührt — es ist weiterhin
* die Basis für die Suche im Modal. */
content?: m.Child
}
/**
@@ -491,12 +496,18 @@ export const MultiSelect: m.ClosureComponent<iMultiSelect> = () => {
m("h2", modalTitle)
),
m("div.w3-container.w3-theme-l1", {style: {padding: '16px'}},
// Suchfeld.
// Suchfeld. Der oncreate-Hook fokussiert das
// Feld direkt beim Öffnen des Modals — das
// Input wird ja erst mit dem Modal erzeugt,
// sodass der Nutzer sofort tippen kann.
m("input.w3-input.w3-border", {
type: "text",
value: search,
placeholder: "Suchbegriff …",
style: {'margin-bottom': '10px', width: '100%'},
oncreate: (vnode: m.VnodeDOM) => {
(vnode.dom as HTMLInputElement).focus()
},
oninput: (e: Event) => {
search = (e.target as HTMLInputElement).value
}
@@ -526,19 +537,33 @@ export const MultiSelect: m.ClosureComponent<iMultiSelect> = () => {
toggleDraft(option)
}
}),
color
// Ist ein fertiger content gesetzt (z.B. eine
// Badge-Komponente des Aufrufers), wird dieser
// statt Farbpunkt und Label angezeigt — das
// Widget selbst bleibt frei von Tag-Wissen.
option.content
? m("span", {
style: {
display: 'inline-block',
width: '10px',
height: '10px',
borderRadius: '50%',
backgroundColor: color,
flex: '0 0 auto'
display: 'inline-flex',
alignItems: 'center',
flex: '1 1 auto'
}
})
: null,
m("span", option.label)
}, option.content)
: [
color
? m("span", {
style: {
display: 'inline-block',
width: '10px',
height: '10px',
borderRadius: '50%',
backgroundColor: color,
flex: '0 0 auto'
}
})
: null,
m("span", option.label)
]
)
})
),