Skip to content

Commit

Permalink
Merge pull request #312 from gnosisguild/app-post-members
Browse files Browse the repository at this point in the history
allow posting members as part of role updates
  • Loading branch information
jfschwarz authored Jan 13, 2025
2 parents 9ed3140 + 6337336 commit 1c34598
Show file tree
Hide file tree
Showing 28 changed files with 432 additions and 223 deletions.
Original file line number Diff line number Diff line change
@@ -1,8 +1,3 @@
.main {
border: 1px solid var(--border-color);
padding: var(--spacing-1);
}

.hash {
width: 150px;
overflow: hidden;
Expand Down
58 changes: 18 additions & 40 deletions packages/app/app/[mod]/roles/[role]/diff/[hash]/page.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
import { Annotation, Clearance, Target, fetchRolesMod } from "zodiac-roles-sdk"
import { fetchRolesMod } from "zodiac-roles-sdk"
import { notFound } from "next/navigation"
import { kv } from "@vercel/kv"

import Layout from "@/components/Layout"
import { parseModParam, parseRoleParam } from "@/app/params"
import PermissionsDiff from "@/components/permissions/PermissionsDiff"
import PageBreadcrumbs from "./breadcrumbs"
import styles from "./page.module.css"
import Flex from "@/ui/Flex"
import ApplyUpdates from "@/components/ApplyUpdate"
import AnnotationsToggle from "@/components/AnnotationsToggle"
import { fetchOrInitRole } from "../../fetching"
import { PermissionsPost } from "@/app/api/permissions/types"
import DiffView from "@/components/DiffView"

export default async function DiffPage({
params,
Expand All @@ -26,27 +27,17 @@ export default async function DiffPage({
}

const roleData = await fetchOrInitRole({ ...mod, roleKey })
const roleTargets = roleData.targets.filter(
(target) => !isEmptyFunctionScoped(target)
)

const entry = await kv.get<{
targets: Target[]
annotations: Annotation[]
}>(params.hash)
if (!entry) {
const post = await kv.get<PermissionsPost>(params.hash)
if (!post) {
notFound()
}
const entryTargets = entry.targets.filter(
(target) => !isEmptyFunctionScoped(target)
)

const hasAnnotations =
roleData.annotations.length > 0 || entry.annotations.length > 0
const shallShowAnnotations = searchParams.annotations !== "false"
roleData.annotations.length > 0 ||
(post.annotations && post.annotations.length > 0)

const roleAnnotations = shallShowAnnotations ? roleData.annotations : []
const entryAnnotations = shallShowAnnotations ? entry.annotations : []
const showAnnotations = searchParams.annotations !== "false"

const modInfo = await fetchRolesMod(mod, { next: { revalidate: 1 } })
if (!modInfo) {
Expand All @@ -55,37 +46,24 @@ export default async function DiffPage({

return (
<Layout head={<PageBreadcrumbs {...params} mod={mod} />}>
{hasAnnotations && (
<Flex
direction="row"
gap={1}
justifyContent="end"
className={styles.toolbar}
>
<AnnotationsToggle on={shallShowAnnotations} />
</Flex>
)}
<main className={styles.main}>
<Flex direction="column" gap={1}>
<PermissionsDiff
left={{ targets: roleTargets, annotations: roleAnnotations }}
right={{ targets: entryTargets, annotations: entryAnnotations }}
<main>
<Flex direction="column" gap={3}>
<DiffView
left={roleData}
right={post}
chainId={mod.chainId}
showAnnotations={showAnnotations}
/>
<ApplyUpdates
{...mod}
role={params.role}
role={roleData}
owner={modInfo.owner}
targets={entryTargets}
annotations={entryAnnotations}
currentTargets={roleTargets}
currentAnnotations={roleAnnotations}
targets={post.targets}
annotations={post.annotations}
members={post.members}
/>
</Flex>
</main>
</Layout>
)
}

const isEmptyFunctionScoped = (target: Target) =>
target.clearance === Clearance.Function && target.functions.length === 0
26 changes: 11 additions & 15 deletions packages/app/app/api/permissions/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,32 +2,28 @@ import { NextResponse } from "next/server"
import { checkIntegrity } from "zodiac-roles-sdk"
import { kv } from "@vercel/kv"
import { createHash } from "crypto"
import { z } from "zod"
import { zAnnotation, zTarget } from "@/components/permissions/schema"
import { PermissionsPost, zPermissionsPost } from "./types"

export async function POST(req: Request) {
const json = await req.json()

const zParams = z.object({
targets: z.array(zTarget),
annotations: z.array(zAnnotation),
})

let validated: z.infer<typeof zParams>
let validated: PermissionsPost
try {
validated = zParams.parse(json)
validated = zPermissionsPost.parse(json)
} catch (e) {
return NextResponse.json({
error: "Json is invalid",
})
}

try {
checkIntegrity(validated.targets)
} catch (e) {
return NextResponse.json({
error: "Targets integrity check failed",
})
if (validated.targets) {
try {
checkIntegrity(validated.targets)
} catch (e) {
return NextResponse.json({
error: "Targets integrity check failed",
})
}
}

const stringValue = JSON.stringify(validated)
Expand Down
15 changes: 15 additions & 0 deletions packages/app/app/api/permissions/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { zAddress, zAnnotation, zTarget } from "@/components/permissions/schema"
import { z } from "zod"
import { Annotation, Target } from "zodiac-roles-sdk"

export const zPermissionsPost = z.object({
targets: z.array(zTarget).optional(),
annotations: z.array(zAnnotation).optional(),
members: z.array(zAddress).optional(),
})

export interface PermissionsPost {
targets?: Target[]
annotations?: Annotation[]
members?: `0x${string}`[]
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,3 @@
.main {
border: 1px solid var(--border-color);
padding: var(--spacing-1);
}

.hash {
width: 150px;
overflow: hidden;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,11 @@
import { Annotation, Clearance, Target } from "zodiac-roles-sdk"
import { notFound } from "next/navigation"
import { kv } from "@vercel/kv"

import Layout from "@/components/Layout"
import PermissionsDiff from "@/components/permissions/PermissionsDiff"
import PageBreadcrumbs from "./breadcrumbs"
import styles from "./page.module.css"
import { CHAINS } from "@/app/chains"
import AnnotationsToggle from "@/components/AnnotationsToggle"
import Flex from "@/ui/Flex"
import { PermissionsPost } from "@/app/api/permissions/types"
import DiffView from "@/components/DiffView"

const chains = Object.values(CHAINS)

Expand All @@ -22,62 +19,33 @@ export default async function DiffPage({
const chainId = chains.find(
(c) => c.prefix === params.chain.toLowerCase()
)?.id

if (!chainId) {
notFound()
}

const left = await kv.get<{
targets: Target[]
annotations: Annotation[]
}>(params.hash)
const left = await kv.get<PermissionsPost>(params.hash)
if (!left) {
notFound()
}

const right = await kv.get<{
targets: Target[]
annotations: Annotation[]
}>(params.hashRight)
const right = await kv.get<PermissionsPost>(params.hashRight)
if (!right) {
notFound()
}

const hasAnnotations =
left.annotations.length > 0 || right.annotations.length > 0
const shallShowAnnotations = searchParams.annotations !== "false"
const showAnnotations = searchParams.annotations !== "false"

return (
<Layout head={<PageBreadcrumbs {...params} />}>
{hasAnnotations && (
<Flex
direction="row"
gap={1}
justifyContent="end"
className={styles.toolbar}
>
<AnnotationsToggle on={shallShowAnnotations} />
</Flex>
)}
<main className={styles.main}>
<PermissionsDiff
left={{
targets: left.targets.filter(
(target) => !isEmptyFunctionScoped(target)
),
annotations: shallShowAnnotations ? left.annotations : [],
}}
right={{
targets: right.targets.filter(
(target) => !isEmptyFunctionScoped(target)
),
annotations: shallShowAnnotations ? right.annotations : [],
}}
<main>
<DiffView
left={left}
right={right}
chainId={chainId}
showAnnotations={showAnnotations}
/>
</main>
</Layout>
)
}

const isEmptyFunctionScoped = (target: Target) =>
target.clearance === Clearance.Function && target.functions.length === 0
Loading

0 comments on commit 1c34598

Please sign in to comment.