Skip to content

Commit

Permalink
Combined defs + tables + more (#271)
Browse files Browse the repository at this point in the history
* wip

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

* new folder structure, new/import tables buttons in sidebar

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

* lint fixes

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

* properly displaying deployed and undeployed tables, exec deployment working

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

* New team nav

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

* correct layout nesting

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

* move table desc to table wrapper

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

* one line description

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

* update/delete defs and deployments apis

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

* working ui for table settings

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

* working delete table and undeploy table

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

* prettier fix

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

* conditional show undeploy button

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

* remove update schema code

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

* hardcode default env into links for now

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

* project overview page

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

* lint fix

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

* revert unrelated wip

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

* only display deploy table in menu if authorized

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

* deploy status in def details

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

* conditionally display card content

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

* link to default env when using project links

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

* more default env band aid

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

* properly working table menu

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

* fix tooltips

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

* fix detection of mainnet testnet collision with hardhat

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

* update react-share to get rid of warnings

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

* sidebar border

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

* lint fix

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

* better header layout

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

* correct font for hash display

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

* center hashdisaply text

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

* correct sticky behavior for sidebar

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

* fix header z index

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

* breadcrumb nav working for unauthenticated and unautorized users

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

* new logo

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

* better styling on overview

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

* upgrade tsx

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

* display project description

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

* don't allow studio logo to shrink

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

* better base url resolution for vercel

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

* testing out baseurl resolution

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

* better use of vercel url env vars

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

* remove test display of baseurl

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

* remove use of nonempty()

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

* refactor def details display so it can be used for tableland table as well

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

* move new and import table buttons

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

* smaller share icons, x icon

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

* fewer words in share card

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

* better project name display in overview, table menu button moved left

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

* move project settings above tables in left nav

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

* address pr feedback

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>
  • Loading branch information
asutula and asutula authored May 28, 2024
1 parent c506920 commit e822052
Show file tree
Hide file tree
Showing 63 changed files with 2,187 additions and 1,333 deletions.
229 changes: 122 additions & 107 deletions package-lock.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@
"sinon": "^15.0.1",
"tailwindcss": "^3.3.2",
"ts-node": "^10.9.1",
"tsx": "^3.12.7",
"tsx": "^4.10.5",
"typescript": "^5.4.5"
}
}
38 changes: 36 additions & 2 deletions packages/api/src/routers/defs.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
import { type Store } from "@tableland/studio-store";
import { type schema, type Store } from "@tableland/studio-store";
import { TRPCError } from "@trpc/server";
import { z } from "zod";
import {
newDefApiSchema,
defNameAvailableSchema,
updateDefApiSchema,
} from "@tableland/studio-validators";
import { projectProcedure, publicProcedure, createTRPCRouter } from "../trpc";
import {
projectProcedure,
publicProcedure,
createTRPCRouter,
defAdminProcedure,
} from "../trpc";
import { internalError } from "../utils/internalError";

export function defsRouter(store: Store) {
Expand Down Expand Up @@ -55,5 +61,33 @@ export function defsRouter(store: Store) {
throw internalError("Error saving def record.", err);
}
}),
updateDef: defAdminProcedure(store)
.input(updateDefApiSchema)
.mutation(async ({ input }) => {
let def: schema.Def | undefined;
try {
def = await store.defs.updateDef(
input.defId,
input.name,
input.description,
);
} catch (err) {
throw internalError("Error updating def record.", err);
}
if (!def) {
throw new TRPCError({
code: "NOT_FOUND",
message: "Definition not found",
});
}
return def;
}),
deleteDef: defAdminProcedure(store).mutation(async ({ input }) => {
try {
await store.defs.deleteDef(input.defId);
} catch (err) {
throw internalError("Error deleting def record.", err);
}
}),
});
}
38 changes: 37 additions & 1 deletion packages/api/src/routers/deployments.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
import { type Store } from "@tableland/studio-store";
import { z } from "zod";
import { publicProcedure, createTRPCRouter, defProcedure } from "../trpc";
import { TRPCError } from "@trpc/server";
import {
publicProcedure,
createTRPCRouter,
defProcedure,
defAdminProcedure,
} from "../trpc";
import { internalError } from "../utils/internalError";

export function deploymentsRouter(store: Store) {
return createTRPCRouter({
Expand Down Expand Up @@ -30,6 +37,15 @@ export function deploymentsRouter(store: Store) {
});
return res;
}),
deleteDeployments: defAdminProcedure(store)
.input(z.object({ envId: z.string().trim().uuid().optional() }))
.mutation(async ({ input }) => {
try {
await store.deployments.deleteDeployments(input.defId, input.envId);
} catch (err) {
throw internalError("error deleting deployment", err);
}
}),
deploymentsByDefId: publicProcedure
.input(
z.object({
Expand All @@ -55,6 +71,26 @@ export function deploymentsRouter(store: Store) {
input.environmentId,
);
}),
deploymentByEnvAndDefId: publicProcedure
.input(
z.object({
envId: z.string().trim().min(1),
defId: z.string().trim().min(1),
}),
)
.query(async ({ input }) => {
const res = await store.deployments.deploymentByEnvAndDefId(
input.envId,
input.defId,
);
if (!res) {
throw new TRPCError({
code: "NOT_FOUND",
message: "Deployment not found",
});
}
return res;
}),
deploymentReferences: publicProcedure
.input(
z.object({
Expand Down
21 changes: 21 additions & 0 deletions packages/api/src/routers/environments.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { type Store } from "@tableland/studio-store";
import { z } from "zod";
import { TRPCError } from "@trpc/server";
import { projectProcedure, publicProcedure, createTRPCRouter } from "../trpc";

export function environmentsRouter(store: Store) {
Expand All @@ -24,5 +25,25 @@ export function environmentsRouter(store: Store) {
});
return environment;
}),
environmentBySlug: publicProcedure
.input(
z.object({
projectId: z.string().trim().min(1),
slug: z.string().trim().min(1),
}),
)
.query(async ({ input }) => {
const env = await store.environments.environmentBySlug(
input.projectId,
input.slug,
);
if (!env) {
throw new TRPCError({
code: "NOT_FOUND",
message: "Environment not found",
});
}
return env;
}),
});
}
11 changes: 11 additions & 0 deletions packages/api/src/trpc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -308,3 +308,14 @@ export const defProcedure = (store: Store) =>
ctx: { ...ctx, session: ctx.session, teamAuthorization: membership },
});
});

