Skip to content

Commit e58eab2

Browse files
Bill LeoutsakosBill Leoutsakos
authored andcommitted
improvement(ui): share knowledge tag rows
1 parent 5653710 commit e58eab2

3 files changed

Lines changed: 82 additions & 56 deletions

File tree

‎apps/sim/app/workspace/[workspaceId]/knowledge/[id]/[documentId]/components/document-tags-modal/document-tags-modal.tsx‎

Lines changed: 12 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ import {
1515
handleKeyboardActivation,
1616
Label,
1717
} from '@sim/emcn'
18-
import { Trash } from '@sim/emcn/icons'
1918
import { createLogger } from '@sim/logger'
2019
import { formatDate } from '@sim/utils/formatting'
2120
import {
@@ -27,6 +26,7 @@ import {
2726
} from '@/lib/knowledge/constants'
2827
import type { DocumentTag } from '@/lib/knowledge/tags/types'
2928
import type { DocumentData } from '@/lib/knowledge/types'
29+
import { KnowledgeTagRow } from '@/app/workspace/[workspaceId]/knowledge/components/knowledge-tag-row'
3030
import {
3131
type TagDefinition,
3232
useKnowledgeBaseTagDefinitions,
@@ -385,40 +385,24 @@ export function DocumentTagsModal({
385385
<div className='space-y-2'>
386386
{documentTags.map((tag, index) => (
387387
<div key={tag.displayName} className='space-y-2'>
388-
<div
388+
<KnowledgeTagRow
389389
role='button'
390390
tabIndex={0}
391-
className='flex cursor-pointer items-center gap-2 rounded-sm border p-2 hover-hover:bg-[var(--surface-2)]'
392391
onClick={() => startEditingTag(index)}
393392
onKeyDown={(event) => {
394393
if (event.target !== event.currentTarget) return
395394
handleKeyboardActivation(event, () => startEditingTag(index))
396395
}}
397-
>
398-
<span className='min-w-0 truncate text-[var(--text-primary)] text-caption'>
399-
{tag.displayName}
400-
</span>
401-
<span className='rounded-[3px] bg-[var(--surface-3)] px-1.5 py-0.5 text-[var(--text-muted)] text-micro'>
402-
{FIELD_TYPE_LABELS[tag.fieldType] || tag.fieldType}
403-
</span>
404-
<div className='mb-[-1.5px] h-[14px] w-[1.25px] shrink-0 rounded-full bg-[var(--border-1)]' />
405-
<span className='min-w-0 flex-1 truncate text-[var(--text-muted)] text-caption'>
406-
{formatValueForDisplay(tag.value, tag.fieldType)}
407-
</span>
408-
<div className='flex shrink-0 items-center gap-1'>
409-
<Button
410-
aria-label='Remove tag'
411-
variant='ghost-destructive-muted'
412-
onClick={(e) => {
413-
e.stopPropagation()
414-
handleRemoveTag(index)
415-
}}
416-
className='size-4 p-0'
417-
>
418-
<Trash className='size-3' />
419-
</Button>
420-
</div>
421-
</div>
396+
name={tag.displayName}
397+
typeLabel={FIELD_TYPE_LABELS[tag.fieldType] || tag.fieldType}
398+
detail={formatValueForDisplay(tag.value, tag.fieldType)}
399+
truncateDetail
400+
removeLabel='Remove tag'
401+
onRemove={(e) => {
402+
e.stopPropagation()
403+
handleRemoveTag(index)
404+
}}
405+
/>
422406

423407
{editingTagIndex === index && (
424408
<div className='space-y-2 rounded-md border p-3'>

‎apps/sim/app/workspace/[workspaceId]/knowledge/[id]/components/base-tags-modal/base-tags-modal.tsx‎

Lines changed: 15 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ import {
1414
type ComboboxOption,
1515
handleKeyboardActivation,
1616
} from '@sim/emcn'
17-
import { Trash } from '@sim/emcn/icons'
1817
import { createLogger } from '@sim/logger'
1918
import { getDocumentIcon } from '@/components/icons/document-icons'
2019
import type { TagUsageData } from '@/lib/api/contracts/knowledge'
@@ -24,6 +23,7 @@ import {
2423
SUPPORTED_FIELD_TYPES,
2524
TAG_SLOT_CONFIG,
2625
} from '@/lib/knowledge/constants'
26+
import { KnowledgeTagRow } from '@/app/workspace/[workspaceId]/knowledge/components/knowledge-tag-row'
2727
import {
2828
type TagDefinition,
2929
useKnowledgeBaseTagDefinitions,
@@ -270,41 +270,28 @@ export function BaseTagsModal({ open, onOpenChange, knowledgeBaseId }: BaseTagsM
270270
{kbTagDefinitions.map((tag) => {
271271
const usage = getTagUsage(tag.tagSlot)
272272
return (
273-
<div
273+
<KnowledgeTagRow
274274
key={tag.id}
275275
role='button'
276276
tabIndex={0}
277-
className='flex cursor-pointer items-center gap-2 rounded-sm border p-2 hover-hover:bg-[var(--surface-2)]'
278277
onClick={() => handleViewDocuments(tag)}
279278
onKeyDown={(event) => {
280279
if (event.target !== event.currentTarget) return
281280
handleKeyboardActivation(event, () => handleViewDocuments(tag))
282281
}}
283-
>
284-
<span className='min-w-0 truncate text-[var(--text-primary)] text-caption'>
285-
{tag.displayName}
286-
</span>
287-
<span className='rounded-[3px] bg-[var(--surface-3)] px-1.5 py-0.5 text-[var(--text-muted)] text-micro'>
288-
{FIELD_TYPE_LABELS[tag.fieldType] || tag.fieldType}
289-
</span>
290-
<div className='mb-[-1.5px] h-[14px] w-[1.25px] shrink-0 rounded-full bg-[var(--border-1)]' />
291-
<span className='min-w-0 flex-1 text-[var(--text-muted)] text-caption'>
292-
{usage.documentCount} document{usage.documentCount !== 1 ? 's' : ''}
293-
</span>
294-
<div className='flex shrink-0 items-center gap-1'>
295-
<Button
296-
aria-label='Delete Tag'
297-
variant='ghost-destructive-muted'
298-
onClick={(e) => {
299-
e.stopPropagation()
300-
handleDeleteTagClick(tag)
301-
}}
302-
className='size-4 p-0'
303-
>
304-
<Trash className='size-3' />
305-
</Button>
306-
</div>
307-
</div>
282+
name={tag.displayName}
283+
typeLabel={FIELD_TYPE_LABELS[tag.fieldType] || tag.fieldType}
284+
detail={
285+
<>
286+
{usage.documentCount} document{usage.documentCount !== 1 ? 's' : ''}
287+
</>
288+
}
289+
removeLabel='Delete Tag'
290+
onRemove={(e) => {
291+
e.stopPropagation()
292+
handleDeleteTagClick(tag)
293+
}}
294+
/>
308295
)
309296
})}
310297

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
import type { HTMLAttributes, MouseEventHandler, ReactNode } from 'react'
2+
import { Button, cn } from '@sim/emcn'
3+
import { Trash } from '@sim/emcn/icons'
4+
5+
interface KnowledgeTagRowProps
6+
extends Omit<HTMLAttributes<HTMLDivElement>, 'children' | 'className'> {
7+
name: string
8+
typeLabel: string
9+
detail: ReactNode
10+
truncateDetail?: boolean
11+
removeLabel: string
12+
onRemove: MouseEventHandler<HTMLButtonElement>
13+
}
14+
15+
/** Shared tag summary; callers retain activation, keyboard and removal behavior. */
16+
export function KnowledgeTagRow({
17+
name,
18+
typeLabel,
19+
detail,
20+
truncateDetail = false,
21+
removeLabel,
22+
onRemove,
23+
...props
24+
}: KnowledgeTagRowProps) {
25+
return (
26+
<div
27+
{...props}
28+
className='flex cursor-pointer items-center gap-2 rounded-sm border p-2 hover-hover:bg-[var(--surface-2)]'
29+
>
30+
<span className='min-w-0 truncate text-[var(--text-primary)] text-caption'>{name}</span>
31+
<span className='rounded-[3px] bg-[var(--surface-3)] px-1.5 py-0.5 text-[var(--text-muted)] text-micro'>
32+
{typeLabel}
33+
</span>
34+
<div className='mb-[-1.5px] h-[14px] w-[1.25px] shrink-0 rounded-full bg-[var(--border-1)]' />
35+
<span
36+
className={cn(
37+
'min-w-0 flex-1 text-[var(--text-muted)] text-caption',
38+
truncateDetail && 'truncate'
39+
)}
40+
>
41+
{detail}
42+
</span>
43+
<div className='flex shrink-0 items-center gap-1'>
44+
<Button
45+
aria-label={removeLabel}
46+
variant='ghost-destructive-muted'
47+
onClick={onRemove}
48+
className='size-4 p-0'
49+
>
50+
<Trash className='size-3' />
51+
</Button>
52+
</div>
53+
</div>
54+
)
55+
}

0 commit comments

Comments
 (0)