Skip to content

Commit d8e96c5

Browse files
fix ui shape
1 parent f23f234 commit d8e96c5

23 files changed

Lines changed: 916 additions & 787 deletions

File tree

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
import { createLogger } from '@sim/logger'
2+
import { type NextRequest, NextResponse } from 'next/server'
3+
import { runColumnContract } from '@/lib/api/contracts/tables'
4+
import { parseRequest } from '@/lib/api/server'
5+
import { checkSessionOrInternalAuth } from '@/lib/auth/hybrid'
6+
import { generateRequestId } from '@/lib/core/utils/request'
7+
import { withRouteHandler } from '@/lib/core/utils/with-route-handler'
8+
import { runWorkflowColumn } from '@/lib/table/workflow-columns'
9+
import { accessError, checkAccess } from '@/app/api/table/utils'
10+
11+
const logger = createLogger('TableRunColumnAPI')
12+
13+
interface RouteParams {
14+
params: Promise<{ tableId: string }>
15+
}
16+
17+
/** POST /api/table/[tableId]/columns/run */
18+
export const POST = withRouteHandler(async (request: NextRequest, { params }: RouteParams) => {
19+
const requestId = generateRequestId()
20+
try {
21+
const auth = await checkSessionOrInternalAuth(request, { requireWorkflowId: false })
22+
if (!auth.success || !auth.userId) {
23+
return NextResponse.json({ error: 'Authentication required' }, { status: 401 })
24+
}
25+
const parsed = await parseRequest(runColumnContract, request, { params })
26+
if (!parsed.success) return parsed.response
27+
const { tableId } = parsed.data.params
28+
const { workspaceId, groupIds, runMode, rowIds } = parsed.data.body
29+
const access = await checkAccess(tableId, auth.userId, 'write')
30+
if (!access.ok) return accessError(access, requestId, tableId)
31+
32+
const { triggered } = await runWorkflowColumn({
33+
tableId,
34+
workspaceId,
35+
groupIds,
36+
mode: runMode,
37+
rowIds,
38+
requestId,
39+
})
40+
return NextResponse.json({ success: true, data: { triggered } })
41+
} catch (error) {
42+
if (error instanceof Error && error.message === 'Invalid workspace ID') {
43+
return NextResponse.json({ error: 'Invalid workspace ID' }, { status: 400 })
44+
}
45+
logger.error(`run-column failed:`, error)
46+
return NextResponse.json({ error: 'Failed to run columns' }, { status: 500 })
47+
}
48+
})

apps/sim/app/api/table/[tableId]/groups/[groupId]/run/route.ts

Lines changed: 0 additions & 67 deletions
This file was deleted.
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
import { createLogger } from '@sim/logger'
2+
import { type NextRequest, NextResponse } from 'next/server'
3+
import { runCellContract } from '@/lib/api/contracts/tables'
4+
import { parseRequest } from '@/lib/api/server'
5+
import { checkSessionOrInternalAuth } from '@/lib/auth/hybrid'
6+
import { generateRequestId } from '@/lib/core/utils/request'
7+
import { withRouteHandler } from '@/lib/core/utils/with-route-handler'
8+
import { runWorkflowCell } from '@/lib/table/workflow-columns'
9+
import { accessError, checkAccess } from '@/app/api/table/utils'
10+
11+
const logger = createLogger('TableRunCellAPI')
12+
13+
interface RouteParams {
14+
params: Promise<{ tableId: string; rowId: string; groupId: string }>
15+
}
16+
17+
/** POST /api/table/[tableId]/rows/[rowId]/cells/[groupId]/run */
18+
export const POST = withRouteHandler(async (request: NextRequest, { params }: RouteParams) => {
19+
const requestId = generateRequestId()
20+
try {
21+
const auth = await checkSessionOrInternalAuth(request, { requireWorkflowId: false })
22+
if (!auth.success || !auth.userId) {
23+
return NextResponse.json({ error: 'Authentication required' }, { status: 401 })
24+
}
25+
const parsed = await parseRequest(runCellContract, request, { params })
26+
if (!parsed.success) return parsed.response
27+
const { tableId, rowId, groupId } = parsed.data.params
28+
const { workspaceId } = parsed.data.body
29+
const access = await checkAccess(tableId, auth.userId, 'write')
30+
if (!access.ok) return accessError(access, requestId, tableId)
31+
32+
const { triggered } = await runWorkflowCell({
33+
tableId,
34+
workspaceId,
35+
rowId,
36+
groupId,
37+
requestId,
38+
})
39+
return NextResponse.json({ success: true, data: { triggered } })
40+
} catch (error) {
41+
if (error instanceof Error && error.message === 'Invalid workspace ID') {
42+
return NextResponse.json({ error: 'Invalid workspace ID' }, { status: 400 })
43+
}
44+
logger.error(`run-cell failed:`, error)
45+
return NextResponse.json({ error: 'Failed to run cell' }, { status: 500 })
46+
}
47+
})

