Skip to content

Commit

Permalink
Native mode (#304)
Browse files Browse the repository at this point in the history
* Native mode (#308)

* (nonce) ensure incrby does not remove ttl (#303)

* Console refresh (#301)

* wip on new console

Signed-off-by: Aaron Sutula <asutula@users.noreply.github.com>

* better layout for console and data table

Signed-off-by: Aaron Sutula <asutula@users.noreply.github.com>

* more query validation, multiple statement support

Signed-off-by: Aaron Sutula <asutula@users.noreply.github.com>

* remove old files

Signed-off-by: Aaron Sutula <asutula@users.noreply.github.com>

* remove old code editor and deps

Signed-off-by: Aaron Sutula <asutula@users.noreply.github.com>

* layout fix

Signed-off-by: Aaron Sutula <asutula@users.noreply.github.com>

* working tabs

Signed-off-by: Aaron Sutula <asutula@users.noreply.github.com>

* support esc key to cancel edit tab name

Signed-off-by: Aaron Sutula <asutula@users.noreply.github.com>

* persisted tab data

Signed-off-by: Aaron Sutula <asutula@users.noreply.github.com>

* shared wallet status component and supporting changes

Signed-off-by: Aaron Sutula <asutula@users.noreply.github.com>

* little css cleanup

Signed-off-by: Aaron Sutula <asutula@users.noreply.github.com>

* store tab data per project

Signed-off-by: Aaron Sutula <asutula@users.noreply.github.com>

* combining conditional logic

Signed-off-by: Aaron Sutula <asutula@users.noreply.github.com>

---------

Signed-off-by: Aaron Sutula <asutula@users.noreply.github.com>
Co-authored-by: Aaron Sutula <asutula@users.noreply.github.com>

* native mode as project setting, scope tab results to env

Signed-off-by: Aaron Sutula <asutula@users.noreply.github.com>

* support native mode in studio aliases

Signed-off-by: Aaron Sutula <asutula@users.noreply.github.com>

* cli fix

Signed-off-by: Aaron Sutula <asutula@users.noreply.github.com>

* add native_mode columns to cli tests

Signed-off-by: Aaron Sutula <asutula@users.noreply.github.com>

---------

Signed-off-by: Aaron Sutula <asutula@users.noreply.github.com>
Co-authored-by: Joe Wagner <joewagner@users.noreply.github.com>
Co-authored-by: Aaron Sutula <asutula@users.noreply.github.com>

* try out trpc utils invalidate

Signed-off-by: Aaron Sutula <asutula@users.noreply.github.com>

* fix missing nativeMode form value

Signed-off-by: Aaron Sutula <asutula@users.noreply.github.com>

---------

Signed-off-by: Aaron Sutula <asutula@users.noreply.github.com>
Co-authored-by: Aaron Sutula <528969+asutula@users.noreply.github.com>
Co-authored-by: Aaron Sutula <asutula@users.noreply.github.com>
  • Loading branch information
3 people authored Aug 12, 2024
1 parent 3d7a475 commit 9ce02e6
Show file tree
Hide file tree
Showing 17 changed files with 672 additions and 20 deletions.
2 changes: 2 additions & 0 deletions packages/api/src/routers/projects.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ export function projectsRouter(store: Store) {
ctx.orgId,
input.name,
input.description,
input.nativeMode,
input.envNames.map((env) => env.name),
);
return project;
Expand All @@ -101,6 +102,7 @@ export function projectsRouter(store: Store) {
input.projectId,
input.name,
input.description,
input.nativeMode,
);
} catch (err) {
throw internalError("Error updating project", err);
Expand Down
1 change: 1 addition & 0 deletions packages/cli/src/commands/project.ts
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@ export const builder = function (args: Yargs) {
orgId,
name,
description,
nativeMode: false,
// TODO: Allow user to specify env names
envNames: [{ name: "default" }],
});
Expand Down
1 change: 1 addition & 0 deletions packages/cli/test/sql/setup_studio_test_tables.sql
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ CREATE TABLE `projects` (
`name` text NOT NULL,
`slug` text NOT NULL,
`description` text NOT NULL,
`native_mode` integer,
`created_at` text,
`updated_at` text
);
Expand Down
5 changes: 5 additions & 0 deletions packages/client/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,11 @@ type API = ReturnType<typeof api>;
// TODO: there is currently no concept of an environment for a user
function studioAliases({
environmentId,
nativeMode,
apiUrl,
}: {
environmentId: string;
nativeMode?: boolean;
apiUrl?: string;
}): helpers.AliasesNameMap {
const studioApi = api({
Expand All @@ -65,6 +67,9 @@ function studioAliases({
_map = {};
res.forEach(function (dep) {
_map[dep.def.name] = dep.deployment.tableName;
if (nativeMode) {
_map[dep.deployment.tableName] = dep.deployment.tableName;
}
});
};

Expand Down
4 changes: 4 additions & 0 deletions packages/store/src/api/projects.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ export function initProjects(
orgId: string,
name: string,
description: string,
nativeMode: boolean,
envNames: string[],
) {
const projectId = randomUUID();
Expand All @@ -53,6 +54,7 @@ export function initProjects(
name,
description,
slug,
nativeMode: nativeMode ? 1 : 0,
createdAt: now,
updatedAt: now,
};
Expand Down Expand Up @@ -88,6 +90,7 @@ export function initProjects(
projectId: string,
name?: string,
description?: string,
nativeMode?: boolean,
) {
const now = new Date().toISOString();
const slug = name ? slugify(name) : undefined;
Expand All @@ -97,6 +100,7 @@ export function initProjects(
name,
slug,
description,
nativeMode: nativeMode === undefined ? undefined : nativeMode ? 1 : 0,
updatedAt: now,
})
.where(eq(projects.id, projectId))
Expand Down
1 change: 1 addition & 0 deletions packages/store/src/schema/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ export const projects = sqliteTable("projects", {
name: text("name").notNull(),
slug: text("slug").notNull(),
description: text("description").notNull(),
nativeMode: integer("native_mode"),
createdAt: text("created_at"),
updatedAt: text("updated_at"),
});
Expand Down
2 changes: 2 additions & 0 deletions packages/validators/src/validators/projects.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ export const projectNameAvailableSchema = z.object({
export const newProjectSchema = z.object({
name: projectNameSchema,
description: projectDescriptionSchema,
nativeMode: z.boolean(),
envNames: z
.array(envNameSchema)
.min(1)
Expand All @@ -33,4 +34,5 @@ export const newProjectSchema = z.object({
export const updateProjectSchema = z.object({
name: projectNameSchema.optional(),
description: projectDescriptionSchema.optional(),
nativeMode: z.boolean().optional(),
});
3 changes: 2 additions & 1 deletion packages/web/app/[org]/[project]/[env]/console/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,9 @@ export default async function ConsolePage({
<ConsoleTabs
auth={session.auth}
projectId={project.id}
nativeMode={!!project.nativeMode}
environmentId={environment.id}
defs={deployments.map((d) => d.def)}
deployments={deployments}
/>
</main>
);
Expand Down
5 changes: 5 additions & 0 deletions packages/web/app/[org]/[project]/_components/sidebar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,11 @@ export function Sidebar() {
key={def.id}
icon={Table2}
title={def.name}
subtitle={
projectQuery.data.nativeMode && deployment
? deployment.tableName
: undefined
}
href={`/${orgQuery.data.slug}/${projectQuery.data.slug}/${linkEnv.slug}/${def.slug}`}
selected={def.id === defQuery.data?.id}
showIndicator={!!env && !deployment && !!isAuthorizedQuery.data}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import {
import InputWithCheck from "@/components/input-with-check";
import { api } from "@/trpc/react";
import { Textarea } from "@/components/ui/textarea";
import { Switch } from "@/components/ui/switch";

export default function EditProject({
org,
Expand All @@ -39,6 +40,7 @@ export default function EditProject({
defaultValues: {
name: project.name,
description: project.description,
nativeMode: !!project.nativeMode,
},
});

Expand All @@ -52,10 +54,17 @@ export default function EditProject({
: skipToken,
{ retry: false },
);

const utils = api.useUtils();

const updateProject = api.projects.updateProject.useMutation({
onSuccess: (project) => {
router.refresh();
router.replace(`/${org.slug}/${project.slug}/settings`);
router.refresh();
void utils.projects.projectBySlug.invalidate({
slug: project.slug,
orgId: org.id,
});
},
});

Expand All @@ -66,6 +75,9 @@ export default function EditProject({
description: form.formState.dirtyFields.description
? values.description
: undefined,
nativeMode: form.formState.dirtyFields.nativeMode
? values.nativeMode
: undefined,
});
};

Expand Down Expand Up @@ -124,6 +136,31 @@ export default function EditProject({
</FormItem>
)}
/>
<FormField
control={form.control}
name="nativeMode"
render={({ field: { value, onChange, ...field } }) => (
<FormItem className="">
<FormLabel>Native Mode</FormLabel>
<FormControl>
<Switch
className="block"
disabled={disabled || updateProject.isPending}
checked={value}
onCheckedChange={onChange}
{...field}
/>
</FormControl>
<FormDescription>
Native mode will display native Tableland table names in your
project&apos;s left hand panel for any definitions that have
been deployed, and allow you to use those table names in your
Console queries.
</FormDescription>
<FormMessage />
</FormItem>
)}
/>
<div className="flex gap-4">
<Button
variant="secondary"
Expand Down
35 changes: 24 additions & 11 deletions packages/web/components/console-tabs.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
"use client";

import { type schema } from "@tableland/studio-store";
import { Plus, X } from "lucide-react";
import { type Result } from "@tableland/sdk";
import { useAtom } from "jotai";
import { atomWithStorage } from "jotai/utils";
import { type Auth } from "@tableland/studio-api";
import { type RouterOutputs, type Auth } from "@tableland/studio-api";
import { useRef } from "react";
import { Tabs, TabsContent, TabsList, TabsTrigger } from "./ui/tabs";
import { Console } from "./console";
Expand All @@ -19,34 +18,43 @@ interface Tab {
name: string;
selected: boolean;
query: string;
result?: Result<Record<string, unknown>>;
// This is optional because a previous version stored
// a single result for all environments under the key
// "result". This update stores results per environment.
results?: Record<string, Result<Record<string, unknown>> | undefined>;
editingName: boolean;
newName: string;
}

export default function ConsoleTabs({
auth,
projectId,
nativeMode,
environmentId,
defs,
deployments,
}: {
auth?: Auth;
projectId: string;
nativeMode: boolean;
environmentId: string;
defs: schema.Def[];
deployments: RouterOutputs["deployments"]["deploymentsByEnvironmentId"];
}) {
const address = useAccount();

const tabsStorageKey = nativeMode
? `env_tabs_${environmentId}`
: `project_tabs_${projectId}`;

const tabsAtom = useRef(
atomWithStorage<Tab[]>(
`env_tabs_${projectId}`,
tabsStorageKey,
[
{
id: window.self.crypto.randomUUID(),
name: "New Query",
selected: true,
query: "",
result: undefined,
results: {},
editingName: false,
newName: "",
},
Expand All @@ -67,7 +75,7 @@ export default function ConsoleTabs({
name: "New Query",
selected: true,
query: "",
result: undefined,
results: {},
editingName: false,
newName: "",
},
Expand Down Expand Up @@ -138,7 +146,11 @@ export default function ConsoleTabs({
result: Result<Record<string, unknown>> | undefined,
) => {
setTabs((tabs) =>
tabs.map((t) => (t.id === tab.id ? { ...t, result } : t)),
tabs.map((t) =>
t.id === tab.id
? { ...t, results: { ...t.results, [environmentId]: result } }
: t,
),
);
};

Expand Down Expand Up @@ -223,10 +235,11 @@ export default function ConsoleTabs({
<Console
key={tab.id}
environmentId={environmentId}
defs={defs}
deployments={deployments}
nativeMode={nativeMode}
query={tab.query}
setQuery={(q) => setQuery(tab, q)}
res={tab.result}
res={tab.results ? tab.results[environmentId] : undefined}
setRes={(r) => setRes(tab, r)}
/>
</TabsContent>
Expand Down
27 changes: 21 additions & 6 deletions packages/web/components/console.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@ import { Database, type Result, helpers } from "@tableland/sdk";
import CodeMirror from "@uiw/react-codemirror";
import { SQLite, sql } from "@codemirror/lang-sql";
import { vscodeDark } from "@uiw/codemirror-theme-vscode";
import { type schema } from "@tableland/studio-store";
import { Loader2 } from "lucide-react";
import { getNetwork, switchNetwork } from "wagmi/actions";
import { type RouterOutputs } from "@tableland/studio-api";
import { DataTable } from "./data-table";
import { Button } from "./ui/button";
import { useToast } from "./ui/use-toast";
Expand All @@ -28,14 +28,16 @@ init().catch((err: any) => {

export function Console({
environmentId,
defs,
deployments,
nativeMode,
query,
setQuery,
res,
setRes,
}: {
environmentId: string;
defs: schema.Def[];
deployments: RouterOutputs["deployments"]["deploymentsByEnvironmentId"];
nativeMode: boolean;
query: string;
setQuery: (query: string) => void;
res: Result<Record<string, unknown>> | undefined;
Expand All @@ -45,9 +47,21 @@ export function Console({

const [pending, setPending] = useState(false);

const schema = defs.reduce<Record<string, string[]>>((acc, def) => {
return { ...acc, [def.name]: def.schema.columns.map((col) => col.name) };
}, {});
const schema = deployments.reduce<Record<string, string[]>>(
(acc, deployment) => {
const cols = deployment.def.schema.columns.map((col) => col.name);
const aliased = { [deployment.def.name]: cols };
const native = nativeMode
? { [deployment.deployment.tableName]: cols }
: {};
return {
...acc,
...aliased,
...native,
};
},
{},
);

const columns: Array<ColumnDef<unknown>> = useMemo(
() =>
Expand Down Expand Up @@ -91,6 +105,7 @@ export function Console({
const aliases = studioAliases({
environmentId,
apiUrl: getBaseUrl(),
nativeMode,
});
const nameMapping = await aliases.read();
const aliasMap = new Map(Object.entries(nameMapping));
Expand Down
1 change: 1 addition & 0 deletions packages/web/components/new-project-form.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ export default function NewProjectForm({
defaultValues: {
name: "",
description: "",
nativeMode: false,
envNames: [{ name: "default" }],
},
});
Expand Down
Loading

1 comment on commit 9ce02e6

@vercel
Copy link

@vercel vercel bot commented on 9ce02e6 Aug 12, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.