From 9b5c33527bd3b91dfc5fc23bbe63f0d02ddfa4dd Mon Sep 17 00:00:00 2001 From: Zach Waterfield Date: Fri, 27 Dec 2024 14:23:25 -0500 Subject: [PATCH] improve access control object ui --- .../access_control/AccessControlObject.tsx | 185 +++++++++++------- 1 file changed, 117 insertions(+), 68 deletions(-) diff --git a/frontend/src/layout/navigation-3000/sidepanel/panels/access_control/AccessControlObject.tsx b/frontend/src/layout/navigation-3000/sidepanel/panels/access_control/AccessControlObject.tsx index 93e14755e12d5..d0660023786fc 100644 --- a/frontend/src/layout/navigation-3000/sidepanel/panels/access_control/AccessControlObject.tsx +++ b/frontend/src/layout/navigation-3000/sidepanel/panels/access_control/AccessControlObject.tsx @@ -1,9 +1,10 @@ -import { IconX } from '@posthog/icons' +import { IconTrash } from '@posthog/icons' import { LemonBanner, LemonButton, LemonDialog, LemonInputSelect, + LemonModal, LemonSelect, LemonSelectProps, LemonTable, @@ -37,7 +38,7 @@ export function AccessControlObject(props: AccessControlLogicProps): JSX.Element return ( -
+
{canEditAccessControls === false ? ( You don't have permission to edit access controls for {suffix}. @@ -48,12 +49,10 @@ export function AccessControlObject(props: AccessControlLogicProps): JSX.Element

Default access to {suffix}

-

Members

-

Roles

@@ -88,11 +87,19 @@ function AccessControlObjectDefaults(): JSX.Element | null { function AccessControlObjectUsers(): JSX.Element | null { const { user } = useValues(userLogic) - const { membersById, addableMembers, accessControlMembers, accessControlsLoading, availableLevels } = - useValues(accessControlLogic) + const { + membersById, + addableMembers, + accessControlMembers, + accessControlsLoading, + availableLevels, + canEditAccessControls, + } = useValues(accessControlLogic) const { updateAccessControlMembers } = useAsyncActions(accessControlLogic) const { guardAvailableFeature } = useValues(upgradeModalLogic) + const [modelOpen, setModelOpen] = useState(false) + if (!user) { return null } @@ -104,33 +111,26 @@ function AccessControlObjectUsers(): JSX.Element | null { // TODO: WHAT A MESS - Fix this to do the index mapping beforehand... const columns: LemonTableColumns = [ { - key: 'user_profile_picture', - render: function ProfilePictureRender(_, ac) { - return - }, - width: 32, - }, - { - title: 'Name', - key: 'user_first_name', + key: 'user', + title: 'User', render: (_, ac) => ( - - {member(ac)?.user.uuid == user.uuid - ? `${member(ac)?.user.first_name} (you)` - : member(ac)?.user.first_name} - +
+ +
+

+ {member(ac)?.user.uuid == user.uuid + ? `${member(ac)?.user.first_name} (you)` + : member(ac)?.user.first_name} +

+

{member(ac)?.user.email}

+
+
), sorter: (a, b) => member(a)?.user.first_name.localeCompare(member(b)?.user.first_name), }, { - title: 'Email', - key: 'user_email', - render: (_, ac) => member(ac)?.user.email, - sorter: (a, b) => member(a)?.user.email.localeCompare(member(b)?.user.email), - }, - { - title: 'Level', key: 'level', + title: 'Level', width: 0, render: function LevelRender(_, { access_level, organization_member }) { return ( @@ -164,12 +164,30 @@ function AccessControlObjectUsers(): JSX.Element | null { ] return ( -
- +
+
+

Members

+ setModelOpen(true)} + disabledReason={!canEditAccessControls ? 'You cannot edit this' : undefined} + > + Add + +
+ + +
+ + { if (guardAvailableFeature(AvailableFeature.PROJECT_BASED_PERMISSIONING)) { await updateAccessControlMembers(newValues.map((member) => ({ member, level }))) + setModelOpen(false) } }} options={addableMembers.map((member) => ({ @@ -178,18 +196,24 @@ function AccessControlObjectUsers(): JSX.Element | null { labelComponent: , }))} /> - - -
+ ) } function AccessControlObjectRoles(): JSX.Element | null { - const { accessControlRoles, accessControlsLoading, addableRoles, rolesById, availableLevels } = - useValues(accessControlLogic) + const { + accessControlRoles, + accessControlsLoading, + addableRoles, + rolesById, + availableLevels, + canEditAccessControls, + } = useValues(accessControlLogic) const { updateAccessControlRoles } = useAsyncActions(accessControlLogic) const { guardAvailableFeature } = useValues(upgradeModalLogic) + const [modelOpen, setModelOpen] = useState(false) + const columns: LemonTableColumns = [ { title: 'Role', @@ -253,12 +277,30 @@ function AccessControlObjectRoles(): JSX.Element | null { ] return ( -
- +
+
+

Roles

+ setModelOpen(true)} + disabledReason={!canEditAccessControls ? 'You cannot edit this' : undefined} + > + Add + +
+ + +
+ + { if (guardAvailableFeature(AvailableFeature.PROJECT_BASED_PERMISSIONING)) { await updateAccessControlRoles(newValues.map((role) => ({ role, level }))) + setModelOpen(false) } }} options={addableRoles.map((role) => ({ @@ -266,9 +308,7 @@ function AccessControlObjectRoles(): JSX.Element | null { label: role.name, }))} /> - - -
+ ) } @@ -306,8 +346,7 @@ function RemoveAccessButton({ return ( } - status="danger" + icon={} size="small" disabledReason={!canEditAccessControls ? 'You cannot edit this' : undefined} onClick={() => @@ -325,7 +364,9 @@ function RemoveAccessButton({ ) } -function AddItemsControls(props: { +function AddItemsControlsModal(props: { + modelOpen: boolean + setModelOpen: (open: boolean) => void placeholder: string onAdd: (newValues: string[], level: AccessControlType['access_level']) => Promise options: { @@ -352,32 +393,40 @@ function AddItemsControls(props: { : undefined return ( -
-
- setItems(newValues)} - mode="multiple" - options={props.options} - disabled={!canEditAccessControls} - /> + props.setModelOpen(false)} + title="Add access" + maxWidth="30rem" + description="Allow other users or roles to access this resource" + > +
+
+ setItems(newValues)} + mode="multiple" + options={props.options} + disabled={!canEditAccessControls} + /> +
+ + + + Add +
- - - - Add - -
+ ) }