Scrollable tables, specify multi-part filename, fix required prop in prompt, better tab padding

This commit is contained in:
Gregory Schier
2025-11-25 08:45:33 -08:00
parent 0cad8f69e2
commit c4ab2965f7
16 changed files with 245 additions and 144 deletions

View File

@@ -1,9 +1,16 @@
import type { Folder } from '@yaakapp-internal/models';
import { createWorkspaceModel } from '@yaakapp-internal/models';
import { createWorkspaceModel, type Folder, modelTypeLabel } from '@yaakapp-internal/models';
import { applySync, calculateSync } from '@yaakapp-internal/sync';
import { Banner } from '../components/core/Banner';
import { InlineCode } from '../components/core/InlineCode';
import { VStack } from '../components/core/Stacks';
import {
Table,
TableBody,
TableCell,
TableHead,
TableHeaderCell,
TableRow,
TruncatedWideTableCell,
} from '../components/core/Table';
import { activeWorkspaceIdAtom } from '../hooks/useActiveWorkspace';
import { createFastMutation } from '../hooks/useFastMutation';
import { showConfirm } from '../lib/confirm';
@@ -76,63 +83,72 @@ export const syncWorkspace = createFastMutation<
: await showConfirm({
id: 'commit-sync',
title: 'Changes Detected',
size: 'md',
confirmText: 'Apply Changes',
color: isDeletingWorkspace ? 'danger' : 'primary',
description: (
<VStack space={3}>
{isDeletingWorkspace && (
<div className="h-full grid grid-rows-[auto_auto_minmax(0,1fr)] gap-3">
{isDeletingWorkspace ? (
<Banner color="danger">
🚨 <strong>Changes contain a workspace deletion!</strong>
</Banner>
) : (
<span />
)}
<p>
{pluralizeCount('file', dbOps.length)} in the directory{' '}
{dbOps.length === 1 ? 'has' : 'have'} changed. Do you want to update your workspace?
</p>
<div className="overflow-y-auto max-h-[10rem]">
<table className="w-full text-sm mb-auto min-w-full max-w-full divide-y divide-surface-highlight">
<thead>
<tr>
<th className="py-1 text-left">Name</th>
<th className="py-1 text-right pl-4">Operation</th>
</tr>
</thead>
<tbody className="divide-y divide-surface-highlight">
{dbOps.map((op, i) => {
let name = '';
let label = '';
let color = '';
<Table scrollable>
<TableHead>
<TableRow>
<TableHeaderCell>Type</TableHeaderCell>
<TableHeaderCell>Name</TableHeaderCell>
<TableHeaderCell>Operation</TableHeaderCell>
</TableRow>
</TableHead>
<TableBody>
{dbOps.map((op, i) => {
let name: string;
let label: string;
let color: string;
let model: string;
if (op.type === 'dbCreate') {
label = 'create';
name = resolvedModelNameWithFolders(op.fs.model);
color = 'text-success';
} else if (op.type === 'dbUpdate') {
label = 'update';
name = resolvedModelNameWithFolders(op.fs.model);
color = 'text-info';
} else if (op.type === 'dbDelete') {
label = 'delete';
name = resolvedModelNameWithFolders(op.model);
color = 'text-danger';
} else {
return null;
}
if (op.type === 'dbCreate') {
label = 'create';
name = resolvedModelNameWithFolders(op.fs.model);
color = 'text-success';
model = modelTypeLabel(op.fs.model);
} else if (op.type === 'dbUpdate') {
label = 'update';
name = resolvedModelNameWithFolders(op.fs.model);
color = 'text-info';
model = modelTypeLabel(op.fs.model);
} else if (op.type === 'dbDelete') {
label = 'delete';
name = resolvedModelNameWithFolders(op.model);
color = 'text-danger';
model = modelTypeLabel(op.model);
} else {
return null;
}
return (
// biome-ignore lint/suspicious/noArrayIndexKey: none
<tr key={i} className="text-text">
<td className="py-1">{name}</td>
<td className="py-1 pl-4 text-right">
<InlineCode className={color}>{label}</InlineCode>
</td>
</tr>
);
})}
</tbody>
</table>
</div>
</VStack>
return (
// biome-ignore lint/suspicious/noArrayIndexKey: none
<TableRow key={i}>
<TableCell>{model}</TableCell>
<TruncatedWideTableCell className="text-text">
{name}
</TruncatedWideTableCell>
<TableCell className="text-right">
<InlineCode className={color}>{label}</InlineCode>
</TableCell>
</TableRow>
);
})}
</TableBody>
</Table>
</div>
),
});
if (confirmed) {