Skip to content
Merged
Changes from 1 commit
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
e622b6e
improvement(tables): improve table filtering UX
waleedlatif1 Mar 29, 2026
bcc7974
fix(table-filter): use ref to stabilize handleRemove/handleApply call…
waleedlatif1 Mar 29, 2026
5d037ac
improvement(tables,kb): remove hacky patterns, fix KB filter popover …
waleedlatif1 Mar 29, 2026
2e67864
feat(knowledge): add sort and filter to KB list page
waleedlatif1 Mar 29, 2026
866e91d
feat(files): add sort and filter to files list page
waleedlatif1 Mar 29, 2026
6c18471
feat(scheduled-tasks): add sort and filter to scheduled tasks page
waleedlatif1 Mar 29, 2026
f46f83c
fix(table-filter): use explicit close handler instead of toggle
waleedlatif1 Mar 29, 2026
8a1f3dc
improvement(files,knowledge): replace manual debounce with useDebounc…
waleedlatif1 Mar 29, 2026
4899dc3
fix(resource): prevent popover from inheriting anchor min-width
waleedlatif1 Mar 29, 2026
f6edb88
feat(tables): add sort to tables list page
waleedlatif1 Mar 29, 2026
51c9df9
feat(knowledge): add content and owner filters to KB list
waleedlatif1 Mar 29, 2026
12ea734
feat(scheduled-tasks): add status and health filters
waleedlatif1 Mar 29, 2026
a3ffc2f
feat(files): add size and uploaded-by filters to files list
waleedlatif1 Mar 29, 2026
0142c69
feat(tables): add row count, owner, and column type filters
waleedlatif1 Mar 29, 2026
2553cac
improvement(scheduled-tasks): use combobox filter panel matching logs…
waleedlatif1 Mar 29, 2026
9dd3028
improvement(knowledge): use combobox filter panel matching logs UI style
waleedlatif1 Mar 29, 2026
446a665
improvement(files): use combobox filter panel matching logs UI style
waleedlatif1 Mar 29, 2026
c56e3ac
improvement(tables): use combobox filter panel matching logs UI style
waleedlatif1 Mar 29, 2026
f0e988d
feat(settings): add sort to recently deleted page
waleedlatif1 Mar 29, 2026
bf0bcf3
feat(logs): add sort to logs page
waleedlatif1 Mar 29, 2026
ffe6806
improvement(knowledge): upgrade document list filter to combobox style
waleedlatif1 Mar 29, 2026
483c35c
fix(resources): fix missing imports, memoization, and stale refs acro…
waleedlatif1 Mar 29, 2026
c8672f7
improvement(tables): remove column type filter
waleedlatif1 Mar 29, 2026
71794bb
fix(resources): fix filter/sort correctness issues from audit
waleedlatif1 Mar 29, 2026
aeeec6b
fix(chunks): add server-side sort to document chunks API
waleedlatif1 Mar 29, 2026
7b13a1a
perf(resources): memoize filterContent JSX across all resource pages
waleedlatif1 Mar 29, 2026
90bd958
fix(resources): add missing sort options for all visible columns
waleedlatif1 Mar 29, 2026
0318725
whitelabeling updates, sidebar fixes, files bug
waleedlatif1 Mar 29, 2026
432e4d0
increased type safety
waleedlatif1 Mar 29, 2026
f8a26a3
pr fixes
waleedlatif1 Mar 29, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
feat(tables): add sort to tables list page
  • Loading branch information
