Skip to content

Commit 7673726

Browse files
committed
refactor(knowledge): extract withActionGuard helper to deduplicate context menu guard
1 parent dea71d1 commit 7673726

File tree

1 file changed

+23
-30
lines changed
  • apps/sim/app/workspace/[workspaceId]/knowledge/components/base-card

1 file changed

+23
-30
lines changed

apps/sim/app/workspace/[workspaceId]/knowledge/components/base-card/base-card.tsx

Lines changed: 23 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,20 @@ export function BaseCard({
100100
const [isDeleteModalOpen, setIsDeleteModalOpen] = useState(false)
101101
const [isTagsModalOpen, setIsTagsModalOpen] = useState(false)
102102
const [isDeleting, setIsDeleting] = useState(false)
103+
104+
/**
105+
* Guards against context menu actions triggering card navigation.
106+
* The card's onClick fires synchronously during the click event bubble phase,
107+
* so the ref is checked before the setTimeout-0 callback resets it.
108+
*/
103109
const actionTakenRef = useRef(false)
110+
const withActionGuard = useCallback((fn: () => void) => {
111+
actionTakenRef.current = true
112+
fn()
113+
setTimeout(() => {
114+
actionTakenRef.current = false
115+
}, 0)
116+
}, [])
104117

105118
const searchParams = new URLSearchParams({
106119
kbName: title,
@@ -131,45 +144,25 @@ export function BaseCard({
131144
)
132145

133146
const handleOpenInNewTab = useCallback(() => {
134-
actionTakenRef.current = true
135-
window.open(href, '_blank')
136-
setTimeout(() => {
137-
actionTakenRef.current = false
138-
}, 0)
139-
}, [href])
147+
withActionGuard(() => window.open(href, '_blank'))
148+
}, [href, withActionGuard])
140149

141150
const handleViewTags = useCallback(() => {
142-
actionTakenRef.current = true
143-
setIsTagsModalOpen(true)
144-
setTimeout(() => {
145-
actionTakenRef.current = false
146-
}, 0)
147-
}, [])
151+
withActionGuard(() => setIsTagsModalOpen(true))
152+
}, [withActionGuard])
148153

149154
const handleEdit = useCallback(() => {
150-
actionTakenRef.current = true
151-
setIsEditModalOpen(true)
152-
setTimeout(() => {
153-
actionTakenRef.current = false
154-
}, 0)
155-
}, [])
155+
withActionGuard(() => setIsEditModalOpen(true))
156+
}, [withActionGuard])
156157

157158
const handleDelete = useCallback(() => {
158-
actionTakenRef.current = true
159-
setIsDeleteModalOpen(true)
160-
setTimeout(() => {
161-
actionTakenRef.current = false
162-
}, 0)
163-
}, [])
159+
withActionGuard(() => setIsDeleteModalOpen(true))
160+
}, [withActionGuard])
164161

165162
const handleCopyId = useCallback(() => {
166163
if (!id) return
167-
actionTakenRef.current = true
168-
navigator.clipboard.writeText(id)
169-
setTimeout(() => {
170-
actionTakenRef.current = false
171-
}, 0)
172-
}, [id])
164+
withActionGuard(() => navigator.clipboard.writeText(id))
165+
}, [id, withActionGuard])
173166

174167
const handleConfirmDelete = useCallback(async () => {
175168
if (!id || !onDelete) return

0 commit comments

Comments
 (0)