import { useState } from "react"; import { Group, Stack, Tabs } from "@mantine/core"; import { IconUser, IconUserDown, IconUsersGroup } from "@tabler/icons-react"; import type { GroupPermissionKey } from "@homarr/definitions"; import { useScopedI18n } from "@homarr/translation/client"; import type { TablerIcon } from "@homarr/ui"; import { CountBadge } from "@homarr/ui"; import { AccessProvider } from "./context"; import type { AccessFormType } from "./form"; import { GroupAccessForm } from "./group-access-form"; import { InheritAccessTable } from "./inherit-access-table"; import { UsersAccessForm } from "./user-access-form"; interface GroupAccessPermission { permission: TPermission; group: { id: string; name: string; }; } interface UserAccessPermission { permission: TPermission; user: { name: string | null; image: string | null; id: string; }; } interface SimpleMutation { mutate: ( props: { entityId: string; permissions: { principalId: string; permission: TPermission }[] }, options: { onSuccess: () => void }, ) => void; isPending: boolean; } export interface AccessQueryData { inherited: GroupAccessPermission[]; groups: GroupAccessPermission[]; users: UserAccessPermission[]; } interface Props { permission: { items: readonly TPermission[]; default: TPermission; icons: Record; groupPermissionMapping: Record; fullAccessGroupPermission: GroupPermissionKey; }; query: { data: AccessQueryData; invalidate: () => Promise; }; groupsMutation: SimpleMutation; usersMutation: SimpleMutation; entity: { id: string; ownerId: string | null; owner: { id: string; name: string | null; image: string | null; } | null; }; translate: (key: TPermission) => string; } export const AccessSettings = ({ permission, query, groupsMutation, usersMutation, entity, translate, }: Props) => { const [counts, setCounts] = useState({ user: query.data.users.length + (entity.owner ? 1 : 0), group: query.data.groups.length, }); const handleGroupSubmit = (values: AccessFormType) => { groupsMutation.mutate( { entityId: entity.id, permissions: values.items, }, { onSuccess() { void query.invalidate(); }, }, ); }; const handleUserSubmit = (values: AccessFormType) => { usersMutation.mutate( { entityId: entity.id, permissions: values.items, }, { onSuccess() { void query.invalidate(); }, }, ); }; return ( defaultPermission={permission.default} icons={permission.icons} permissions={permission.items} translate={translate} > entity={entity} accessQueryData={query.data} handleCountChange={(callback) => setCounts(({ user, ...others }) => ({ user: callback(user), ...others, })) } handleSubmit={handleUserSubmit} isPending={usersMutation.isPending} /> accessQueryData={query.data} handleCountChange={(callback) => setCounts(({ group, ...others }) => ({ group: callback(group), ...others, })) } handleSubmit={handleGroupSubmit} isPending={groupsMutation.isPending} /> accessQueryData={query.data} fullAccessGroupPermission={permission.fullAccessGroupPermission} mapPermissions={permission.groupPermissionMapping} /> ); }; interface TabItemProps { value: "user" | "group" | "inherited"; count: number; icon: TablerIcon; } const TabItem = ({ value, icon: Icon, count }: TabItemProps) => { const t = useScopedI18n("permission"); return ( }> {t(`tab.${value}`)} ); };