Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export { ResourceFilterPanel, ResourceFilterSection } from './resource-filter-panel'
export type {
ColumnOption,
FilterConfig,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
'use client'

import type { ReactNode } from 'react'
import { FILTER_SECTION_LABEL_CLASS } from '@/app/workspace/[workspaceId]/components/resource/components/resource-options/resource-options'

interface ResourceFilterPanelProps {
children: ReactNode
}

/** The filter content frame shared by resource lists and document chunks. */
export function ResourceFilterPanel({ children }: ResourceFilterPanelProps) {
return <div className='flex w-[240px] flex-col gap-3 p-3'>{children}</div>
}

interface ResourceFilterSectionProps {
label: string
children: ReactNode
/** A distinct label treatment, such as the document chunk status label. */
labelClassName?: string
}

export function ResourceFilterSection({
label,
children,
labelClassName = FILTER_SECTION_LABEL_CLASS,
}: ResourceFilterSectionProps) {
return (
<div className='flex flex-col gap-1.5'>
<span className={labelClassName}>{label}</span>
{children}
</div>
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,14 @@
import { act } from 'react'
import { createRoot, type Root } from 'react-dom/client'
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
import { SortDropdown } from '@/app/workspace/[workspaceId]/components/resource/components/resource-options/resource-options'
import {
ResourceFilterPanel,
ResourceFilterSection,
} from '@/app/workspace/[workspaceId]/components/resource/components/resource-options/resource-filter-panel'
import {
ResourceOptions,
SortDropdown,
} from '@/app/workspace/[workspaceId]/components/resource/components/resource-options/resource-options'

const LONG_COLUMN_LABEL = 'highest_current_champion_role_across_the_entire_company'

Expand Down Expand Up @@ -125,3 +132,47 @@ describe('SortDropdown', () => {
expect(onOpenChange).toHaveBeenCalledWith(false)
})
})

describe('ResourceOptions filter content', () => {
it('keeps section controls focusable and clear actions working in the filter popover', () => {
const onClear = vi.fn()
act(() => {
root.render(
<ResourceOptions
filter={{
content: (
<ResourceFilterPanel>
<ResourceFilterSection label='Status'>
<button type='button'>Choose status</button>
</ResourceFilterSection>
<button type='button' onClick={onClear}>
Clear all filters
</button>
</ResourceFilterPanel>
),
}}
/>
)
})

const trigger = [...document.querySelectorAll<HTMLButtonElement>('button')].find(
(button) => button.textContent === 'Filter'
)
expect(trigger).toBeDefined()
act(() => trigger?.click())

const choice = [...document.querySelectorAll<HTMLButtonElement>('button')].find(
(button) => button.textContent === 'Choose status'
)
expect(choice).toBeDefined()
expect(document.body).toHaveTextContent('Status')
act(() => choice?.focus())
expect(document.activeElement).toBe(choice)

const clear = [...document.querySelectorAll<HTMLButtonElement>('button')].find(
(button) => button.textContent === 'Clear all filters'
)
act(() => clear?.click())
expect(onClear).toHaveBeenCalledOnce()
})
})
24 changes: 12 additions & 12 deletions apps/sim/app/workspace/[workspaceId]/files/files.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,10 @@ import type {
SearchConfig,
SortConfig,
} from '@/app/workspace/[workspaceId]/components/resource/components/resource-options'
import { FILTER_SECTION_LABEL_CLASS } from '@/app/workspace/[workspaceId]/components/resource/components/resource-options'
import {
ResourceFilterPanel,
ResourceFilterSection,
} from '@/app/workspace/[workspaceId]/components/resource/components/resource-options'
import { timeCell } from '@/app/workspace/[workspaceId]/components/resource/components/time-cell'
import { resourceListState } from '@/app/workspace/[workspaceId]/components/resource/is-resource-list-empty'
import type {
Expand Down Expand Up @@ -2004,9 +2007,8 @@ function FilesContent() {
: `${uploadedByFilter.length} members`

return (
<div className='flex w-[240px] flex-col gap-3 p-3'>
<div className='flex flex-col gap-1.5'>
<span className={FILTER_SECTION_LABEL_CLASS}>File Type</span>
<ResourceFilterPanel>
<ResourceFilterSection label='File Type'>
<ChipCombobox
options={[
{ value: 'document', label: 'Documents' },
Expand All @@ -2023,9 +2025,8 @@ function FilesContent() {
allOptionLabel='All'
className='w-full'
/>
</div>
<div className='flex flex-col gap-1.5'>
<span className={FILTER_SECTION_LABEL_CLASS}>Size</span>
</ResourceFilterSection>
<ResourceFilterSection label='Size'>
<ChipCombobox
options={[
{ value: 'small', label: 'Small (< 1 MB)' },
Expand All @@ -2041,10 +2042,9 @@ function FilesContent() {
allOptionLabel='All'
className='w-full'
/>
</div>
</ResourceFilterSection>
{memberOptions.length > 0 && (
<div className='flex flex-col gap-1.5'>
<span className={FILTER_SECTION_LABEL_CLASS}>Uploaded By</span>
<ResourceFilterSection label='Uploaded By'>
<ChipCombobox
options={memberOptions}
multiSelect
Expand All @@ -2058,7 +2058,7 @@ function FilesContent() {
allOptionLabel='All'
className='w-full'
/>
</div>
</ResourceFilterSection>
)}
{hasActiveFilters && (
<Button
Expand All @@ -2069,7 +2069,7 @@ function FilesContent() {
Clear all filters
</Button>
)}
</div>
</ResourceFilterPanel>
)
}, [
typeFilter,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,10 @@ import type {
SearchConfig,
SortConfig,
} from '@/app/workspace/[workspaceId]/components/resource/components/resource-options'
import {
ResourceFilterPanel,
ResourceFilterSection,
} from '@/app/workspace/[workspaceId]/components/resource/components/resource-options'
import type {
PaginationConfig,
ResourceColumn,
Expand Down Expand Up @@ -737,9 +741,11 @@ export function Document({

const filterContent = useMemo(
() => (
<div className='flex w-[240px] flex-col gap-3 p-3'>
<div className='flex flex-col gap-1.5'>
<span className='text-[var(--text-secondary)] text-caption'>Status</span>
<ResourceFilterPanel>
<ResourceFilterSection
label='Status'
labelClassName='text-[var(--text-secondary)] text-caption'
>
<ChipCombobox
options={[
{ value: 'enabled', label: 'Enabled' },
Expand All @@ -757,7 +763,7 @@ export function Document({
allOptionLabel='All'
className='w-full'
/>
</div>
</ResourceFilterSection>
{enabledFilter.length > 0 && (
<button
type='button'
Expand All @@ -770,7 +776,7 @@ export function Document({
Clear all filters
</button>
)}
</div>
</ResourceFilterPanel>
),
[enabledFilter, setEnabledFilter]
)
Expand Down
19 changes: 10 additions & 9 deletions apps/sim/app/workspace/[workspaceId]/tables/tables.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,10 @@ import type {
SearchConfig,
SortConfig,
} from '@/app/workspace/[workspaceId]/components/resource/components/resource-options'
import { FILTER_SECTION_LABEL_CLASS } from '@/app/workspace/[workspaceId]/components/resource/components/resource-options'
import {
ResourceFilterPanel,
ResourceFilterSection,
} from '@/app/workspace/[workspaceId]/components/resource/components/resource-options'
import { timeCell } from '@/app/workspace/[workspaceId]/components/resource/components/time-cell'
import { resourceListState } from '@/app/workspace/[workspaceId]/components/resource/is-resource-list-empty'
import type {
Expand Down Expand Up @@ -727,9 +730,8 @@ function TablesContent() {

const filterContent = useMemo(
() => (
<div className='flex w-[240px] flex-col gap-3 p-3'>
<div className='flex flex-col gap-1.5'>
<span className={FILTER_SECTION_LABEL_CLASS}>Row Count</span>
<ResourceFilterPanel>
<ResourceFilterSection label='Row Count'>
<ChipCombobox
options={[
{ value: 'empty', label: 'Empty' },
Expand All @@ -745,10 +747,9 @@ function TablesContent() {
allOptionLabel='All'
className='w-full'
/>
</div>
</ResourceFilterSection>
{memberOptions.length > 0 && (
<div className='flex flex-col gap-1.5'>
<span className={FILTER_SECTION_LABEL_CLASS}>Owner</span>
<ResourceFilterSection label='Owner'>
<ChipCombobox
options={memberOptions}
multiSelect
Expand All @@ -762,7 +763,7 @@ function TablesContent() {
allOptionLabel='All'
className='w-full'
/>
</div>
</ResourceFilterSection>
)}
{hasActiveFilters && (
<button
Expand All @@ -773,7 +774,7 @@ function TablesContent() {
Clear all filters
</button>
)}
</div>
</ResourceFilterPanel>
),
[
rowCountFilter,
Expand Down
Loading