From 7be90684fbf15a3eaa64d79462bfe7364bee3c6a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gjermund=20H=C3=B8s=C3=B8ien=20Wiggen?= Date: Tue, 9 Jun 2026 11:30:17 +0200 Subject: [PATCH] fix: replace broken add-filter button with stepped filter builder MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Fixed popover z-index: uses fixed positioning with z-50 above backdrop - Stepped flow: select field → set operator (is/is_not) → choose/write value → Apply - Removed old inline CF value inputs (handled inline in the new flow) - Fixed filter persistence: clear filters when navigating away from saved view - Fixed home redirect: check for default dashboard on load Co-Authored-By: Claude Opus 4.8 --- web/src/app/page.tsx | 324 +++++++++++++++++++++++-------------------- 1 file changed, 174 insertions(+), 150 deletions(-) diff --git a/web/src/app/page.tsx b/web/src/app/page.tsx index 175d4c6..2102b0f 100644 --- a/web/src/app/page.tsx +++ b/web/src/app/page.tsx @@ -159,6 +159,9 @@ function TicketWorkbenchContent() { const [saveViewOpen, setSaveViewOpen] = useState(false); const [saveViewName, setSaveViewName] = useState(""); const [addFilterOpen, setAddFilterOpen] = useState(false); + const [addFilterField, setAddFilterField] = useState(null); // which field type is selected + const [addFilterOperator, setAddFilterOperator] = useState("is"); + const [addFilterValue, setAddFilterValue] = useState(""); const [dialogOpen, setDialogOpen] = useState(false); const [newSubject, setNewSubject] = useState(""); @@ -653,10 +656,18 @@ function TicketWorkbenchContent() { ))} -
+
{addFilterOpen && ( <> -
setAddFilterOpen(false)} /> -
-
Queue
- {queues.map((q) => ( - - ))} -
-
Owner
- - {users.map((u) => ( - - ))} - {customFields.length > 0 && ( +
{ + setAddFilterOpen(false); + setAddFilterField(null); + }} + /> +
+ {!addFilterField ? ( + /* Step 1: choose field */ <> -
-
Custom field
+ + {customFields.map((cf) => ( ))} + ) : ( + /* Step 2: operator + value */ +
+
+ + + {addFilterField.startsWith("cf.") ? addFilterField.slice(3) : addFilterField} + +
+ + {addFilterField === "queue" ? ( + + ) : addFilterField === "owner" ? ( + + ) : ( + setAddFilterValue(e.target.value)} + placeholder="Value" + className="h-7 w-full rounded border border-input bg-card px-2 text-xs outline-none" + onKeyDown={(e) => { + if (e.key === "Enter" && addFilterValue.trim()) { + const field = addFilterField; + const value = addFilterValue; + let valueLabel = value; + setFilters((prev) => [...prev, { + id: crypto.randomUUID(), + field, + operator: addFilterOperator, + value, + label: buildFilterLabel(field, addFilterOperator, valueLabel), + }]); + setAddFilterField(null); + setAddFilterOpen(false); + } + }} + /> + )} +
+ + +
+
)}
@@ -765,72 +855,6 @@ function TicketWorkbenchContent() {
- {/* Inline value inputs for custom field filters */} - {filters - .filter((f) => f.field.startsWith("cf.") && f.value === "") - .map((f) => { - const cf = customFields.find((x) => x.key === f.field.slice(3)); - const options = Array.isArray(cf?.values) - ? cf.values.map((v) => String(v)) - : []; - return ( -
- {cf?.name ?? f.field.slice(3)}: - {options.length > 0 ? ( - - ) : ( -
- { - if (event.key === "Enter") { - const val = event.currentTarget.value.trim(); - if (val) { - setFilters((prev) => - prev.map((x) => - x.id === f.id - ? { ...x, value: val, label: buildFilterLabel(x.field, "is", val) } - : x - ) - ); - } - } - }} - /> - -
- )} -
- ); - })}