This commit is contained in:
Frank
2025-10-08 18:59:41 -04:00
parent d18b6673e6
commit 5b1fd7e539
7 changed files with 79 additions and 72 deletions

View File

@@ -74,6 +74,7 @@ export const getActor = async (workspace?: string): Promise<Actor.Info> => {
userID: user.id,
workspaceID: user.workspaceID,
accountID: user.accountID,
role: user.role,
},
}
}

View File

@@ -48,10 +48,12 @@ export default function () {
<div data-slot="sections">
<NewUserSection />
<KeySection />
<Show when={isBeta()}>
<MemberSection />
</Show>
<Show when={userInfo()?.isAdmin}>
<Show when={isBeta()}>
<SettingsSection />
<MemberSection />
<ModelSection />
<ProviderSection />
</Show>

View File

@@ -7,11 +7,6 @@ import { createStore } from "solid-js/store"
import { formatDateUTC, formatDateForTable } from "./common"
import styles from "./key-section.module.css"
import { Actor } from "@opencode-ai/console-core/actor.js"
import { and, Database, eq, isNull, sql } from "@opencode-ai/console-core/drizzle/index.js"
import { KeyTable } from "@opencode-ai/console-core/schema/key.sql.js"
import { UserTable } from "@opencode-ai/console-core/schema/user.sql.js"
import { AccountTable } from "@opencode-ai/console-core/schema/account.sql.js"
import { User } from "@opencode-ai/console-core/user.js"
const removeKey = action(async (form: FormData) => {
"use server"

View File

@@ -10,10 +10,10 @@ import { User } from "@opencode-ai/console-core/user.js"
const listMembers = query(async (workspaceID: string) => {
"use server"
return withActor(async () => {
const actor = Actor.assert("user")
return {
members: await User.list(),
currentUserID: actor.properties.userID,
actorID: Actor.userID(),
actorRole: Actor.userRole(),
}
}, workspaceID)
}, "member.list")
@@ -158,10 +158,11 @@ export function MemberCreateForm() {
)
}
function MemberRow(props: { member: any; workspaceID: string; currentUserID: string | null }) {
function MemberRow(props: { member: any; workspaceID: string; actorID: string; actorRole: string }) {
const [editing, setEditing] = createSignal(false)
const submission = useSubmission(updateMember)
const isCurrentUser = () => props.currentUserID === props.member.id
const isCurrentUser = () => props.actorID === props.member.id
const isAdmin = () => props.actorRole === "admin"
createEffect(() => {
if (!submission.pending && submission.result && !submission.result.error) {
@@ -200,19 +201,19 @@ function MemberRow(props: { member: any; workspaceID: string; currentUserID: str
<td data-slot="member-email">{props.member.accountEmail ?? props.member.email}</td>
<td data-slot="member-role">{props.member.role}</td>
<td data-slot="member-usage">{getUsageDisplay()}</td>
<Show when={!props.member.timeSeen} fallback={<td data-slot="member-joined"></td>}>
<td data-slot="member-joined">invited</td>
</Show>
<td data-slot="member-joined">{props.member.timeSeen ? "" : "invited"}</td>
<td data-slot="member-actions">
<button data-color="ghost" onClick={() => setEditing(true)}>
Edit
</button>
<Show when={!isCurrentUser()}>
<form action={removeMember} method="post">
<input type="hidden" name="id" value={props.member.id} />
<input type="hidden" name="workspaceID" value={props.workspaceID} />
<button data-color="ghost">Delete</button>
</form>
<Show when={isAdmin()}>
<button data-color="ghost" onClick={() => setEditing(true)}>
Edit
</button>
<Show when={!isCurrentUser()}>
<form action={removeMember} method="post">
<input type="hidden" name="id" value={props.member.id} />
<input type="hidden" name="workspaceID" value={props.workspaceID} />
<button data-color="ghost">Delete</button>
</form>
</Show>
</Show>
</td>
</tr>
@@ -293,37 +294,34 @@ export function MemberSection() {
<section class={styles.root}>
<div data-slot="section-title">
<h2>Members</h2>
<p>Manage your members for accessing opencode services.</p>
</div>
<MemberCreateForm />
<Show when={data()?.actorRole === "admin"}>
<MemberCreateForm />
</Show>
<div data-slot="members-table">
<Show
when={data()?.members.length}
fallback={
<div data-component="empty-state">
<p>Invite a member to your workspace</p>
</div>
}
>
<table data-slot="members-table-element">
<thead>
<tr>
<th>Email</th>
<th>Role</th>
<th>Usage</th>
<th></th>
<th></th>
</tr>
</thead>
<tbody>
<For each={data()!.members}>
{(member) => (
<MemberRow member={member} workspaceID={params.id} currentUserID={data()!.currentUserID} />
)}
</For>
</tbody>
</table>
</Show>
<table data-slot="members-table-element">
<thead>
<tr>
<th>Email</th>
<th>Role</th>
<th>Usage</th>
<th></th>
<th></th>
</tr>
</thead>
<tbody>
<For each={data()?.members || []}>
{(member) => (
<MemberRow
member={member}
workspaceID={params.id}
actorID={data()!.actorID}
actorRole={data()!.actorRole}
/>
)}
</For>
</tbody>
</table>
</div>
</section>
)