fix: add-filter button uses ref + state for positioning
Store button position in state on click, then pass to the portal popover via style. Eliminates getElementById race condition where the portal hadn't rendered yet when trying to set DOM styles. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
import { Suspense, useCallback, useEffect, useMemo, useState } from "react";
|
import { Suspense, useCallback, useEffect, useMemo, useRef, useState } from "react";
|
||||||
import { createPortal } from "react-dom";
|
import { createPortal } from "react-dom";
|
||||||
import { useRouter, useSearchParams } from "next/navigation";
|
import { useRouter, useSearchParams } from "next/navigation";
|
||||||
import {
|
import {
|
||||||
@@ -237,9 +237,11 @@ function TicketWorkbenchContent() {
|
|||||||
const [saveViewOpen, setSaveViewOpen] = useState(false);
|
const [saveViewOpen, setSaveViewOpen] = useState(false);
|
||||||
const [saveViewName, setSaveViewName] = useState("");
|
const [saveViewName, setSaveViewName] = useState("");
|
||||||
const [addFilterOpen, setAddFilterOpen] = useState(false);
|
const [addFilterOpen, setAddFilterOpen] = useState(false);
|
||||||
const [addFilterField, setAddFilterField] = useState<string | null>(null); // which field type is selected
|
const [addFilterField, setAddFilterField] = useState<string | null>(null);
|
||||||
const [addFilterOperator, setAddFilterOperator] = useState("is");
|
const [addFilterOperator, setAddFilterOperator] = useState("is");
|
||||||
const [addFilterValue, setAddFilterValue] = useState("");
|
const [addFilterValue, setAddFilterValue] = useState("");
|
||||||
|
const [filterPopoverPos, setFilterPopoverPos] = useState({ left: 0, top: 0 });
|
||||||
|
const addFilterBtnRef = useRef<HTMLButtonElement>(null);
|
||||||
|
|
||||||
const [dialogOpen, setDialogOpen] = useState(false);
|
const [dialogOpen, setDialogOpen] = useState(false);
|
||||||
const [newSubject, setNewSubject] = useState("");
|
const [newSubject, setNewSubject] = useState("");
|
||||||
@@ -840,13 +842,12 @@ function TicketWorkbenchContent() {
|
|||||||
))}
|
))}
|
||||||
<div>
|
<div>
|
||||||
<button
|
<button
|
||||||
|
ref={addFilterBtnRef}
|
||||||
type="button"
|
type="button"
|
||||||
onClick={(event) => {
|
onClick={() => {
|
||||||
const rect = event.currentTarget.getBoundingClientRect();
|
if (addFilterBtnRef.current) {
|
||||||
const popover = document.getElementById("add-filter-popover");
|
const rect = addFilterBtnRef.current.getBoundingClientRect();
|
||||||
if (popover) {
|
setFilterPopoverPos({ left: rect.left, top: rect.bottom + 4 });
|
||||||
popover.style.left = `${rect.left}px`;
|
|
||||||
popover.style.top = `${rect.bottom + 4}px`;
|
|
||||||
}
|
}
|
||||||
setAddFilterOpen((prev) => !prev);
|
setAddFilterOpen((prev) => !prev);
|
||||||
}}
|
}}
|
||||||
@@ -1408,8 +1409,8 @@ function TicketWorkbenchContent() {
|
|||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<div
|
<div
|
||||||
id="add-filter-popover"
|
|
||||||
className="fixed z-[9999] w-52 rounded-md border border-border bg-popover p-1 shadow-lg"
|
className="fixed z-[9999] w-52 rounded-md border border-border bg-popover p-1 shadow-lg"
|
||||||
|
style={{ left: filterPopoverPos.left, top: filterPopoverPos.top }}
|
||||||
>
|
>
|
||||||
{!addFilterField ? (
|
{!addFilterField ? (
|
||||||
<>
|
<>
|
||||||
|
|||||||
Reference in New Issue
Block a user