## What does this PR do? This PR implements attributes PBAC - router checks + UI ## Visual Demo (For contributors especially) A visual demonstration is strongly recommended, for both the original and new change **(video / image - any one)**. #### Video Demo (if applicable): - Show screen recordings of the issue or feature. - Demonstrate how to reproduce the issue, the behavior before and after the change. #### Image Demo (if applicable): - Add side-by-side screenshots of the original and updated change. - Highlight any significant change(s). ## Mandatory Tasks (DO NOT REMOVE) - [ ] I have self-reviewed the code (A decent size PR without self-review might be rejected). - [ ] I have updated the developer docs in /docs if this PR makes changes that would require a [documentation change](https://cal.com/docs). If N/A, write N/A here and check the checkbox. - [ ] I confirm automated tests are in place that prove my fix is effective or that my feature works. ## How should this be tested? Enable PBAC on an org Create a custom role -> advanced -> organizations -> "editUser" Assign it to a user impersonate user test they have access to all things attributes remove permissions check they dont have permissions. ## Checklist <!-- Remove bullet points below that don't apply to you --> - I haven't read the [contributing guide](https://github.com/calcom/cal.com/blob/main/CONTRIBUTING.md) - My code doesn't follow the style guidelines of this project - I haven't commented my code, particularly in hard-to-understand areas - I haven't checked if my changes generate no new warnings <!-- This is an auto-generated description by cubic. --> --- ## Summary by cubic Adds a new PBAC “editUsers” permission and read gating for Attributes, updating the UI and backend so users can view and edit attributes only when allowed. - **New Features** - Added CustomAction.EditUsers to the permission registry for organization-scoped attribute editing. - Settings computes canViewAttributes and shows the Attributes tab only when allowed. - Members page fetches Attributes permissions and exposes canViewAttributes and canEditAttributesForUser to the UI. - User Edit Sheet hides attributes without read permission and shows attribute editing and the bulk “Mass Assign Attributes” action only with editUsers; other user edits depend on changeMemberRole. - Attributes TRPC router gates create/edit/delete/toggle via PBAC and requires organization.attributes.editUsers for assign/bulk-assign; added a helper to create PBAC-aware procedures. - **Migration** - Run the new Prisma migration to seed the admin role with editUsers. - If using custom roles, grant Edit Users under Attributes as needed. <sup>Written for commit 856aa2e8e1521fc22cd71cb0fa6d720036efe8a2. Summary will update automatically on new commits.</sup> <!-- End of auto-generated description by cubic. -->
88 lines
2.1 KiB
TypeScript
88 lines
2.1 KiB
TypeScript
import { useLocale } from "@calcom/lib/hooks/useLocale";
|
|
import { Button } from "@calcom/ui/components/button";
|
|
import { SheetClose } from "@calcom/ui/components/sheet";
|
|
|
|
import { useEditMode } from "./store";
|
|
|
|
function EditModeFooter() {
|
|
const { t } = useLocale();
|
|
const setEditMode = useEditMode((state) => state.setEditMode);
|
|
const isPending = useEditMode((state) => state.mutationLoading);
|
|
|
|
return (
|
|
<>
|
|
<Button
|
|
color="secondary"
|
|
type="button"
|
|
className="justify-center"
|
|
onClick={() => {
|
|
setEditMode(false);
|
|
}}>
|
|
{t("cancel")}
|
|
</Button>
|
|
|
|
<Button type="submit" loading={isPending} className="justify-center">
|
|
{t("update")}
|
|
</Button>
|
|
</>
|
|
);
|
|
}
|
|
|
|
function MoreInfoFooter({
|
|
canEditAttributesForUser,
|
|
canChangeMemberRole,
|
|
}: {
|
|
canEditAttributesForUser?: boolean;
|
|
canChangeMemberRole?: boolean;
|
|
}) {
|
|
const { t } = useLocale();
|
|
const setEditMode = useEditMode((state) => state.setEditMode);
|
|
|
|
// Show edit button if user can change member role (edit user info) or edit attributes
|
|
const canEdit = canChangeMemberRole || canEditAttributesForUser;
|
|
|
|
return (
|
|
<>
|
|
<SheetClose asChild>
|
|
<Button color="secondary" type="button" className="justify-center">
|
|
{t("close")}
|
|
</Button>
|
|
</SheetClose>
|
|
{canEdit && (
|
|
<Button
|
|
type="button"
|
|
className="justify-center"
|
|
onClick={() => {
|
|
setEditMode(true);
|
|
}}
|
|
key="EDIT_BUTTON"
|
|
StartIcon="pencil">
|
|
{t("edit")}
|
|
</Button>
|
|
)}
|
|
</>
|
|
);
|
|
}
|
|
|
|
export function SheetFooterControls({
|
|
canEditAttributesForUser,
|
|
canChangeMemberRole,
|
|
}: {
|
|
canEditAttributesForUser?: boolean;
|
|
canChangeMemberRole?: boolean;
|
|
}) {
|
|
const editMode = useEditMode((state) => state.editMode);
|
|
return (
|
|
<>
|
|
{editMode ? (
|
|
<EditModeFooter />
|
|
) : (
|
|
<MoreInfoFooter
|
|
canEditAttributesForUser={canEditAttributesForUser}
|
|
canChangeMemberRole={canChangeMemberRole}
|
|
/>
|
|
)}
|
|
</>
|
|
);
|
|
}
|