import { Everyone, JsonObject, LocalNode, RawAccount, RawCoValue, RawGroup, } from "cojson"; import { CoID } from "cojson"; import { useState } from "react"; import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow, } from "../ui/table.js"; import { AccountOrGroupText } from "./account-or-group-text.js"; import { RawDataCard } from "./raw-data-card.js"; import { PageInfo, isCoId } from "./types.js"; import { Button, Icon, Modal, Input, Select } from "../ui/index.js"; function partitionMembers(data: Record) { const everyone = Object.entries(data) .filter(([key]) => key === "everyone") .map(([key, value]) => ({ id: key as CoID, role: value as string, })); const members = Object.entries(data) .filter(([key]) => isCoId(key)) .map(([key, value]) => ({ id: key as CoID, role: value, })); const parentGroups = Object.entries(data) .filter(([key]) => key.startsWith("parent_co_")) .map(([key, value]) => ({ id: key.slice(7) as CoID, role: value, })); const childGroups = Object.entries(data) .filter( ([key, value]) => key.startsWith("child_co_") && value !== "revoked", ) .map(([key, value]) => ({ id: key.slice(6) as CoID, role: value, })); return { everyone, members, parentGroups, childGroups }; } export function GroupView({ coValue, data, onNavigate, node, }: { coValue: RawCoValue; data: JsonObject; onNavigate: (pages: PageInfo[]) => void; node: LocalNode; }) { const [addMemberType, setAddMemberType] = useState< null | "account" | "group" >(null); const { everyone, members, parentGroups, childGroups } = partitionMembers( data as Record, ); const onRemoveMember = async (id: CoID) => { if (confirm("Are you sure you want to remove this member?") === false) { return; } try { const group = await node.load(coValue.id); if (group === "unavailable") { throw new Error("Group not found"); } const rawGroup = group as RawGroup; rawGroup.removeMember(id as any); } catch (error) { console.error(error); throw error; } }; const onRemoveGroup = async (id: CoID) => { if (confirm("Are you sure you want to remove this group?") === false) { return; } try { const group = await node.load(coValue.id); if (group === "unavailable") { throw new Error("Group not found"); } const rawGroup = group as RawGroup; const targetGroup = await node.load(id); if (targetGroup === "unavailable") { throw new Error("Group not found"); } const rawTargetGroup = targetGroup as RawGroup; rawGroup.revokeExtend(rawTargetGroup); } catch (error) { console.error(error); throw error; } }; const handleAddMemberSubmit = async ( event: React.FormEvent, ) => { event.preventDefault(); const form = event.currentTarget; const memberId = (form.elements.namedItem("memberId") as HTMLInputElement) ?.value; const role = (form.elements.namedItem("role") as HTMLSelectElement)?.value; try { const group = await node.load(coValue.id); if (group === "unavailable") { throw new Error("Group not found"); } const rawGroup = group as RawGroup; // Adding an account if (addMemberType === "account") { let rawAccount: RawAccount | Everyone = "everyone"; if (memberId !== "everyone") { const account = await node.load(memberId as CoID); if (account === "unavailable") { throw new Error("Account not found"); } rawAccount = account as RawAccount; } rawGroup.addMember(rawAccount, role as "reader" | "writer" | "admin"); } // Adding a group else if (addMemberType === "group") { const targetGroup = await node.load(memberId as CoID); if (targetGroup === "unavailable") { throw new Error("Group not found"); } const rawTargetGroup = targetGroup as RawGroup; rawGroup.extend( rawTargetGroup, role as "reader" | "writer" | "admin" | "inherit", ); } setAddMemberType(null); } catch (error: any) { console.error(error); alert(`Failed to add ${addMemberType}: ${error.message}`); } }; return ( <> Member Permission {everyone.map((member) => ( {member.id} {member.role} {member.role !== "revoked" && ( )} ))} {members.map((member) => ( { onNavigate([{ coId: member.id, name: member.id }]); }} /> {member.role} {member.role !== "revoked" && ( )} ))} {parentGroups.map((group) => ( { onNavigate([{ coId: group.id, name: group.id }]); }} /> {group.role} {group.role !== "revoked" && ( )} ))}
{childGroups.length > 0 && ( Member of {childGroups.map((group) => ( { onNavigate([{ coId: group.id, name: group.id }]); }} /> ))}
)} setAddMemberType(null)} heading={addMemberType === "account" ? "Add Account" : "Add Group"} showButtons={false} >
); }