apps/sim/app/api/table/[tableId]/rows/[rowId]/run-workflow-group/route.ts

Lines changed: 0 additions & 58 deletions
This file was deleted.
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
import { createLogger } from '@sim/logger'
2+
import { type NextRequest, NextResponse } from 'next/server'
3+
import { runRowContract } from '@/lib/api/contracts/tables'
4+
import { parseRequest } from '@/lib/api/server'
5+
import { checkSessionOrInternalAuth } from '@/lib/auth/hybrid'
6+
import { generateRequestId } from '@/lib/core/utils/request'
7+
import { withRouteHandler } from '@/lib/core/utils/with-route-handler'
8+
import { runWorkflowRow } from '@/lib/table/workflow-columns'
9+
import { accessError, checkAccess } from '@/app/api/table/utils'
10+
11+
const logger = createLogger('TableRunRowAPI')
12+
13+
interface RouteParams {
14+
params: Promise<{ tableId: string }>
15+
}
16+
17+
/** POST /api/table/[tableId]/rows/run */
18+
export const POST = withRouteHandler(async (request: NextRequest, { params }: RouteParams) => {
19+
const requestId = generateRequestId()
20+
try {
21+
const auth = await checkSessionOrInternalAuth(request, { requireWorkflowId: false })
22+
if (!auth.success || !auth.userId) {
23+
return NextResponse.json({ error: 'Authentication required' }, { status: 401 })
24+
}
25+
const parsed = await parseRequest(runRowContract, request, { params })
26+
if (!parsed.success) return parsed.response
27+
const { tableId } = parsed.data.params
28+
const { workspaceId, rowIds } = parsed.data.body
29+
const access = await checkAccess(tableId, auth.userId, 'write')
30+
if (!access.ok) return accessError(access, requestId, tableId)
31+
32+
const { triggered } = await runWorkflowRow({
33+
tableId,
34+
workspaceId,
35+
rowIds,
36+
requestId,
37+
})
38+
return NextResponse.json({ success: true, data: { triggered } })
39+
} catch (error) {
40+
if (error instanceof Error && error.message === 'Invalid workspace ID') {
41+
return NextResponse.json({ error: 'Invalid workspace ID' }, { status: 400 })
42+
}
43+
logger.error(`run-row failed:`, error)
44+
return NextResponse.json({ error: 'Failed to run rows' }, { status: 500 })
45+
}
46+
})

apps/sim/app/workspace/[workspaceId]/tables/[tableId]/components/table-grid/headers/workflow-group-meta-cell.tsx

