Refactor renamed the component groups to something less obtuse:
Elements -> Groups -> Screens -> Views
This commit is contained in:
parent
ca6de91a96
commit
dd46acba87
2 changed files with 151 additions and 144 deletions
|
|
@ -0,0 +1,61 @@
|
|||
import type { Meta, StoryObj } from "@storybook/react-vite";
|
||||
import { fn } from "storybook/test";
|
||||
import { RootsTable } from "./RootsTable";
|
||||
|
||||
const meta: Meta<typeof RootsTable> = {
|
||||
title: "Groups/RootsTable",
|
||||
component: RootsTable,
|
||||
args: {
|
||||
onRemoveRoot: fn(),
|
||||
onNewRootNameChange: fn(),
|
||||
onNewRootPathChange: fn(),
|
||||
onAddRoot: fn(),
|
||||
onBrowse: fn(),
|
||||
},
|
||||
};
|
||||
|
||||
export default meta;
|
||||
type Story = StoryObj<typeof RootsTable>;
|
||||
|
||||
export const WithRoots: Story = {
|
||||
args: {
|
||||
roots: [
|
||||
{ name: "Project Source", uri: "file:///home/user/project/src" },
|
||||
{ name: "Configuration", uri: "file:///home/user/project/config" },
|
||||
{ name: "Documentation", uri: "file:///home/user/project/docs" },
|
||||
],
|
||||
newRootName: "",
|
||||
newRootPath: "",
|
||||
},
|
||||
};
|
||||
|
||||
export const Empty: Story = {
|
||||
args: {
|
||||
roots: [],
|
||||
newRootName: "",
|
||||
newRootPath: "",
|
||||
},
|
||||
};
|
||||
|
||||
export const AddingNew: Story = {
|
||||
args: {
|
||||
roots: [{ name: "Project Source", uri: "file:///home/user/project/src" }],
|
||||
newRootName: "Test Data",
|
||||
newRootPath: "/home/user/project/test-data",
|
||||
},
|
||||
};
|
||||
|
||||
export const ManyRoots: Story = {
|
||||
args: {
|
||||
roots: [
|
||||
{ name: "Source Code", uri: "file:///home/user/project/src" },
|
||||
{ name: "Configuration", uri: "file:///home/user/project/config" },
|
||||
{ name: "Documentation", uri: "file:///home/user/project/docs" },
|
||||
{ name: "Test Fixtures", uri: "file:///home/user/project/test/fixtures" },
|
||||
{ name: "Build Output", uri: "file:///home/user/project/dist" },
|
||||
{ name: "Scripts", uri: "file:///home/user/project/scripts" },
|
||||
],
|
||||
newRootName: "",
|
||||
newRootPath: "",
|
||||
},
|
||||
};
|
||||
113
clients/web/src/components/groups/RootsTable/RootsTable.tsx
Normal file
113
clients/web/src/components/groups/RootsTable/RootsTable.tsx
Normal file
|
|
@ -0,0 +1,113 @@
|
|||
import {
|
||||
ActionIcon,
|
||||
Alert,
|
||||
Button,
|
||||
Divider,
|
||||
Group,
|
||||
Stack,
|
||||
Table,
|
||||
Text,
|
||||
TextInput,
|
||||
Title,
|
||||
} from "@mantine/core";
|
||||
|
||||
export interface RootEntry {
|
||||
name: string;
|
||||
uri: string;
|
||||
}
|
||||
|
||||
export interface RootsTableProps {
|
||||
roots: RootEntry[];
|
||||
newRootName: string;
|
||||
newRootPath: string;
|
||||
onRemoveRoot: (uri: string) => void;
|
||||
onNewRootNameChange: (name: string) => void;
|
||||
onNewRootPathChange: (path: string) => void;
|
||||
onAddRoot: () => void;
|
||||
onBrowse: () => void;
|
||||
}
|
||||
|
||||
const HintText = Text.withProps({
|
||||
size: "sm",
|
||||
c: "dimmed",
|
||||
});
|
||||
|
||||
const RemoveIcon = ActionIcon.withProps({
|
||||
color: "red",
|
||||
variant: "subtle",
|
||||
});
|
||||
|
||||
const AddRootButton = Button.withProps({
|
||||
variant: "light",
|
||||
fullWidth: true,
|
||||
});
|
||||
|
||||
export function RootsTable({
|
||||
roots,
|
||||
newRootName,
|
||||
newRootPath,
|
||||
onRemoveRoot,
|
||||
onNewRootNameChange,
|
||||
onNewRootPathChange,
|
||||
onAddRoot,
|
||||
onBrowse,
|
||||
}: RootsTableProps) {
|
||||
return (
|
||||
<Stack gap="md">
|
||||
<Title order={4}>Roots Configuration</Title>
|
||||
<HintText>Filesystem roots exposed to the connected server:</HintText>
|
||||
|
||||
{roots.length > 0 && (
|
||||
<Table>
|
||||
<Table.Thead>
|
||||
<Table.Tr>
|
||||
<Table.Th>Name</Table.Th>
|
||||
<Table.Th>URI</Table.Th>
|
||||
<Table.Th>Actions</Table.Th>
|
||||
</Table.Tr>
|
||||
</Table.Thead>
|
||||
<Table.Tbody>
|
||||
{roots.map((root) => (
|
||||
<Table.Tr key={root.uri}>
|
||||
<Table.Td>{root.name}</Table.Td>
|
||||
<Table.Td>{root.uri}</Table.Td>
|
||||
<Table.Td>
|
||||
<RemoveIcon onClick={() => onRemoveRoot(root.uri)}>
|
||||
X
|
||||
</RemoveIcon>
|
||||
</Table.Td>
|
||||
</Table.Tr>
|
||||
))}
|
||||
</Table.Tbody>
|
||||
</Table>
|
||||
)}
|
||||
|
||||
<AddRootButton onClick={onAddRoot}>+ Add Root</AddRootButton>
|
||||
|
||||
<Divider />
|
||||
|
||||
<Title order={5}>Add New Root:</Title>
|
||||
<TextInput
|
||||
label="Name"
|
||||
value={newRootName}
|
||||
onChange={(e) => onNewRootNameChange(e.currentTarget.value)}
|
||||
/>
|
||||
<TextInput
|
||||
label="Path"
|
||||
value={newRootPath}
|
||||
onChange={(e) => onNewRootPathChange(e.currentTarget.value)}
|
||||
/>
|
||||
<Group justify="flex-end">
|
||||
<Button variant="light" onClick={onBrowse}>
|
||||
Browse
|
||||
</Button>
|
||||
<Button onClick={onAddRoot}>Add</Button>
|
||||
</Group>
|
||||
|
||||
<Alert color="yellow" title="Warning">
|
||||
Roots give the server access to these directories. Only add directories
|
||||
you trust the server to access.
|
||||
</Alert>
|
||||
</Stack>
|
||||
);
|
||||
}
|
||||
Loading…
Reference in a new issue