import { createFileRoute } from '@tanstack/solid-router' // **** Components **** import { PageContainer } from '@/components/layout/page-container' import { PageHeader } from '@/components/layout/page-header' import { Button } from '@/components/ui/button' import { IconCircleDashedPlus, IconEye, IconLink, IconUsersGroup } from '@tabler/icons-solidjs' import { AppCard, AppCardContainer, AppCardHeader, CardContent } from '@/components/ui/app-card' import { Link } from '@tanstack/solid-router' import { Tooltip, TooltipTrigger, TooltipContent } from '@/components/ui/tooltip' import { Badge } from '@/components/ui/badge' import { Switch, For, Match, Suspense, Show } from 'solid-js' import { Avatar, AvatarImage, AvatarFallback } from '@/components/ui/avatar' // **** Utils **** import { roleCollection } from '@/domain/role/role.collection' import { gtpCollection } from '@/domain/gtp/gtp.collection' import { groupCollection } from '@/domain/group/group.collection' import { teamCollection } from '@/domain/team/team.collection' import { userRequiredGuard } from '@/lib/auth.guard' import { createSignal, createEffect, onCleanup } from 'solid-js' import { Query } from '@tanstack/solid-db' import { or, eq } from '@tanstack/solid-db' import { cn } from '@/lib/utils' import { buttonVariants } from '@/components/ui/button' // **** Hooks **** import { useLiveQuery } from '@tanstack/solid-db' // **** Types **** import type { Role } from '@/domain/role/role.schema' import type { Group } from '@/domain/group/group.schema' import type { GTP } from '@/domain/gtp/gtp.schema' export const Route = createFileRoute('/_app/$slug/(shared)/roles/')({ remountDeps: (ctx) => [ctx.loaderDeps], component: RouteComponent, beforeLoad: async () => { return await userRequiredGuard() }, loader: async ({ context }) => { const { session } = context // await roleCollection.preload() // await gtpCollection.preload() // await groupCollection.preload() // await teamCollection.preload() return { orgId: session.activeOrganizationId } } }) function RouteComponent() { const params = Route.useParams() const rData = Route.useLoaderData() const [createRoleDialogOpen, setCreateRoleDialogOpen] = createSignal(false) const roleQb = new Query() .from({ role: roleCollection }) const { data: roles, isReady: isRolesReady } = useLiveQuery(() => ({ query: roleQb })) const groupQb = new Query() .from({ group: groupCollection }) const { data: groups, isReady: isGroupsReady } = useLiveQuery(() => ({ query: groupQb })) const gtpQb = new Query() .from({ gtp: gtpCollection }) .innerJoin({ role: roleCollection }, ({ gtp, role }) => eq(gtp.group_role_id, role.id) ) .innerJoin({ team: teamCollection }, ({ gtp, team }) => eq(gtp.team_id, team.id) ) .where(({ role, team }) => or( eq(role.org_id, rData().orgId), eq(team.organization_id, rData().orgId) ) ) .select(({ gtp, role, team }) => ({ ...gtp, roleName: role.name, teamName: team.name, })) const { data: gtps, isReady: isGtpsReady } = useLiveQuery(() => ({ query: gtpQb })) createEffect(() => { onCleanup(() => roleCollection.cleanup()) onCleanup(() => groupCollection.cleanup()) onCleanup(() => gtpCollection.cleanup()) onCleanup(() => teamCollection.cleanup()) }) return ( Loading} > setCreateRoleDialogOpen(true)} > Add role } />
{r => ( )}
) } function getEnrichedRole( groups: Group[], gtps: GTP[], role: Role ) { // Set containing groupIds using this role const groupRoleIds = new Set() const groupsUsingRole: Group[] = [] for (const x of gtps) { if (x.group_role_id === role.id) { groupRoleIds.add(x.group_id) } } for (const g of groups) { if (groupRoleIds.has(g.id)) { groupsUsingRole.push(g) } } return { ...role, groupCount: groupRoleIds.size, groups: groupsUsingRole } } type RoleCardProps = { tenantSlug: string type?: string role: ReturnType } function RoleCard(props: RoleCardProps) { let internalId = props.role.id switch (props.type) { case "admin": internalId = 'admin' break case "owner": internalId = 'owner' break default: internalId = props.role.id } return ( {props.role.name.charAt(0)}
{props.role.name}

{props.role.description}

{`${props.role.groupCount} group(s)`}
View
) }