Skip to content

Commit 4165045

Browse files
committed
feat(kba-drafter): add ticket viewer, unreview, status filter, and UI improvements
- Add ticket viewer dialog to display original incident details * New "Ticket" button in KBA header with DocumentSearch icon * Modal dialog showing incident data (ID, summary, status, priority, assignee, notes, resolution) * Backend endpoint /api/csv-tickets/by-incident/<incident_id> for incident ID lookup * Frontend API function getCSVTicketByIncident() - Add unreview functionality for reviewed KBAs * "Zurück zu Entwurf" button with ArrowUndo icon * Allows resetting reviewed KBAs back to draft status for further editing - Redesign KBA overview list * Replace corner delete button with professional overflow menu (⋮) * Horizontal layout: content left, status badge right-aligned, menu button * Menu component with delete option - Add status filter dropdown to KBA overview * Filter options: All, draft, reviewed, published * Dropdown in card header for easy filtering - Align EditableList "Add" button width with input fields * Use invisible placeholder buttons for exact width matching * Ensures consistent layout regardless of allowReorder setting Files modified: - frontend/src/features/kba-drafter/KBADrafterPage.jsx - frontend/src/features/kba-drafter/components/EditableList.jsx - frontend/src/services/api.js - backend/app.py
1 parent de4a1aa commit 4165045

2 files changed

Lines changed: 140 additions & 55 deletions

File tree

frontend/src/features/kba-drafter/KBADrafterPage.jsx