waleedlatif1 committed Mar 29, 2026
commit f6edb88d814c292792388a247a3a95eecb4ef706
91 changes: 71 additions & 20 deletions apps/sim/app/workspace/[workspaceId]/tables/tables.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,12 @@ import {
import { Columns3, Rows3, Table as TableIcon } from '@/components/emcn/icons'
import type { TableDefinition } from '@/lib/table'
import { generateUniqueTableName } from '@/lib/table/constants'
import type { ResourceColumn, ResourceRow } from '@/app/workspace/[workspaceId]/components'
import type {
ResourceColumn,
ResourceRow,
SearchConfig,
SortConfig,
} from '@/app/workspace/[workspaceId]/components'
import { ownerCell, Resource, timeCell } from '@/app/workspace/[workspaceId]/components'
import { useUserPermissionsContext } from '@/app/workspace/[workspaceId]/providers/workspace-permissions-provider'
import { TablesListContextMenu } from '@/app/workspace/[workspaceId]/tables/components'
Expand All @@ -29,6 +34,7 @@ import {
useUploadCsvToTable,
} from '@/hooks/queries/tables'
import { useWorkspaceMembersQuery } from '@/hooks/queries/workspace'
import { useDebounce } from '@/hooks/use-debounce'

const logger = createLogger('Tables')

Expand Down Expand Up @@ -60,6 +66,11 @@ export function Tables() {
const [isDeleteDialogOpen, setIsDeleteDialogOpen] = useState(false)
const [activeTable, setActiveTable] = useState<TableDefinition | null>(null)
const [searchTerm, setSearchTerm] = useState('')
const debouncedSearchTerm = useDebounce(searchTerm, 300)
const [activeSort, setActiveSort] = useState<{
column: string
direction: 'asc' | 'desc'
} | null>(null)
const [uploading, setUploading] = useState(false)
const [uploadProgress, setUploadProgress] = useState({ completed: 0, total: 0 })
const csvInputRef = useRef<HTMLInputElement>(null)
Expand All @@ -78,15 +89,39 @@ export function Tables() {
closeMenu: closeRowContextMenu,
} = useContextMenu()

const filteredTables = useMemo(() => {
if (!searchTerm) return tables
const term = searchTerm.toLowerCase()
return tables.filter((table) => table.name.toLowerCase().includes(term))
}, [tables, searchTerm])
const processedTables = useMemo(() => {
const result = debouncedSearchTerm
? tables.filter((t) => t.name.toLowerCase().includes(debouncedSearchTerm.toLowerCase()))
: tables

const col = activeSort?.column ?? 'created'
const dir = activeSort?.direction ?? 'desc'
return [...result].sort((a, b) => {
let cmp = 0
switch (col) {
case 'name':
cmp = a.name.localeCompare(b.name)
break
case 'columns':
cmp = a.schema.columns.length - b.schema.columns.length
break
case 'rows':
cmp = a.rowCount - b.rowCount
break
case 'created':
cmp = new Date(a.createdAt).getTime() - new Date(b.createdAt).getTime()
break
case 'updated':
cmp = new Date(a.updatedAt).getTime() - new Date(b.updatedAt).getTime()
break
}
return dir === 'asc' ? cmp : -cmp
})
}, [tables, debouncedSearchTerm, activeSort])

const rows: ResourceRow[] = useMemo(
() =>
filteredTables.map((table) => ({
processedTables.map((table) => ({
id: table.id,
cells: {
name: {
Expand All @@ -105,14 +140,34 @@ export function Tables() {
owner: ownerCell(table.createdBy, members),
updated: timeCell(table.updatedAt),
},
sortValues: {
columns: table.schema.columns.length,
rows: table.rowCount,
created: -new Date(table.createdAt).getTime(),
updated: -new Date(table.updatedAt).getTime(),
},
})),
[filteredTables, members]
[processedTables, members]
)

const searchConfig: SearchConfig = useMemo(
() => ({
value: searchTerm,
onChange: setSearchTerm,
onClearAll: () => setSearchTerm(''),
placeholder: 'Search tables...',
}),
[searchTerm]
)

const sortConfig: SortConfig = useMemo(
() => ({
options: [
{ id: 'name', label: 'Name' },
{ id: 'columns', label: 'Columns' },
{ id: 'rows', label: 'Rows' },
{ id: 'created', label: 'Created' },
{ id: 'updated', label: 'Last Updated' },
],
active: activeSort,
onSort: (column, direction) => setActiveSort({ column, direction }),
onClear: () => setActiveSort(null),
}),
[activeSort]
)

const handleContentContextMenu = useCallback(
Expand Down Expand Up @@ -260,12 +315,8 @@ export function Tables() {
onClick: handleCreateTable,
disabled: uploading || userPermissions.canEdit !== true || createTable.isPending,
}}
search={{
value: searchTerm,
onChange: setSearchTerm,
placeholder: 'Search tables...',
}}
defaultSort='created'
search={searchConfig}
sort={sortConfig}
headerActions={[
{
label: uploadButtonLabel,
Expand Down
Loading