Lines changed: 26 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -48,10 +48,10 @@ interface ColumnOptionsMenuProps {
4848
onDeleteGroup?: () => void
4949
/** When provided, the menu is being opened from a workflow-group header and
5050
* exposes group-level run actions above the column actions. */
51-
onRunGroupAll?: () => void
52-
onRunGroupIncomplete?: () => void
51+
onRunColumnAll?: () => void
52+
onRunColumnIncomplete?: () => void
5353
/** When set, surfaces a "Run N selected rows" item above Run all. */
54-
onRunGroupSelected?: () => void
54+
onRunColumnSelected?: () => void
5555
selectedRowCount?: number
5656
/** When set, the menu surfaces a "View workflow" item that opens a popup
5757
* preview of the configured workflow. */
@@ -76,14 +76,14 @@ export function ColumnOptionsMenu({
7676
onInsertRight,
7777
onDeleteColumn,
7878
onDeleteGroup,
79-
onRunGroupAll,
80-
onRunGroupIncomplete,
81-
onRunGroupSelected,
79+
onRunColumnAll,
80+
onRunColumnIncomplete,
81+
onRunColumnSelected,
8282
selectedRowCount = 0,
8383
onViewWorkflow,
8484
}: ColumnOptionsMenuProps) {
85-
const showRunActions = Boolean(onRunGroupAll && onRunGroupIncomplete)
86-
const showRunSelected = Boolean(onRunGroupSelected) && selectedRowCount > 0
85+
const showRunActions = Boolean(onRunColumnAll && onRunColumnIncomplete)
86+
const showRunSelected = Boolean(onRunColumnSelected) && selectedRowCount > 0
8787
return (
8888
<DropdownMenu open={open} onOpenChange={onOpenChange}>
8989
<DropdownMenuTrigger asChild>
@@ -116,12 +116,14 @@ export function ColumnOptionsMenu({
116116
</DropdownMenuSubTrigger>
117117
<DropdownMenuSubContent>
118118
{showRunSelected && (
119-
<DropdownMenuItem onSelect={() => onRunGroupSelected?.()}>
119+
<DropdownMenuItem onSelect={() => onRunColumnSelected?.()}>
120120
{`Run ${selectedRowCount} selected ${selectedRowCount === 1 ? 'row' : 'rows'}`}
121121
</DropdownMenuItem>
122122
)}
123-
<DropdownMenuItem onSelect={() => onRunGroupAll?.()}>Run all rows</DropdownMenuItem>
124-
<DropdownMenuItem onSelect={() => onRunGroupIncomplete?.()}>
123+
<DropdownMenuItem onSelect={() => onRunColumnAll?.()}>
124+
Run all rows
125+
</DropdownMenuItem>
126+
<DropdownMenuItem onSelect={() => onRunColumnIncomplete?.()}>
125127
Run empty rows
126128
</DropdownMenuItem>
127129
</DropdownMenuSubContent>
@@ -172,12 +174,7 @@ interface WorkflowGroupMetaCellProps {
172174
isGroupSelected: boolean
173175
onSelectGroup: (startColIndex: number, size: number) => void
174176
onOpenConfig: (columnName: string) => void
175-
onRunGroup?: (
176-
groupId: string,
177-
workflowId: string,
178-
mode?: 'all' | 'incomplete',
179-
rowIds?: string[]
180-
) => void
177+
onRunColumn?: (groupId: string, mode?: 'all' | 'incomplete', rowIds?: string[]) => void
181178
onInsertLeft?: (columnName: string) => void
182179
onInsertRight?: (columnName: string) => void
183180
onDeleteColumn?: (columnName: string) => void
@@ -215,7 +212,7 @@ export function WorkflowGroupMetaCell({
215212
isGroupSelected,
216213
onSelectGroup,
217214
onOpenConfig,
218-
onRunGroup,
215+
onRunColumn,
219216
onInsertLeft,
220217
onInsertRight,
221218
onDeleteColumn,
@@ -240,18 +237,18 @@ export function WorkflowGroupMetaCell({
240237
const selectedCount = selectedRowIds?.length ?? 0
241238

242239
const handleRunAll = useCallback(() => {
243-
if (groupId && workflowId) onRunGroup?.(groupId, workflowId, 'all')
244-
}, [groupId, workflowId, onRunGroup])
240+
if (groupId) onRunColumn?.(groupId, 'all')
241+
}, [groupId, onRunColumn])
245242

246243
const handleRunIncomplete = useCallback(() => {
247-
if (groupId && workflowId) onRunGroup?.(groupId, workflowId, 'incomplete')
248-
}, [groupId, workflowId, onRunGroup])
244+
if (groupId) onRunColumn?.(groupId, 'incomplete')
245+
}, [groupId, onRunColumn])
249246

250247
const handleRunSelected = useCallback(() => {
251-
if (groupId && workflowId && selectedRowIds && selectedRowIds.length > 0) {
252-
onRunGroup?.(groupId, workflowId, 'all', selectedRowIds)
248+
if (groupId && selectedRowIds && selectedRowIds.length > 0) {
249+
onRunColumn?.(groupId, 'all', selectedRowIds)
253250
}
254-
}, [groupId, workflowId, onRunGroup, selectedRowIds])
251+
}, [groupId, onRunColumn, selectedRowIds])
255252

256253
const handleContextMenu = useCallback(
257254
(e: React.MouseEvent) => {
@@ -380,7 +377,7 @@ export function WorkflowGroupMetaCell({
380377
<span className='min-w-0 truncate font-medium text-[11px] text-[var(--text-secondary)]'>
381378
{name}
382379
</span>
383-
{onRunGroup && (
380+
{onRunColumn && (
384381
<DropdownMenu open={runMenuOpen} onOpenChange={setRunMenuOpen}>
385382
<DropdownMenuTrigger asChild>
386383
<button
@@ -421,9 +418,9 @@ export function WorkflowGroupMetaCell({
421418
onInsertRight={onInsertRight}
422419
onDeleteColumn={onDeleteColumn}
423420
onDeleteGroup={onDeleteGroup ? () => onDeleteGroup(groupId) : undefined}
424-
onRunGroupAll={onRunGroup ? handleRunAll : undefined}
425-
onRunGroupIncomplete={onRunGroup ? handleRunIncomplete : undefined}
426-
onRunGroupSelected={onRunGroup && selectedCount > 0 ? handleRunSelected : undefined}
421+
onRunColumnAll={onRunColumn ? handleRunAll : undefined}
422+
onRunColumnIncomplete={onRunColumn ? handleRunIncomplete : undefined}
423+
onRunColumnSelected={onRunColumn && selectedCount > 0 ? handleRunSelected : undefined}
427424
selectedRowCount={selectedCount}
428425
onViewWorkflow={onViewWorkflow ? () => onViewWorkflow(workflowId) : undefined}
429426
/>

0 commit comments

Comments
 (0)