Lines changed: 99 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,13 @@ import {
3535
DialogBody,
3636
DialogActions,
3737
DialogContent,
38+
Menu,
39+
MenuTrigger,
40+
MenuPopover,
41+
MenuList,
42+
MenuItem,
43+
Dropdown,
44+
Option,
3845
} from "@fluentui/react-components";
3946
import {
4047
DocumentText24Regular,
@@ -55,6 +62,7 @@ import {
5562
Search20Regular,
5663
DocumentSearch20Regular,
5764
ArrowUndo24Regular,
65+
MoreVertical20Regular,
5866
} from "@fluentui/react-icons";
5967
import * as api from "../../services/api";
6068
import EditableList from "./components/EditableList";
@@ -199,6 +207,9 @@ export default function KBADrafterPage() {
199207
const [ticketDialogOpen, setTicketDialogOpen] = useState(false);
200208
const [ticketData, setTicketData] = useState(null);
201209
const [loadingTicket, setLoadingTicket] = useState(false);
210+
211+
// Filter state
212+
const [statusFilter, setStatusFilter] = useState("all");
202213

203214
// Helper: Check for pending changes
204215
const hasPendingChanges = editedDraft && JSON.stringify(editedDraft) !== JSON.stringify(currentDraft);
@@ -1129,66 +1140,106 @@ export default function KBADrafterPage() {
11291140
{/* Recent Drafts List */}
11301141
{!currentDraft && drafts.length > 0 && (
11311142
<Card>
1132-
<CardHeader header={<strong>Letzte Entwürfe</strong>} />
1143+
<CardHeader
1144+
header={
1145+
<div style={{ display: "flex", alignItems: "center", justifyContent: "space-between", width: "100%" }}>
1146+
<strong>Letzte Entwürfe</strong>
1147+
<Dropdown
1148+
placeholder="Status filtern"
1149+
value={statusFilter === "all" ? "Alle Status" : statusFilter}
1150+
selectedOptions={[statusFilter]}
1151+
onOptionSelect={(e, data) => setStatusFilter(data.optionValue)}
1152+
size="small"
1153+
style={{ minWidth: "150px" }}
1154+
>
1155+
<Option value="all">Alle Status</Option>
1156+
<Option value="draft">draft</Option>
1157+
<Option value="reviewed">reviewed</Option>
1158+
<Option value="published">published</Option>
1159+
</Dropdown>
1160+
</div>
1161+
}
1162+
/>
11331163
<div style={{ padding: tokens.spacingVerticalM }}>
1134-
{drafts.map((draft) => (
1164+
{drafts
1165+
.filter(draft => statusFilter === "all" || draft.status === statusFilter)
1166+
.map((draft) => (
11351167
<Card
11361168
key={draft.id}
11371169
style={{
11381170
marginBottom: tokens.spacingVerticalS,
11391171
cursor: "pointer",
11401172
transition: "background 0.2s",
1141-
position: "relative"
11421173
}}
11431174
onClick={() => loadDraft(draft.id)}
11441175
>
1145-
<div style={{ padding: tokens.spacingVerticalM, paddingBottom: tokens.spacingVerticalL }}>
1146-
<Badge
1147-
appearance="filled"
1148-
color={getStatusBadgeColor(draft.status)}
1149-
style={{
1150-
position: "absolute",
1151-
top: "8px",
1152-
right: "8px"
1153-
}}
1154-
>
1155-
{draft.status}
1156-
</Badge>
1157-
<div>
1158-
<strong style={{ overflowWrap: "break-word", wordBreak: "break-word", paddingRight: "80px" }}>{draft.title}</strong>
1176+
<div style={{
1177+
padding: tokens.spacingVerticalM,
1178+
display: "flex",
1179+
alignItems: "flex-start",
1180+
gap: tokens.spacingHorizontalM,
1181+
}}>
1182+
{/* Left: Content */}
1183+
<div style={{ flex: 1, minWidth: 0 }}>
1184+
<div style={{
1185+
fontSize: "14px",
1186+
fontWeight: 600,
1187+
marginBottom: tokens.spacingVerticalXXS,
1188+
overflowWrap: "break-word",
1189+
wordBreak: "break-word"
1190+
}}>
1191+
{draft.title}
1192+
</div>
1193+
<div style={{
1194+
fontSize: "12px",
1195+
color: tokens.colorNeutralForeground3,
1196+
display: "flex",
1197+
gap: tokens.spacingHorizontalS,
1198+
flexWrap: "wrap",
1199+
alignItems: "center"
1200+
}}>
1201+
<span>{draft.incident_id}</span>
1202+
<span></span>
1203+
<span>{new Date(draft.created_at).toLocaleString("de-DE")}</span>
1204+
</div>
11591205
</div>
1160-
<div style={{ fontSize: "12px", color: tokens.colorNeutralForeground3, marginTop: tokens.spacingVerticalXS, overflowWrap: "break-word", wordBreak: "break-word" }}>
1161-
{draft.incident_id}{new Date(draft.created_at).toLocaleString("de-DE")}
1206+
1207+
{/* Right: Status Badge */}
1208+
<div style={{ display: "flex", justifyContent: "flex-end", minWidth: "80px" }}>
1209+
<Badge
1210+
appearance="filled"
1211+
color={getStatusBadgeColor(draft.status)}
1212+
size="large"
1213+
>
1214+
{draft.status}
1215+
</Badge>
11621216
</div>
1163-
<div
1164-
onClick={(e) => {
1165-
e.stopPropagation();
1166-
deleteDraft(draft.id, draft.title);
1167-
}}
1168-
title="Entwurf löschen"
1169-
style={{
1170-
position: "absolute",
1171-
bottom: 0,
1172-
right: 0,
1173-
width: "24px",
1174-
height: "24px",
1175-
backgroundColor: "#d13438",
1176-
display: "flex",
1177-
alignItems: "center",
1178-
justifyContent: "center",
1179-
cursor: "pointer",
1180-
transition: "background-color 0.2s",
1181-
borderTopLeftRadius: "4px"
1182-
}}
1183-
onMouseEnter={(e) => e.currentTarget.style.backgroundColor = "#a82c30"}
1184-
onMouseLeave={(e) => e.currentTarget.style.backgroundColor = "#d13438"}
1185-
>
1186-
<Dismiss20Regular
1187-
style={{
1188-
color: "white",
1189-
fontSize: "14px",
1190-
}}
1191-
/>
1217+
1218+
{/* Right: Menu */}
1219+
<div style={{ marginLeft: tokens.spacingHorizontalL }}>
1220+
<Menu>
1221+
<MenuTrigger disableButtonEnhancement>
1222+
<Button
1223+
appearance="subtle"
1224+
icon={<MoreVertical20Regular />}
1225+
size="small"
1226+
onClick={(e) => e.stopPropagation()}
1227+
/>
1228+
</MenuTrigger>
1229+
<MenuPopover>
1230+
<MenuList>
1231+
<MenuItem
1232+
icon={<Delete24Regular />}
1233+
onClick={(e) => {
1234+
e.stopPropagation();
1235+
deleteDraft(draft.id, draft.title);
1236+
}}
1237+
>
1238+
Löschen
1239+
</MenuItem>
1240+
</MenuList>
1241+
</MenuPopover>
1242+
</Menu>
11921243
</div>
11931244
</div>
11941245
</Card>

frontend/src/features/kba-drafter/components/EditableList.jsx

Lines changed: 41 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -132,14 +132,48 @@ export default function EditableList({
132132
</div>
133133
))}
134134

135-
<Button
136-
appearance="outline"
137-
icon={<Add24Regular />}
138-
onClick={handleAddItem}
139-
size="small"
135+
<div
136+
style={{
137+
display: "flex",
138+
gap: "8px",
139+
alignItems: "center",
140+
}}
140141
>
141-
{itemLabel} hinzufügen
142-
</Button>
142+
<Button
143+
appearance="outline"
144+
icon={<Add24Regular />}
145+
onClick={handleAddItem}
146+
size="small"
147+
style={{ flex: 1 }}
148+
>
149+
{itemLabel} hinzufügen
150+
</Button>
151+
152+
<div style={{ display: "flex", gap: "4px", visibility: "hidden", pointerEvents: "none" }}>
153+
{allowReorder && (
154+
<>
155+
<Button
156+
appearance="subtle"
157+
icon={<ArrowUp24Regular />}
158+
size="small"
159+
disabled
160+
/>
161+
<Button
162+
appearance="subtle"
163+
icon={<ArrowDown24Regular />}
164+
size="small"
165+
disabled
166+
/>
167+
</>
168+
)}
169+
<Button
170+
appearance="subtle"
171+
icon={<Delete24Regular />}
172+
size="small"
173+
disabled
174+
/>
175+
</div>
176+
</div>
143177
</div>
144178
);
145179
}

0 commit comments

Comments
 (0)