Skip to content

Commit 5dce35d

Browse files
committed
feat(kb): emcn alignment; sidebar: popover primary; settings-modal: expand
1 parent 1642ed7 commit 5dce35d

File tree

17 files changed

+614
-712
lines changed

17 files changed

+614
-712
lines changed

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

Lines changed: 35 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,8 @@
11
'use client'
22

3-
import { useState } from 'react'
4-
import { Check, Copy, LibraryBig } from 'lucide-react'
53
import Link from 'next/link'
64
import { useParams } from 'next/navigation'
7-
import { createLogger } from '@/lib/logs/console/logger'
8-
9-
const logger = createLogger('BaseOverviewComponent')
5+
import { Badge, DocumentAttachment, Tooltip } from '@/components/emcn'
106

117
interface BaseOverviewProps {
128
id?: string
@@ -17,6 +13,9 @@ interface BaseOverviewProps {
1713
updatedAt?: string
1814
}
1915

16+
/**
17+
* Formats a date string to relative time (e.g., "2h ago", "3d ago")
18+
*/
2019
function formatRelativeTime(dateString: string): string {
2120
const date = new Date(dateString)
2221
const now = new Date()
@@ -49,6 +48,9 @@ function formatRelativeTime(dateString: string): string {
4948
return `${years}y ago`
5049
}
5150

51+
/**
52+
* Formats a date string to absolute format for tooltip display
53+
*/
5254
function formatAbsoluteDate(dateString: string): string {
5355
const date = new Date(dateString)
5456
return date.toLocaleDateString('en-US', {
@@ -60,15 +62,10 @@ function formatAbsoluteDate(dateString: string): string {
6062
})
6163
}
6264

63-
export function BaseOverview({
64-
id,
65-
title,
66-
docCount,
67-
description,
68-
createdAt,
69-
updatedAt,
70-
}: BaseOverviewProps) {
71-
const [isCopied, setIsCopied] = useState(false)
65+
/**
66+
* Knowledge base card component displaying overview information
67+
*/
68+
export function BaseOverview({ id, title, docCount, description, updatedAt }: BaseOverviewProps) {
7269
const params = useParams()
7370
const workspaceId = params?.workspaceId as string
7471

@@ -77,64 +74,39 @@ export function BaseOverview({
7774
})
7875
const href = `/workspace/${workspaceId}/knowledge/${id || title.toLowerCase().replace(/\s+/g, '-')}?${searchParams.toString()}`
7976

80-
const handleCopy = async (e: React.MouseEvent) => {
81-
e.preventDefault()
82-
e.stopPropagation()
83-
84-
if (id) {
85-
try {
86-
await navigator.clipboard.writeText(id)
87-
setIsCopied(true)
88-
setTimeout(() => setIsCopied(false), 2000)
89-
} catch (err) {
90-
logger.error('Failed to copy ID:', err)
91-
}
92-
}
93-
}
77+
const shortId = id ? `kb-${id.slice(0, 8)}` : ''
9478

9579
return (
96-
<Link href={href} prefetch={true}>
97-
<div className='group flex cursor-pointer flex-col gap-3 rounded-md border bg-background p-4 transition-colors hover:bg-accent/50'>
98-
<div className='flex items-center gap-2'>
99-
<LibraryBig className='h-4 w-4 flex-shrink-0 text-muted-foreground' />
100-
<h3 className='truncate font-medium text-sm leading-tight'>{title}</h3>
80+
<Link href={href} prefetch={true} className='h-full'>
81+
<div className='group flex h-full cursor-pointer flex-col gap-[12px] rounded-[4px] bg-[var(--surface-elevated)] px-[8px] py-[6px] transition-colors hover:bg-[var(--surface-5)]'>
82+
<div className='flex items-center justify-between gap-[8px]'>
83+
<h3 className='min-w-0 flex-1 truncate text-[14px] text-[var(--text-primary)]'>
84+
{title}
85+
</h3>
86+
{shortId && <Badge className='flex-shrink-0 rounded-[4px] text-[12px]'>{shortId}</Badge>}
10187
</div>
10288

103-
<div className='flex flex-col gap-2'>
104-
<div className='flex items-center gap-2 text-muted-foreground text-xs'>
105-
<span>
89+
<div className='flex flex-1 flex-col gap-[8px]'>
90+
<div className='flex items-center justify-between'>
91+
<span className='flex items-center gap-[6px] text-[12px] text-[var(--text-tertiary)]'>
92+
<DocumentAttachment className='h-[12px] w-[12px]' />
10693
{docCount} {docCount === 1 ? 'doc' : 'docs'}
10794
</span>
108-
<span></span>
109-
<div className='flex items-center gap-2'>
110-
<span className='truncate font-mono'>{id?.slice(0, 8)}</span>
111-
<button
112-
onClick={handleCopy}
113-
className='flex h-4 w-4 items-center justify-center rounded text-gray-500 hover:bg-gray-100 hover:text-gray-700'
114-
>
115-
{isCopied ? <Check className='h-3 w-3' /> : <Copy className='h-3 w-3' />}
116-
</button>
117-
</div>
95+
{updatedAt && (
96+
<Tooltip.Root>
97+
<Tooltip.Trigger asChild>
98+
<span className='cursor-default text-[12px] text-[var(--text-muted)]'>
99+
last updated: {formatRelativeTime(updatedAt)}
100+
</span>
101+
</Tooltip.Trigger>
102+
<Tooltip.Content>{formatAbsoluteDate(updatedAt)}</Tooltip.Content>
103+
</Tooltip.Root>
104+
)}
118105
</div>
119106

120-
{/* Timestamps */}
121-
{(createdAt || updatedAt) && (
122-
<div className='flex items-center gap-2 text-muted-foreground text-xs'>
123-
{updatedAt && (
124-
<span title={`Last updated: ${formatAbsoluteDate(updatedAt)}`}>
125-
Updated {formatRelativeTime(updatedAt)}
126-
</span>
127-
)}
128-
{updatedAt && createdAt && <span></span>}
129-
{createdAt && (
130-
<span title={`Created: ${formatAbsoluteDate(createdAt)}`}>
131-
Created {formatRelativeTime(createdAt)}
132-
</span>
133-
)}
134-
</div>
135-
)}
107+
<div className='h-0 w-full border-[var(--divider)] border-t' />
136108

137-
<p className='line-clamp-2 overflow-hidden text-muted-foreground text-xs'>
109+
<p className='line-clamp-2 h-[36px] text-[12px] text-[var(--text-tertiary)] leading-[18px]'>
138110
{description}
139111
</p>
140112
</div>

0 commit comments

Comments
 (0)