Skip to content

Commit 0c1167d

Browse files
authored
improvement(workspace): fix resource table column proportions and toast stacking (#4655)
* improvement(workspace): fix resource table column proportions and toast stacking * fix(resource): restore scrollbar-gutter stable on table scroll container * fix(resource): remove scrollbar-gutter stable — single-table layout doesn't need it * fixed files cols * fix(findymail): add required enabled field to wandConfig entries * fix(findymail): remove optional from block outputs — not valid on BlockConfig output type * fixes * fix(files): use folderSizeMap for sort value so size sort matches display * files ref
1 parent f3cf8fc commit 0c1167d

25 files changed

Lines changed: 431 additions & 255 deletions

File tree

apps/docs/components/ui/icon-mapping.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -263,7 +263,6 @@ export const blockTypeToIconMap: Record<string, IconComponent> = {
263263
extend_v2: ExtendIcon,
264264
fathom: FathomIcon,
265265
file: DocumentIcon,
266-
file_v3: DocumentIcon,
267266
file_v4: DocumentIcon,
268267
findymail: FindymailIcon,
269268
firecrawl: FirecrawlIcon,

apps/docs/content/docs/de/tools/file.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ description: Mehrere Dateien lesen und parsen
66
import { BlockInfoCard } from "@/components/ui/block-info-card"
77

88
<BlockInfoCard
9-
type="file_v3"
9+
type="file_v4"
1010
color="#40916C"
1111
/>
1212

apps/docs/content/docs/en/tools/prospeo.mdx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -229,9 +229,9 @@ Free endpoint to retrieve valid location or job title values for use in Search f
229229

230230
| Parameter | Type | Description |
231231
| --------- | ---- | ----------- |
232-
| `location_suggestions` | array | Location suggestions when using location_search \(null when searching job titles\) |
232+
| `location_suggestions` | array | Location suggestions when using location_search \(empty when searching job titles\) |
233233
|`name` | string | Formatted location name to use in filters |
234234
|`type` | string | Location type \(COUNTRY, STATE, CITY, or ZONE\) |
235-
| `job_title_suggestions` | array | Up to 25 job title suggestions ordered by popularity when using job_title_search \(null when searching locations\) |
235+
| `job_title_suggestions` | array | Up to 25 job title suggestions ordered by popularity when using job_title_search \(empty when searching locations\) |
236236

237237

apps/docs/content/docs/es/tools/file.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ description: Leer y analizar múltiples archivos
66
import { BlockInfoCard } from "@/components/ui/block-info-card"
77

88
<BlockInfoCard
9-
type="file_v3"
9+
type="file_v4"
1010
color="#40916C"
1111
/>
1212

apps/docs/content/docs/fr/tools/file.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ description: Lire et analyser plusieurs fichiers
66
import { BlockInfoCard } from "@/components/ui/block-info-card"
77

88
<BlockInfoCard
9-
type="file_v3"
9+
type="file_v4"
1010
color="#40916C"
1111
/>
1212

apps/docs/content/docs/ja/tools/file.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ description: 複数のファイルを読み込んで解析する
66
import { BlockInfoCard } from "@/components/ui/block-info-card"
77

88
<BlockInfoCard
9-
type="file_v3"
9+
type="file_v4"
1010
color="#40916C"
1111
/>
1212

apps/docs/content/docs/zh/tools/file.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ description: 读取并解析多个文件
66
import { BlockInfoCard } from "@/components/ui/block-info-card"
77

88
<BlockInfoCard
9-
type="file_v3"
9+
type="file_v4"
1010
color="#40916C"
1111
/>
1212

apps/sim/app/_styles/globals.css

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -878,22 +878,22 @@ input[type="search"]::-ms-clear {
878878
@keyframes toast-enter {
879879
from {
880880
opacity: 0;
881-
transform: translateY(8px) scale(0.97);
881+
transform: translateX(var(--stack-offset, 0px)) translateY(8px) scale(0.97);
882882
}
883883
to {
884884
opacity: 1;
885-
transform: translateY(0) scale(1);
885+
transform: translateX(var(--stack-offset, 0px)) translateY(0) scale(1);
886886
}
887887
}
888888

889889
@keyframes toast-exit {
890890
from {
891891
opacity: 1;
892-
transform: translateY(0) scale(1);
892+
transform: translateX(var(--stack-offset, 0px)) translateY(0) scale(1);
893893
}
894894
to {
895895
opacity: 0;
896-
transform: translateY(8px) scale(0.97);
896+
transform: translateX(var(--stack-offset, 0px)) translateY(8px) scale(0.97);
897897
}
898898
}
899899

apps/sim/app/workspace/[workspaceId]/components/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,4 +25,4 @@ export type {
2525
RowDragDropConfig,
2626
SelectableConfig,
2727
} from './resource/resource'
28-
export { Resource, ResourceTable } from './resource/resource'
28+
export { EMPTY_CELL_PLACEHOLDER, Resource, ResourceTable } from './resource/resource'

apps/sim/app/workspace/[workspaceId]/components/resource/resource.tsx

Lines changed: 48 additions & 93 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,6 @@ export interface ResourceColumn {
2323
id: string
2424
header: string
2525
widthMultiplier?: number
26-
/** Fixed pixel width. When set, the column is excluded from proportional sizing. */
27-
widthPx?: number
2826
}
2927

3028
export interface ResourceCell {
@@ -94,7 +92,7 @@ interface ResourceProps {
9492
overlay?: ReactNode
9593
}
9694

97-
const EMPTY_CELL_PLACEHOLDER = '- - -'
95+
export const EMPTY_CELL_PLACEHOLDER = ''
9896
const SKELETON_ROW_COUNT = 5
9997

10098
/**
@@ -214,20 +212,13 @@ export const ResourceTable = memo(function ResourceTable({
214212
emptyMessage,
215213
overlay,
216214
}: ResourceTableProps) {
217-
const headerRef = useRef<HTMLDivElement>(null)
218215
const loadMoreRef = useRef<HTMLDivElement>(null)
219216
const sortEnabled = defaultSort != null
220217
const [internalSort, setInternalSort] = useState<{ column: string; direction: 'asc' | 'desc' }>({
221218
column: defaultSort ?? '',
222219
direction: 'desc',
223220
})
224221

225-
const handleBodyScroll = useCallback((e: React.UIEvent<HTMLDivElement>) => {
226-
if (headerRef.current) {
227-
headerRef.current.scrollLeft = e.currentTarget.scrollLeft
228-
}
229-
}, [])
230-
231222
const handleSort = useCallback((column: string, direction: 'asc' | 'desc') => {
232223
setInternalSort({ column, direction })
233224
}, [])
@@ -290,10 +281,10 @@ export const ResourceTable = memo(function ResourceTable({
290281

291282
return (
292283
<div className='relative flex min-h-0 flex-1 flex-col overflow-hidden'>
293-
<div ref={headerRef} className='overflow-hidden'>
284+
<div className='min-h-0 flex-1 overflow-auto'>
294285
<table className='w-full table-fixed text-small'>
295286
<ResourceColGroup columns={columns} hasCheckbox={hasCheckbox} />
296-
<thead className='shadow-[inset_0_-1px_0_var(--border)]'>
287+
<thead className='sticky top-0 z-10 bg-[var(--bg)] shadow-[inset_0_-1px_0_var(--border)]'>
297288
<tr>
298289
{hasCheckbox && (
299290
<th className='h-10 w-[52px] py-1.5 pr-0 pl-5 text-left align-middle'>
@@ -341,14 +332,6 @@ export const ResourceTable = memo(function ResourceTable({
341332
})}
342333
</tr>
343334
</thead>
344-
</table>
345-
</div>
346-
<div
347-
className='min-h-0 flex-1 overflow-auto [scrollbar-gutter:stable]'
348-
onScroll={handleBodyScroll}
349-
>
350-
<table className='w-full table-fixed text-small'>
351-
<ResourceColGroup columns={columns} hasCheckbox={hasCheckbox} />
352335
<tbody>
353336
{displayRows.map((row) => (
354337
<DataRow
@@ -644,43 +627,22 @@ interface ResourceColGroupProps {
644627
hasCheckbox?: boolean
645628
}
646629

647-
const CHECKBOX_COLUMN_WIDTH_PX = 52
648-
const CHECKBOX_COLUMN_WIDTH = `${CHECKBOX_COLUMN_WIDTH_PX}px`
630+
const CHECKBOX_COLUMN_WIDTH = '52px'
649631

650632
const ResourceColGroup = memo(function ResourceColGroup({
651633
columns,
652634
hasCheckbox,
653635
}: ResourceColGroupProps) {
654-
const fixedPxTotal = columns.reduce((sum, col) => sum + (col.widthPx ?? 0), 0)
655-
const flexibleWeights = columns.map((col, colIdx) =>
656-
col.widthPx ? 0 : (colIdx === 0 ? 2.5 : 1.0) * (col.widthMultiplier ?? 1)
636+
const weights = columns.map(
637+
(col, colIdx) => (colIdx === 0 ? 2.5 : 1.0) * (col.widthMultiplier ?? 1)
657638
)
658-
const flexibleTotal = flexibleWeights.reduce((s, w) => s + w, 0)
659-
const reservedPx = fixedPxTotal + (hasCheckbox ? CHECKBOX_COLUMN_WIDTH_PX : 0)
660-
639+
const total = weights.reduce((s, w) => s + w, 0)
661640
return (
662641
<colgroup>
663642
{hasCheckbox && <col style={{ width: CHECKBOX_COLUMN_WIDTH }} />}
664-
{columns.map((col, colIdx) => {
665-
if (col.widthPx) {
666-
return <col key={col.id} style={{ width: `${col.widthPx}px` }} />
667-
}
668-
const columnRatio = flexibleTotal > 0 ? flexibleWeights[colIdx] / flexibleTotal : 0
669-
const columnPercent = columnRatio * 100
670-
const reservedOffset = reservedPx * columnRatio
671-
672-
return (
673-
<col
674-
key={col.id}
675-
style={{
676-
width:
677-
reservedOffset > 0
678-
? `calc(${columnPercent}% - ${reservedOffset}px)`
679-
: `${columnPercent}%`,
680-
}}
681-
/>
682-
)
683-
})}
643+
{columns.map((col, colIdx) => (
644+
<col key={col.id} style={{ width: `${((weights[colIdx] / total) * 100).toFixed(3)}%` }} />
645+
))}
684646
</colgroup>
685647
)
686648
})
@@ -697,55 +659,48 @@ const DataTableSkeleton = memo(function DataTableSkeleton({
697659
hasCheckbox,
698660
}: DataTableSkeletonProps) {
699661
return (
700-
<>
701-
<div className='overflow-hidden'>
702-
<table className='w-full table-fixed text-small'>
703-
<ResourceColGroup columns={columns} hasCheckbox={hasCheckbox} />
704-
<thead className='shadow-[inset_0_-1px_0_var(--border)]'>
705-
<tr>
662+
<div className='min-h-0 flex-1 overflow-auto'>
663+
<table className='w-full table-fixed text-small'>
664+
<ResourceColGroup columns={columns} hasCheckbox={hasCheckbox} />
665+
<thead className='sticky top-0 z-10 bg-[var(--bg)] shadow-[inset_0_-1px_0_var(--border)]'>
666+
<tr>
667+
{hasCheckbox && (
668+
<th className='h-10 w-[52px] py-2.5 pr-0 pl-5 text-left align-middle'>
669+
<Skeleton className='size-[14px] rounded-xs' />
670+
</th>
671+
)}
672+
{columns.map((col) => (
673+
<th
674+
key={col.id}
675+
className='h-10 px-6 py-2.5 text-left align-middle font-base text-[var(--text-muted)]'
676+
>
677+
<div className='flex min-h-[20px] items-center'>
678+
<Skeleton className='h-[12px] w-[56px]' />
679+
</div>
680+
</th>
681+
))}
682+
</tr>
683+
</thead>
684+
<tbody>
685+
{Array.from({ length: rowCount }, (_, i) => (
686+
<tr key={i}>
706687
{hasCheckbox && (
707-
<th className='h-10 w-[52px] py-2.5 pr-0 pl-5 text-left align-middle'>
688+
<td className='w-[52px] py-2.5 pr-0 pl-5 align-middle'>
708689
<Skeleton className='size-[14px] rounded-xs' />
709-
</th>
690+
</td>
710691
)}
711-
{columns.map((col) => (
712-
<th
713-
key={col.id}
714-
className='h-10 px-6 py-2.5 text-left align-middle font-base text-[var(--text-muted)]'
715-
>
716-
<div className='flex min-h-[20px] items-center'>
717-
<Skeleton className='h-[12px] w-[56px]' />
718-
</div>
719-
</th>
692+
{columns.map((col, colIdx) => (
693+
<td key={col.id} className='px-6 py-2.5 align-middle'>
694+
<span className='flex min-h-[21px] items-center gap-3'>
695+
{colIdx === 0 && <Skeleton className='size-[14px] rounded-xs' />}
696+
<Skeleton className='h-[14px] w-[128px]' />
697+
</span>
698+
</td>
720699
))}
721700
</tr>
722-
</thead>
723-
</table>
724-
</div>
725-
<div className='min-h-0 flex-1 overflow-auto'>
726-
<table className='w-full table-fixed text-small'>
727-
<ResourceColGroup columns={columns} hasCheckbox={hasCheckbox} />
728-
<tbody>
729-
{Array.from({ length: rowCount }, (_, i) => (
730-
<tr key={i}>
731-
{hasCheckbox && (
732-
<td className='w-[52px] py-2.5 pr-0 pl-5 align-middle'>
733-
<Skeleton className='size-[14px] rounded-xs' />
734-
</td>
735-
)}
736-
{columns.map((col, colIdx) => (
737-
<td key={col.id} className='px-6 py-2.5 align-middle'>
738-
<span className='flex min-h-[21px] items-center gap-3'>
739-
{colIdx === 0 && <Skeleton className='size-[14px] rounded-xs' />}
740-
<Skeleton className='h-[14px] w-[128px]' />
741-
</span>
742-
</td>
743-
))}
744-
</tr>
745-
))}
746-
</tbody>
747-
</table>
748-
</div>
749-
</>
701+
))}
702+
</tbody>
703+
</table>
704+
</div>
750705
)
751706
})

0 commit comments

Comments
 (0)