From 91acf0fb9d9df570329b65d7d85e4ac0a3d59adb Mon Sep 17 00:00:00 2001 From: kyle-ssg Date: Tue, 25 Mar 2025 17:44:08 +0000 Subject: [PATCH 1/6] User permissions summary --- frontend/web/components/EditPermissions.tsx | 89 +++++++++++++------ .../web/components/PermissionsSummaryList.tsx | 44 +++++---- frontend/web/components/PermissionsTabs.tsx | 1 + frontend/web/components/modals/CreateRole.tsx | 14 +-- .../web/components/modals/CreateSegment.tsx | 21 +++-- .../pages/EnvironmentSettingsPage.js | 16 ++++ 6 files changed, 121 insertions(+), 64 deletions(-) diff --git a/frontend/web/components/EditPermissions.tsx b/frontend/web/components/EditPermissions.tsx index a6d9e0417e53..47737a0af88e 100644 --- a/frontend/web/components/EditPermissions.tsx +++ b/frontend/web/components/EditPermissions.tsx @@ -1,6 +1,6 @@ import React, { FC, forwardRef, useCallback, useEffect, useState } from 'react' -import { find } from 'lodash' -import { close as closeIcon } from 'ionicons/icons' +import { find, sortBy } from 'lodash' +import { close as closeIcon, informationCircle } from 'ionicons/icons' import { IonIcon } from '@ionic/react' import _data from 'common/data/base/_data' import { @@ -65,8 +65,11 @@ import PlanBasedAccess from './PlanBasedAccess' import { useGetTagsQuery } from 'common/services/useTag' import { components } from 'react-select' import { SingleValueProps } from 'react-select/lib/components/SingleValue' -import Utils from 'common/utils/utils' import AddEditTags from './tags/AddEditTags' +import PermissionsSummaryList, { + PermissionSummaryItem, +} from './PermissionsSummaryList' +import Tooltip from './Tooltip' const Project = require('common/project') @@ -1132,7 +1135,17 @@ const EditPermissions: FC = (props) => { id='org-members-list' title='Users' className='panel--transparent' - items={users} + items={sortBy(users, (user) => + user.role === 'ADMIN' + ? `0${user.first_name}` + : permissions?.find( + (permission) => + permission.user.id === user.id && + permission.permissions?.length, + ) + ? `1${user.first_name}` + : `2${user.first_name}`, + )} itemHeight={64} header={ @@ -1176,29 +1189,51 @@ const EditPermissions: FC = (props) => { {email} - {role === 'ADMIN' ? ( - - - { - 'Organisation administrators have all permissions enabled.
To change the role of this user, visit Organisation Settings.' - } -
-
- ) : ( - - {matchingPermissions && - matchingPermissions.admin - ? `${Format.camelCase( - level, - )} Administrator` - : 'Regular User'} - - )} +
+ {role === 'ADMIN' ? ( +
+ + } + > + { + 'Organisation administrators have all permissions enabled.
To change the role of this user, visit Organisation Settings.' + } +
+
+ ) : ( +
+ {!matchingPermissions?.permissions + ?.length ? ( + + No Permissions{' '} + + + +
+ } + > + Permissions for this user may exist at + the Group or Role Level + + ) : ( + ({ + permission_key: v, + tags: [], + }), + )} + /> + )} +
+ )} +
+ `${Format.enumeration.get(v.permission_key)}${v.tags?.length ? `*` : ''}` + +export const PermissionSummaryItem: FC = ({ + isAdmin, + value, +}) => { + return ( +
+ {isAdmin ? 'Administrator' : getPermissionString(value)} +
+ ) +} + const PermissionsSummaryList: FC = ({ isAdmin, numberToTruncate = 3, @@ -37,24 +63,12 @@ const PermissionsSummaryList: FC = ({ truncatedItems: (sortedPermissions || []).slice(numberToTruncate), } }, [isAdmin, numberToTruncate, permissions]) - const getPermissionString = (v: RolePermission['permissions'][number]) => - `${Format.enumeration.get(v.permission_key)}${v.tags?.length ? `*` : ''}` const truncatedHasLimitedAccess = truncatedItems?.find((v) => v.tags?.length) return (
{items.map((value, i) => ( -
- {getPermissionString(value)} -
+ ))} {!!truncatedItems.length && ( = ({ - }] + rules: [ + { + rules: Array<{ + conditions: SegmentConditionsError[] + }> + }, + ] } } @@ -351,9 +353,10 @@ const CreateSegment: FC = ({ > {Format.camelCase( - `${displayIndex > 0 ? 'And ' : ''}${rule.type === 'ANY' - ? 'Any of the following' - : 'None of the following' + `${displayIndex > 0 ? 'And ' : ''}${ + rule.type === 'ANY' + ? 'Any of the following' + : 'None of the following' }`, )} diff --git a/frontend/web/components/pages/EnvironmentSettingsPage.js b/frontend/web/components/pages/EnvironmentSettingsPage.js index d931a5c4f454..f69c7741aa47 100644 --- a/frontend/web/components/pages/EnvironmentSettingsPage.js +++ b/frontend/web/components/pages/EnvironmentSettingsPage.js @@ -31,6 +31,7 @@ import { getWebhooks, updateWebhook, } from 'common/services/useWebhooks' +import _data from 'common/data/base/_data' const showDisabledFlagOptions = [ { label: 'Inherit from Project', value: null }, @@ -56,6 +57,7 @@ const EnvironmentSettingsPage = class extends Component { webhooksLoading: true, } AppActions.getProject(this.props.match.params.projectId) + this.getPermissions() } componentDidMount = () => { @@ -79,6 +81,16 @@ const EnvironmentSettingsPage = class extends Component { }) } + getPermissions = () => { + _data + .get( + `${Project.api}environments/${this.props.match.params.environmentId}/user-permissions/`, + ) + .then((permissions) => { + this.setState({ permissions }) + }) + } + getEnvironment = () => { const env = ProjectStore.getEnvs().find( (v) => v.api_key === this.props.match.params.environmentId, @@ -799,6 +811,9 @@ const EnvironmentSettingsPage = class extends Component { { + this.getPermissions() + }} parentId={this.props.match.params.projectId} parentLevel='project' parentSettingsLink={`/project/${this.props.match.params.projectId}/settings`} @@ -806,6 +821,7 @@ const EnvironmentSettingsPage = class extends Component { envId={env.id} router={this.context.router} level='environment' + permissions={this.state.permissions} roleTabTitle='Environment Permissions' roles={this.state.roles} /> From 4e3e99789718c91f2794e338058bef2bfd3e3fb4 Mon Sep 17 00:00:00 2001 From: kyle-ssg Date: Tue, 25 Mar 2025 17:48:22 +0000 Subject: [PATCH 2/6] Revert unchanged From 8cfc9ecf854366416183a0f643e3343cde990e77 Mon Sep 17 00:00:00 2001 From: kyle-ssg Date: Wed, 9 Apr 2025 10:06:13 +0100 Subject: [PATCH 3/6] Make permissions messaging more explicit --- frontend/common/stores/account-store.js | 17 ++++------------- frontend/web/components/EditPermissions.tsx | 8 +++++--- 2 files changed, 9 insertions(+), 16 deletions(-) diff --git a/frontend/common/stores/account-store.js b/frontend/common/stores/account-store.js index 54a4eb468f3c..5284c5b873d4 100644 --- a/frontend/common/stores/account-store.js +++ b/frontend/common/stores/account-store.js @@ -246,22 +246,13 @@ const controller = { } return controller.getOrganisations() }, - register: ({ - email, - first_name, - last_name, - marketing_consent_given, - password, - }) => { + register: (user) => { store.saving() + data .post(`${Project.api}auth/users/`, { - email, - first_name, - invite_hash: API.getInvite() || undefined, - last_name, - marketing_consent_given, - password, + ...user, + invite_hash: API.getInvite(), referrer: API.getReferrer() || '', sign_up_type: API.getInviteType(), }) diff --git a/frontend/web/components/EditPermissions.tsx b/frontend/web/components/EditPermissions.tsx index 47737a0af88e..9efdaa1bbf5b 100644 --- a/frontend/web/components/EditPermissions.tsx +++ b/frontend/web/components/EditPermissions.tsx @@ -1209,7 +1209,7 @@ const EditPermissions: FC = (props) => { - No Permissions{' '} + No User-level Permissions{' '} = (props) => {
} > - Permissions for this user may exist at - the Group or Role Level + This user has no permissions assigned + directly, but they may belong to a + group that has permissions on this + {level}. ) : ( Date: Tue, 15 Apr 2025 12:24:42 +0100 Subject: [PATCH 4/6] Fix no user permission level tooltip --- frontend/web/components/EditPermissions.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/frontend/web/components/EditPermissions.tsx b/frontend/web/components/EditPermissions.tsx index 9efdaa1bbf5b..d89e37f768d5 100644 --- a/frontend/web/components/EditPermissions.tsx +++ b/frontend/web/components/EditPermissions.tsx @@ -1218,10 +1218,10 @@ const EditPermissions: FC = (props) => {
} > - This user has no permissions assigned + {`This user has no permissions assigned directly, but they may belong to a group that has permissions on this - {level}. + ${level}.`} ) : ( Date: Tue, 15 Apr 2025 12:37:38 +0100 Subject: [PATCH 5/6] Fix permission tag when user is admin --- frontend/web/components/EditPermissions.tsx | 25 +++++++++++++++------ 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/frontend/web/components/EditPermissions.tsx b/frontend/web/components/EditPermissions.tsx index d89e37f768d5..3bdc96581336 100644 --- a/frontend/web/components/EditPermissions.tsx +++ b/frontend/web/components/EditPermissions.tsx @@ -1170,6 +1170,7 @@ const EditPermissions: FC = (props) => { const matchingPermissions = permissions?.find( (v) => v.user.id === id, ) + debugger return ( = (props) => { ) : (
{!matchingPermissions?.permissions - ?.length ? ( + ?.length && + !matchingPermissions?.admin ? ( @@ -1225,12 +1227,21 @@ const EditPermissions: FC = (props) => { ) : ( ({ - permission_key: v, - tags: [], - }), - )} + permissions={ + matchingPermissions.admin + ? [ + { + permission_key: `${level} Administrator`, + tags: [], + }, + ] + : matchingPermissions.permissions.map( + (v) => ({ + permission_key: v, + tags: [], + }), + ) + } /> )}
From caff1cc12e4733cd4c89acb405e226d48ca81ea3 Mon Sep 17 00:00:00 2001 From: Kyle Johnson Date: Tue, 29 Apr 2025 15:55:23 +0100 Subject: [PATCH 6/6] Update frontend/web/components/EditPermissions.tsx Co-authored-by: Matthew Elwell --- frontend/web/components/EditPermissions.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/web/components/EditPermissions.tsx b/frontend/web/components/EditPermissions.tsx index 3bdc96581336..c39dcbc32186 100644 --- a/frontend/web/components/EditPermissions.tsx +++ b/frontend/web/components/EditPermissions.tsx @@ -1199,7 +1199,7 @@ const EditPermissions: FC = (props) => { } > { - 'Organisation administrators have all permissions enabled.
To change the role of this user, visit Organisation Settings.' + 'Organisation administrators have all permissions enabled. To change the role of this user, visit Organisation Settings.' }