@@ -39,7 +47,10 @@ export function TableList() {
variant="link"
asChild
>
-
+
{table.title}
diff --git a/apps/web/src/features/dashboard/pages/root/page.tsx b/apps/web/src/features/dashboard/pages/root/page.tsx
index 6c3d03c..db1feeb 100644
--- a/apps/web/src/features/dashboard/pages/root/page.tsx
+++ b/apps/web/src/features/dashboard/pages/root/page.tsx
@@ -1,12 +1,14 @@
+import { FlexCol } from "@manifold/ui/components/ui/flex";
+
import { DashboardHeader } from "~features/dashboard/components/dashboard-header";
import { TableList } from "~features/dashboard/components/table-list";
export function DashboardRoot() {
return (
-
+
);
}
diff --git a/apps/web/src/features/editor/editor.tsx b/apps/web/src/features/editor/editor.tsx
index 6f41fb7..a1b8e8d 100644
--- a/apps/web/src/features/editor/editor.tsx
+++ b/apps/web/src/features/editor/editor.tsx
@@ -1,3 +1,4 @@
+import { FlexCol } from "@manifold/ui/components/ui/flex";
import {
ResizableHandle,
ResizablePanel,
@@ -36,35 +37,34 @@ export function Editor({
}, []);
return (
-
-
- }
- name={name}
- value={value ?? ""}
- onChange={onChange}
- onBlur={onBlur}
- refCallback={refCallback}
- onParseError={onParseError}
- onParseSuccess={onParseSuccess}
- />
-
+
+
+
+ }
+ name={name}
+ value={value ?? ""}
+ onChange={onChange}
+ onBlur={onBlur}
+ refCallback={refCallback}
+ onParseError={onParseError}
+ onParseSuccess={onParseSuccess}
+ />
+
-
+
-
-
-
-
+
+
+
+
+
+
+
+
);
}
diff --git a/apps/web/src/features/editor/input-panel.tsx b/apps/web/src/features/editor/input-panel.tsx
index 4fce77f..d4a357d 100644
--- a/apps/web/src/features/editor/input-panel.tsx
+++ b/apps/web/src/features/editor/input-panel.tsx
@@ -7,7 +7,7 @@ import {
} from "react";
import type { RefCallBack } from "react-hook-form";
-import { currentTableHash, currentTableMetadata } from "./state";
+import { currentTableHash, currentTableMetadata, rollHistory } from "./state";
import { workerInstance } from "./worker";
type Props = {
@@ -32,7 +32,7 @@ export function InputPanel({
onParseSuccess,
}: Props) {
const setTableHash = useSetAtom(currentTableHash);
-
+ const setRollResults = useSetAtom(rollHistory);
const setTableMetadata = useSetAtom(currentTableMetadata);
const parseAndValidate = useCallback(
@@ -43,11 +43,12 @@ export function InputPanel({
setTableHash(hash);
setTableMetadata(metadata);
- onParseSuccess();
} else {
setTableHash(null);
setTableMetadata([]);
}
+
+ onParseSuccess();
} catch (e: unknown) {
console.error(e);
@@ -70,6 +71,13 @@ export function InputPanel({
if (value) {
parseAndValidate(value);
}
+
+ return () => {
+ // oof, maybe I can put the jotai atoms into a context?
+ setRollResults([]);
+ setTableHash(null);
+ setTableMetadata([]);
+ };
}, []); // eslint-disable-line react-hooks/exhaustive-deps
return (
diff --git a/apps/web/src/features/routing/root/layout.tsx b/apps/web/src/features/routing/root/layout.tsx
index 0c133e7..2f0cf75 100644
--- a/apps/web/src/features/routing/root/layout.tsx
+++ b/apps/web/src/features/routing/root/layout.tsx
@@ -55,12 +55,25 @@ export function RootLayout() {
{
+ onCreateTable={async () => {
closeCommandPalette();
/**
* @NOTE: Give the dialog a chance to close before navigating so that
* `autoFocus` works as expected on the subsequent page.
+ *
+ * This raises a warning in the console related to
+ * `@radix-ui/react-dialog` calling `hideOthers` from the
+ * `aria-hidden` package which sets `aria-hidden` on the body element.
+ *
+ * > Blocked aria-hidden on an element because its descendant retained
+ * > focus. The focus must not be hidden from assistive technology
+ * > users. Avoid using aria-hidden on a focused element or its
+ * > ancestor. Consider using the inert attribute instead, which will
+ * > also prevent focus.
+ *
+ * That package supports `inert`, but it hasn't been adopted by Radix
+ * as of right now.
*/
requestAnimationFrame(() => {
navigate("/table/new");
diff --git a/apps/web/src/features/table/components/table-create-form/index.tsx b/apps/web/src/features/table/components/table-create-form/index.tsx
index ac2f323..6872c9c 100644
--- a/apps/web/src/features/table/components/table-create-form/index.tsx
+++ b/apps/web/src/features/table/components/table-create-form/index.tsx
@@ -1,3 +1,4 @@
+import type { TableModel } from "@manifold/db/schema/table";
import {
Form,
FormControl,
@@ -20,7 +21,7 @@ type FormData = z.infer;
export function TableCreateForm({
onCreate,
}: {
- onCreate: (id: string) => void;
+ onCreate: (table: TableModel) => void;
}) {
const form = useZodForm({
schema: tableCreateInput,
@@ -34,7 +35,7 @@ export function TableCreateForm({
const onSubmit: SubmitHandler = async (data) => {
const table = await createTableMutation.mutateAsync(data);
- onCreate(table.id);
+ onCreate(table);
};
return (
diff --git a/apps/web/src/features/table/components/table-update-form/index.tsx b/apps/web/src/features/table/components/table-update-form/index.tsx
index 6e7dd5a..ba83740 100644
--- a/apps/web/src/features/table/components/table-update-form/index.tsx
+++ b/apps/web/src/features/table/components/table-update-form/index.tsx
@@ -1,3 +1,5 @@
+import type { TableModel } from "@manifold/db/schema/table";
+import { FlexCol } from "@manifold/ui/components/ui/flex";
import {
Form,
FormControl,
@@ -19,15 +21,13 @@ import { Header } from "./header";
type FormData = z.infer;
export function TableUpdateForm({
- id,
- title,
- initialDefinition,
+ table,
onUpdate,
+ isDisabled = false,
}: {
- id: string;
- title: string;
- initialDefinition: string;
+ table: TableModel;
onUpdate?: (id: string) => void | Promise;
+ isDisabled?: boolean;
}) {
const form = useZodForm({
mode: "onChange",
@@ -55,16 +55,19 @@ export function TableUpdateForm({
}),
}),
defaultValues: {
- id,
- definition: initialDefinition,
+ id: table.id,
+ definition: table.definition,
},
});
const updateTableMutation = trpc.table.update.useMutation();
useEffect(() => {
- form.reset({ id, definition: initialDefinition });
- }, [form, id, initialDefinition]);
+ form.reset({
+ id: table.id,
+ definition: table.definition,
+ });
+ }, [form, table.id, table.definition]);
const handleSubmit: SubmitHandler = async (data) => {
try {
@@ -88,42 +91,45 @@ export function TableUpdateForm({
return (
+
);
}
diff --git a/apps/web/src/features/table/pages/edit/page.tsx b/apps/web/src/features/table/pages/edit/page.tsx
index 9efc2c8..9d19856 100644
--- a/apps/web/src/features/table/pages/edit/page.tsx
+++ b/apps/web/src/features/table/pages/edit/page.tsx
@@ -1,4 +1,6 @@
-import { useParams } from "react-router-dom";
+import { LoadingIndicator } from "@manifold/ui/components/loading-indicator";
+import { FlexCol } from "@manifold/ui/components/ui/flex";
+import { useLocation, useParams } from "react-router-dom";
import { TableUpdateForm } from "~features/table/components/table-update-form";
import { RoutingError } from "~utils/errors";
@@ -6,35 +8,43 @@ import { trpc } from "~utils/trpc";
export function TableEdit() {
const { id } = useParams();
+ const location = useLocation();
if (!id) {
throw new RoutingError("No ID provided");
}
- const query = trpc.table.get.useQuery(id);
+ const query = trpc.table.get.useQuery(id, {
+ placeholderData: location.state?.table,
+ });
+
const trpcUtils = trpc.useUtils();
if (query.isLoading) {
- return Loading...
;
+ // @TODO: replace with skeleton
+ return (
+
+
+
+ );
}
if (query.isSuccess && query.data) {
const table = query.data;
return (
-
+
Promise.all([
- trpcUtils.table.list.invalidate(),
- trpcUtils.table.get.invalidate(id),
+ trpcUtils.table.list.refetch(),
+ trpcUtils.table.get.refetch(id),
])
}
/>
-
+
);
}
diff --git a/apps/web/src/features/table/pages/new/page.tsx b/apps/web/src/features/table/pages/new/page.tsx
index 6459b2a..22284a8 100644
--- a/apps/web/src/features/table/pages/new/page.tsx
+++ b/apps/web/src/features/table/pages/new/page.tsx
@@ -19,7 +19,11 @@ export function TableNew() {
- navigate(`/table/${id}/edit`)} />
+
+ navigate(`/table/${table.id}/edit`, { state: { table } })
+ }
+ />
diff --git a/apps/web/src/utils/trpc.ts b/apps/web/src/utils/trpc.ts
index 0cd1c4e..35d4a62 100644
--- a/apps/web/src/utils/trpc.ts
+++ b/apps/web/src/utils/trpc.ts
@@ -1,6 +1,7 @@
import type { AppRouter } from "@manifold/router";
import { httpBatchLink } from "@trpc/client";
import { createTRPCReact } from "@trpc/react-query";
+import superjson from "superjson";
/**
* This type annotation feels unnecessary, but `tsc` chokes without it.
@@ -12,6 +13,7 @@ export const trpc: ReturnType