feat: customisable workspace role permissions (#345)

* feat: setup schema for workspace roles

* chore: regen migration

* feat: add publicId to workspace roles

* feat: setup default permissions

* feat: add repo funcs

* feat: setup basic router interactions

* feat: add card permissions

* feat: assert permissions for lists

* feat: assert board permissions

* feat: assert permission for remaining routes

* feat: add permissions page to settings

* feat: enable updating member roles

* feat: order members by role and createdAt

* feat: allow editing individual permissions

* feat: reset role defaults

* feat: clear all permission overrides

* feat: allow users to delete entities they have created

* feat: set roleId when inviting new members

* feat: disable UI elements if user does not have permissions

* feat: allow admins to assign the admin role to other users

* feat: allow delete:list as default

* refactor: centre permissions modal

* chore: translations
This commit is contained in:
Henry
2026-02-01 21:17:18 +00:00
committed by GitHub
parent 5f2d409773
commit 7f5a1ab513
83 changed files with 10568 additions and 1442 deletions

View File

@@ -4,6 +4,8 @@ import { HiOutlineRectangleStack } from "react-icons/hi2";
import Button from "~/components/Button";
import PatternedBackground from "~/components/PatternedBackground";
import { Tooltip } from "~/components/Tooltip";
import { usePermissions } from "~/hooks/usePermissions";
import { useModal } from "~/providers/modal";
import { useWorkspace } from "~/providers/workspace";
import { api } from "~/utils/api";
@@ -11,6 +13,7 @@ import { api } from "~/utils/api";
export function BoardsList({ isTemplate }: { isTemplate?: boolean }) {
const { workspace } = useWorkspace();
const { openModal } = useModal();
const { canCreateBoard } = usePermissions();
const { data, isLoading } = api.board.all.useQuery(
{
@@ -41,9 +44,20 @@ export function BoardsList({ isTemplate }: { isTemplate?: boolean }) {
{t`Get started by creating a new ${isTemplate ? "template" : "board"}`}
</p>
</div>
<Button onClick={() => openModal("NEW_BOARD")}>
{t`Create new ${isTemplate ? "template" : "board"}`}
</Button>
<Tooltip
content={
!canCreateBoard ? t`You don't have permission` : undefined
}
>
<Button
onClick={() => {
if (canCreateBoard) openModal("NEW_BOARD");
}}
disabled={!canCreateBoard}
>
{t`Create new ${isTemplate ? "template" : "board"}`}
</Button>
</Tooltip>
</div>
);