+
-
-
+
+
+ Comparing versions of{" "}
+
+
- {dependency.table?.description || "No table description"}
+ Compare versions of table {table.title}
-
-
- -
- Description
-
- -
- {dependency.table?.description || (
-
- No table description
-
- )}
-
-
- -
- Last updated
-
- -
- {dependency.createdAt.toLocaleDateString()}
-
-
- -
- Version
-
- -
- {dependency.version}
-
-
- -
- Release notes
-
- -
- {dependency.releaseNotes || (
- No release notes
- )}
-
- -
- Available Tables
-
- -
- {dependency.availableTables.map((tableId) => (
-
- {tableId}
-
- ))}
-
-
-
-
-
- {dependency.definition}
-
+
+
+
+
+
+
+
+
+ {!diff ? (
+
+ ) : (
+
+
+
+ Version {sourceVersion.version}
+
+
+ {sourceVersion.definition}
+
+
+
+
+
+ Version {targetVersion.version}
+
+
+ {diffElements}
+
+
+
+ )}
- {
- modal.hide();
- onAddDependency();
- }}
- disabled={!canAddDependency}
- >
- {canAddDependency
- ? "Add this dependency"
- : "Dependency already added"}
-
+
+
+
-
-
-
-
);
}
+
+function VersionSelect({
+ value,
+ onValueChange,
+ versions,
+ versionsMap,
+}: {
+ value: string;
+ onValueChange: (value: string) => void;
+ versions: RouterOutput["tableVersion"]["get"]["versions"];
+ versionsMap: Record<
+ string,
+ RouterOutput["tableVersion"]["get"]["versions"][number]
+ >;
+}) {
+ return (
+
+ );
+}
diff --git a/apps/web/src/features/table-version/pages/detail/index.ts b/apps/web/src/features/table-version/pages/detail/index.ts
index 294d1c5..9be3ac4 100644
--- a/apps/web/src/features/table-version/pages/detail/index.ts
+++ b/apps/web/src/features/table-version/pages/detail/index.ts
@@ -1,2 +1,3 @@
+export { TableVersionLayout } from "./layout";
export { loaderBuilder, type TableVersionDetailLoaderData } from "./loader";
export { TableVersionDetail } from "./page";
diff --git a/apps/web/src/features/table-version/pages/detail/layout.tsx b/apps/web/src/features/table-version/pages/detail/layout.tsx
new file mode 100644
index 0000000..fb05749
--- /dev/null
+++ b/apps/web/src/features/table-version/pages/detail/layout.tsx
@@ -0,0 +1,259 @@
+import { buildTableIdentifier } from "@manifold/lib";
+import type { RouterOutput } from "@manifold/router";
+import { FullScreenLoader } from "@manifold/ui/components/full-screen-loader";
+import { TableIdentifier } from "@manifold/ui/components/table-identifier";
+import { Button } from "@manifold/ui/components/ui/button";
+import { FlexCol } from "@manifold/ui/components/ui/flex";
+import {
+ Tooltip,
+ TooltipArrow,
+ TooltipContent,
+ TooltipTrigger,
+} from "@manifold/ui/components/ui/tooltip";
+import { transitionAlpha } from "@manifold/ui/lib/animation";
+import { AnimatePresence, motion } from "framer-motion";
+import {
+ GoArrowLeft,
+ GoChevronLeft,
+ GoChevronRight,
+ GoCopy,
+ GoDiff,
+ GoPackage,
+ GoPencil,
+} from "react-icons/go";
+import { Outlet, useLocation } from "react-router-dom";
+
+import { DialogManager, DIALOGS } from "~features/dialog-manager";
+import { useRequiredUserProfile } from "~features/onboarding/hooks/use-required-user-profile";
+import { PrefetchableLink } from "~features/routing/components/prefetchable-link";
+import { useRouteParams } from "~features/routing/hooks/use-route-params";
+import { tableVersionDetailParams } from "~features/table-version/pages/detail/params";
+import { trpc } from "~utils/trpc";
+
+export function TableVersionLayout() {
+ const location = useLocation();
+ const userProfile = useRequiredUserProfile();
+ const { username, slug, version } = useRouteParams(tableVersionDetailParams);
+ const tableVersion = trpc.tableVersion.get.useQuery({
+ tableIdentifier: buildTableIdentifier(username, slug),
+ version,
+ });
+
+ if (tableVersion.isLoading) {
+ // @TODO: better loading state
+ return
;
+ }
+
+ if (tableVersion.isError) {
+ // @TODO: better error state
+ return
Error: {tableVersion.error.message}
;
+ }
+
+ const direction =
+ location.state?.previousVersion !== undefined
+ ? location.state.previousVersion > version
+ ? "up"
+ : "down"
+ : location.state?.fromTable
+ ? "left"
+ : undefined;
+
+ const variants = {
+ exit: (direction: "left" | "up" | "down") => {
+ return {
+ left: { x: -12, opacity: 0 },
+ up: { y: "-100%", opacity: 0 },
+ down: { y: "100%", opacity: 0 },
+ }[direction];
+ },
+ enter: (direction: "left" | "up" | "down") => {
+ return {
+ left: { x: -12 },
+ up: { y: "100%" },
+ down: { y: "-100%" },
+ }[direction];
+ },
+ };
+
+ return (
+
+
+
+
+
+ );
+}
+
+function VersionNavigation({
+ version,
+}: {
+ version: RouterOutput["tableVersion"]["get"];
+}) {
+ const currentIndex = version.versions.findIndex(
+ (v) => v.version === version.version,
+ );
+ const totalVersions = version.versions.length;
+
+ // versions are in descending order by `version`, so these seem backwards
+ const hasNextVersion = currentIndex > 0;
+ const hasPreviousVersion = currentIndex < totalVersions - 1;
+
+ const PrevLinkComponent = hasPreviousVersion ? PrefetchableLink : "span";
+ const NextLinkComponent = hasNextVersion ? PrefetchableLink : "span";
+
+ return (
+ <>
+
+
+
+
+
+ Previous version
+
+
+
+
+
+
+
+
+
+ Next version
+
+
+
+ >
+ );
+}
diff --git a/apps/web/src/features/table-version/pages/detail/lazy.ts b/apps/web/src/features/table-version/pages/detail/lazy.ts
index 194bc47..9ef7883 100644
--- a/apps/web/src/features/table-version/pages/detail/lazy.ts
+++ b/apps/web/src/features/table-version/pages/detail/lazy.ts
@@ -4,13 +4,13 @@ import type { TrpcUtils } from "~utils/trpc";
export function loadTableVersionDetailRoute(trpcUtils: TrpcUtils): LazyRoute {
return async () => {
- const { TableVersionDetail, loaderBuilder } = await import(
+ const { TableVersionLayout, loaderBuilder } = await import(
"~features/table-version/pages/detail"
);
return {
loader: loaderBuilder(trpcUtils),
- Component: TableVersionDetail,
+ Component: TableVersionLayout,
handle: {
title: ({ data }) => `Manifold | ${data.title} v${data.version}`,
description: ({ data }) =>
diff --git a/apps/web/src/features/table-version/pages/detail/page.tsx b/apps/web/src/features/table-version/pages/detail/page.tsx
index 2584da4..5b4bcec 100644
--- a/apps/web/src/features/table-version/pages/detail/page.tsx
+++ b/apps/web/src/features/table-version/pages/detail/page.tsx
@@ -1,24 +1,12 @@
import { buildTableIdentifier } from "@manifold/lib";
-import type { RouterOutput } from "@manifold/router";
import { FullScreenLoader } from "@manifold/ui/components/full-screen-loader";
-import { TableIdentifier } from "@manifold/ui/components/table-identifier";
import { Badge } from "@manifold/ui/components/ui/badge";
import { Button } from "@manifold/ui/components/ui/button";
-import { FlexCol } from "@manifold/ui/components/ui/flex";
import { transitionAlpha } from "@manifold/ui/lib/animation";
import { cn } from "@manifold/ui/lib/utils";
import { motion } from "framer-motion";
-import {
- GoArrowLeft,
- GoArrowRight,
- GoChevronLeft,
- GoChevronRight,
- GoCopy,
- GoPackage,
- GoPencil,
-} from "react-icons/go";
+import { GoArrowRight } from "react-icons/go";
-import { useRequiredUserProfile } from "~features/onboarding/hooks/use-required-user-profile";
import { PrefetchableLink } from "~features/routing/components/prefetchable-link";
import { useRouteParams } from "~features/routing/hooks/use-route-params";
import { tableVersionDetailParams } from "~features/table-version/pages/detail/params";
@@ -27,7 +15,6 @@ import { trpc } from "~utils/trpc";
const COLLAPSED_AVAILABLE_TABLES_COUNT = 3;
export function TableVersionDetail() {
- const userProfile = useRequiredUserProfile();
const { username, slug, version } = useRouteParams(tableVersionDetailParams);
const tableVersion = trpc.tableVersion.get.useQuery({
tableIdentifier: buildTableIdentifier(username, slug),
@@ -45,149 +32,87 @@ export function TableVersionDetail() {
}
return (
-
-
-
-
-
- Table details
-
-
- -
- Last updated
-
- -
- {tableVersion.data.table.updatedAt.toLocaleDateString()}
-
-
- -
- Total versions
-
- -
- {tableVersion.data.versions.length}
-
-
- {tableVersion.data.versions.length > 0 ? (
- <>
- -
- Latest release notes
-
- -
- {tableVersion.data.versions[0].releaseNotes || (
- No release notes
- )}
-
- -
- Available Tables
-
- -
- {tableVersion.data.versions[0].availableTables.map(
- (tableId) => (
-
- {tableId}
-
- ),
- )}
-
- >
- ) : null}
-
+
- Definition
+ Definition
-
-
- {tableVersion.data.definition}
-
-
-
-
-
- return (
-
-
+
+ Versions
+
+
+ {tableVersion.data.versions.map((version) => {
+ const isCurrentVersion =
+ version.version === tableVersion.data.version;
+ const LinkComponent = isCurrentVersion ? "span" : PrefetchableLink;
+
+ return (
+ -
+
+ {isCurrentVersion ? (
+
+ ) : null}
+
+
@@ -198,7 +123,7 @@ export function TableVersionDetail() {
{version.createdAt.toLocaleDateString()}
{isCurrentVersion ? (
- Current
+ Current
) : null}
@@ -217,7 +142,7 @@ export function TableVersionDetail() {
.map((tableId) => (
{tableId}
@@ -242,71 +167,13 @@ export function TableVersionDetail() {
) : null}
-
-
- );
- })}
-
-
+
+
+
+ );
+ })}
+
-
- );
-}
-
-function VersionNavigation({
- version,
-}: {
- version: RouterOutput["tableVersion"]["get"];
-}) {
- const currentIndex = version.versions.findIndex(
- (v) => v.version === version.version,
- );
- const totalVersions = version.versions.length;
-
- // versions are in descending order by `version`, so these seem backwards
- const hasNextVersion = currentIndex > 0;
- const hasPreviousVersion = currentIndex < totalVersions - 1;
-
- const PrevLinkComponent = hasPreviousVersion ? PrefetchableLink : "span";
- const NextLinkComponent = hasNextVersion ? PrefetchableLink : "span";
-
- return (
- <>
-
-
-
- >
+
);
}
diff --git a/apps/web/src/features/table/components/table-update-form/publish-button.tsx b/apps/web/src/features/table/components/table-update-form/publish-button.tsx
index 56de4d7..2a24fed 100644
--- a/apps/web/src/features/table/components/table-update-form/publish-button.tsx
+++ b/apps/web/src/features/table/components/table-update-form/publish-button.tsx
@@ -9,7 +9,7 @@ import {
} from "@manifold/ui/components/ui/tooltip";
import { useStateGuard } from "@manifold/ui/hooks/use-state-guard";
import { useAtomValue } from "jotai";
-import { GoPackageDependents } from "react-icons/go";
+import { GoGitBranch } from "react-icons/go";
import { DialogManager, DIALOGS } from "~features/dialog-manager";
import { currentAllResolvedDependenciesAtom } from "~features/editor/components/editor/state";
@@ -76,11 +76,7 @@ export function PublishButton({
})
}
>
- {isPending ? (
-
- ) : (
-
- )}
+ {isPending ?
:
}
Publish{recentVersions.length > 0 ? " Version" : null}
diff --git a/apps/web/src/features/table/pages/detail/page.tsx b/apps/web/src/features/table/pages/detail/page.tsx
index 68b0bfb..55c5eb3 100644
--- a/apps/web/src/features/table/pages/detail/page.tsx
+++ b/apps/web/src/features/table/pages/detail/page.tsx
@@ -13,6 +13,8 @@ import { useRouteParams } from "~features/routing/hooks/use-route-params";
import { tableDetailParams } from "~features/table/pages/detail/params";
import { trpc } from "~utils/trpc";
+const COLLAPSED_AVAILABLE_TABLES_COUNT = 3;
+
export function TableDetail() {
const userProfile = useRequiredUserProfile();
const { username, slug } = useRouteParams(tableDetailParams);
@@ -70,7 +72,10 @@ export function TableDetail() {
{userProfile.userId === table.data.ownerId ? (