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
Expand Up @@ -8,9 +8,9 @@ import { ALL_COLUMN_TYPES } from '@/lib/table/column-types'
* "+ New column" dropdown to spawn a workflow group; the resulting columns are
* stored as scalar types under the hood (none carry `'workflow'`).
*/
export type SidebarColumnType = ColumnDefinition['type'] | 'workflow'
type SidebarColumnType = ColumnDefinition['type'] | 'workflow'

export interface ColumnTypeOption {
interface ColumnTypeOption {
type: SidebarColumnType
label: string
icon: React.ComponentType<{ className?: string }>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,3 @@
export type { ColumnConfig } from './column-config-sidebar'
export { ColumnConfigSidebar } from './column-config-sidebar'
export {
COLUMN_TYPE_OPTIONS,
type ColumnTypeOption,
PLAIN_COLUMN_TYPE_OPTIONS,
type SidebarColumnType,
} from './column-types'
export { COLUMN_TYPE_OPTIONS, PLAIN_COLUMN_TYPE_OPTIONS } from './column-types'
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/**
* @vitest-environment jsdom
*/
import { act } from 'react'
import { createRoot, type Root } from 'react-dom/client'
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
import { COLUMN_TYPE_OPTIONS } from '@/app/workspace/[workspaceId]/tables/[tableId]/components/column-config-sidebar'
import { ColumnDropdown } from '@/app/workspace/[workspaceId]/tables/[tableId]/components/column-dropdown/column-dropdown'

let container: HTMLDivElement
let root: Root

beforeEach(() => {
globalThis.IS_REACT_ACT_ENVIRONMENT = true
container = document.createElement('div')
document.body.appendChild(container)
root = createRoot(container)
})

afterEach(() => {
act(() => root.unmount())
container.remove()
})

describe('ColumnDropdown', () => {
it('lists Enrichments as a regular entry after the column options', () => {
const onPickEnrichment = vi.fn()

act(() => {
root.render(
<ColumnDropdown
trigger='header'
disabled={false}
onPickType={vi.fn()}
onPickWorkflow={vi.fn()}
onPickEnrichment={onPickEnrichment}
blocked={false}
onBlocked={vi.fn()}
/>
)
})
act(() => {
container
.querySelector<HTMLButtonElement>('button')
?.dispatchEvent(new MouseEvent('pointerdown', { bubbles: true, button: 0 }))
})

const items = [...document.body.querySelectorAll<HTMLElement>('[role="menuitem"]')]
expect(items.map((item) => item.textContent)).toEqual([
...COLUMN_TYPE_OPTIONS.map((option) => option.label),
'Enrichments',
])
expect(document.body.querySelector('[role="separator"]')).toBeNull()

act(() => items.at(-1)?.click())
expect(onPickEnrichment).toHaveBeenCalledOnce()
})
})
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuSeparator,
DropdownMenuTrigger,
Plus,
} from '@sim/emcn'
Expand All @@ -19,7 +18,7 @@ import { COLUMN_TYPE_OPTIONS } from '../column-config-sidebar'
const CELL_HEADER =
'border-[var(--border)] border-r border-b bg-[var(--bg)] px-2 py-[7px] text-left align-middle'

interface NewColumnDropdownProps {
interface ColumnDropdownProps {
/** `'header'` renders the page-header trigger (subtle Button); `'inline-header'` renders
* the in-table column-header `<th>` trigger. Same dropdown content either way. */
trigger: 'header' | 'inline-header'
Expand All @@ -42,15 +41,15 @@ interface NewColumnDropdownProps {
* Lists every column type plus "Workflow" and "Enrichments"; picking a type
* opens the right sidebar pre-seeded.
*/
export function NewColumnDropdown({
export function ColumnDropdown({
trigger,
disabled,
onPickType,
onPickWorkflow,
onPickEnrichment,
blocked,
onBlocked,
}: NewColumnDropdownProps) {
}: ColumnDropdownProps) {
const triggerButton =
trigger === 'header' ? (
<button
Expand Down Expand Up @@ -86,18 +85,7 @@ export function NewColumnDropdown({
const menu = (
<DropdownMenu>
<DropdownMenuTrigger asChild>{triggerButton}</DropdownMenuTrigger>
{/* Taller than the 240px shared default: the full type list is 9 items
(295px with its separator and padding), so the default cut the last
two off behind a scrollbar. Sized here rather than in the shared
component, which every other dropdown in the app relies on. */}
<DropdownMenuContent align='start' side='bottom' sideOffset={4} className='max-h-[320px]'>
<>
<DropdownMenuItem onSelect={onPickEnrichment}>
<Sparkles className='size-[14px] text-[var(--text-icon)]' />
Enrichments
</DropdownMenuItem>
<DropdownMenuSeparator />
</>
<DropdownMenuContent align='start' side='bottom' sideOffset={4}>
{COLUMN_TYPE_OPTIONS.map((option) => {
const Icon = option.icon
const onSelect =
Expand All @@ -111,6 +99,10 @@ export function NewColumnDropdown({
</DropdownMenuItem>
)
})}
<DropdownMenuItem onSelect={onPickEnrichment}>
<Sparkles className='size-[14px] text-[var(--text-icon)]' />
Enrichments
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { ColumnDropdown } from './column-dropdown'
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
export * from './column-config-sidebar'
export * from './column-dropdown'
export * from './columns-menu'
export * from './context-menu'
export * from './enrichment-details'
export * from './enrichments-sidebar'
export * from './lock-settings-modal'
export * from './new-column-dropdown'
export * from './row-modal'
export * from './run-status-control'
export * from './save-view-modal'
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,8 @@ import { useContextMenu, useTable } from '../../hooks'
import type { EditingCell, QueryOptions, SaveReason } from '../../types'
import { cleanCellValue, generateColumnName as sharedGenerateColumnName } from '../../utils'
import type { ColumnConfig } from '../column-config-sidebar'
import { ColumnDropdown } from '../column-dropdown'
import { ContextMenu } from '../context-menu'
import { NewColumnDropdown } from '../new-column-dropdown'
import type { WorkflowConfig } from '../workflow-sidebar'
import { ExpandedCellPopover } from './cells'
import { ADD_COL_WIDTH, COL_WIDTH, SELECTION_TINT_BG } from './constants'
Expand Down Expand Up @@ -898,7 +898,11 @@ export function TableGrid({
* so solo editing never pays the map build. */
const columnIndexById = useMemo(() => {
const map = new Map<string, number>()
if (remoteSelections.length > 0) displayColumns.forEach((col, index) => map.set(col.key, index))
if (remoteSelections.length > 0) {
displayColumns.forEach((col, index) => {
map.set(col.key, index)
})
}
return map
}, [displayColumns, remoteSelections.length])

Expand All @@ -907,7 +911,11 @@ export function TableGrid({
* solo editing never pays the O(n) map build on a refetch. */
const rowIndexById = useMemo(() => {
const map = new Map<string, number>()
if (remoteSelections.length > 0) rows.forEach((row, index) => map.set(row.id, index))
if (remoteSelections.length > 0) {
rows.forEach((row, index) => {
map.set(row.id, index)
})
}
return map
}, [rows, remoteSelections.length])

Expand Down Expand Up @@ -2251,7 +2259,9 @@ export function TableGrid({
const draggedGid = colByName.get(dragged)?.workflowGroupId

const orderIndex = new Map<string, number>()
currentOrder.forEach((n, i) => orderIndex.set(n, i))
currentOrder.forEach((n, i) => {
orderIndex.set(n, i)
})

// Compute the contiguous run covering the dragged column. For a plain
// column this is just [fromIndex, fromIndex]. For a group member it spans
Expand Down Expand Up @@ -4853,7 +4863,7 @@ export function TableGrid({
)
})}
{userPermissions.canEdit && (
<NewColumnDropdown
<ColumnDropdown
trigger='inline-header'
disabled={addColumnMutation.isPending}
blocked={!canMutateSchema}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,11 +71,11 @@ import type { DeletedRowSnapshot } from '@/stores/table/types'
import {
type ColumnConfig,
ColumnConfigSidebar,
ColumnDropdown,
ColumnsMenu,
EnrichmentDetails,
EnrichmentsSidebar,
LockSettingsModal,
NewColumnDropdown,
RowModal,
RunStatusControl,
SaveViewModal,
Expand Down Expand Up @@ -1372,7 +1372,7 @@ export function Table({
// table is schema-locked and explains itself instead of disappearing.
const canMutateSchema = userPermissions.canEdit && !tableData?.locks.schemaLocked
const createTrigger = userPermissions.canEdit ? (
<NewColumnDropdown
<ColumnDropdown
trigger='header'
disabled={false}
blocked={!canMutateSchema}
Expand Down
Loading