export const defAdminProcedure = (store: Store) =>
defProcedure(store).use(async ({ ctx, next }) => {
if (!ctx.teamAuthorization.isOwner) {
throw new TRPCError({
code: "UNAUTHORIZED",
message: "not authorized as def admin",
});
}
return await next({ ctx });
});
11 changes: 10 additions & 1 deletion packages/client/src/util.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,15 @@
export function getBaseUrl() {
if (typeof window !== "undefined") return "";
if (process.env.SITE_DOMAIN) return `https://${process.env.SITE_DOMAIN}`;
if (
process.env.NEXT_PUBLIC_VERCEL_ENV === "production" &&
process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL
)
return `https://${process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL}`;
if (
process.env.NEXT_PUBLIC_VERCEL_ENV === "preview" &&
process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL
)
return process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL;
return "http://localhost:3000";
}

Expand Down
51 changes: 51 additions & 0 deletions packages/store/src/api/defs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ const projectDefs = schema.projectDefs;
const defs = schema.defs;
const teamProjects = schema.teamProjects;
const teams = schema.teams;
const deployments = schema.deployments;

export function initDefs(db: DrizzleD1Database<typeof schema>, tbl: Database) {
return {
Expand Down Expand Up @@ -66,6 +67,56 @@ export function initDefs(db: DrizzleD1Database<typeof schema>, tbl: Database) {
return def;
},

updateDef: async function (
defId: string,
name?: string,
description?: string,
schema?: Schema,
) {
const now = new Date().toISOString();
const slug = name ? slugify(name) : undefined;
await db
.update(defs)
.set({
name,
slug,
description,
schema,
updatedAt: now,
})
.where(eq(defs.id, defId))
.execute();
return await db.select().from(defs).where(eq(defs.id, defId)).get();
},

deleteDef: async function (defId: string) {
// projectDefs
const { sql: projectDefsSql, params: projectDefsParams } = db
.delete(projectDefs)
.where(eq(projectDefs.defId, defId))
.toSQL();

// defs
const { sql: defsSql, params: defsParams } = db
.delete(defs)
.where(eq(defs.id, defId))
.toSQL();

// deployments
const { sql: deploymentsSql, params: deploymentsParams } = db
.delete(deployments)
.where(eq(deployments.defId, defId))
.toSQL();

const batch = [
tbl.prepare(projectDefsSql).bind(projectDefsParams),
tbl.prepare(defsSql).bind(defsParams),
tbl.prepare(deploymentsSql).bind(deploymentsParams),
];

await tbl.batch(batch);
},

defsByProjectId: async function (projectId: string) {
const res = await db
.select({ defs })
Expand Down
29 changes: 29 additions & 0 deletions packages/store/src/api/deployments.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,21 @@ export function initDeployments(db: DrizzleD1Database<typeof schema>) {
return deployment;
},

deleteDeployments: async function (defId: string, environmentId?: string) {
// deployments
await db
.delete(deployments)
.where(
and(
eq(deployments.defId, defId),
environmentId
? eq(deployments.environmentId, environmentId)
: undefined,
),
)
.execute();
},

deploymentsByDefId: async function (defId: string) {
const res = await db
.select()
Expand Down Expand Up @@ -75,6 +90,20 @@ export function initDeployments(db: DrizzleD1Database<typeof schema>) {
return res;
},

deploymentByEnvAndDefId: async function (envId: string, defId: string) {
const res = await db
.select()
.from(deployments)
.where(
and(
eq(deployments.environmentId, envId),
eq(deployments.defId, defId),
),
)
.get();
return res;
},

deploymentReferences: async function (chainId: number, tableId: string) {
const res = await db
.select({
Expand Down
15 changes: 14 additions & 1 deletion packages/store/src/api/environments.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { randomUUID } from "crypto";
import { type Database } from "@tableland/sdk";
import { eq } from "drizzle-orm";
import { eq, and } from "drizzle-orm";
import { type DrizzleD1Database } from "drizzle-orm/d1";
import * as schema from "../schema/index.js";
import { slugify } from "../helpers.js";
Expand Down Expand Up @@ -50,5 +50,18 @@ export function initEnvironments(
const res = await tbl.prepare(sql).bind(params).all();
return res.results as Environment[];
},

environmentBySlug: async function (projectId: string, slug: string) {
return await db
.select()
.from(environments)
.where(
and(
eq(environments.projectId, projectId),
eq(environments.slug, slug),
),
)
.get();
},
};
}
Loading

1 comment on commit e822052

@vercel
Copy link

@vercel vercel bot commented on e822052 May 28, 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.