add role update (#11217)
## Context This PR introduces the new Create and Edit role components, behind the PERMISSIONS_ENABLED_V2 feature flag.
This commit is contained in:
-47
@@ -1,47 +0,0 @@
|
||||
import styled from '@emotion/styled';
|
||||
import { t } from '@lingui/core/macro';
|
||||
|
||||
import { IconPicker } from '@/ui/input/components/IconPicker';
|
||||
import { TextArea } from '@/ui/input/components/TextArea';
|
||||
import { TextInput } from '@/ui/input/components/TextInput';
|
||||
import { Section } from 'twenty-ui';
|
||||
import { Role } from '~/generated-metadata/graphql';
|
||||
|
||||
const StyledInputsContainer = styled.div`
|
||||
display: flex;
|
||||
gap: ${({ theme }) => theme.spacing(2)};
|
||||
width: 100%;
|
||||
margin-bottom: ${({ theme }) => theme.spacing(2)};
|
||||
`;
|
||||
|
||||
const StyledInputContainer = styled.div`
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
`;
|
||||
|
||||
type RoleSettingsProps = {
|
||||
role: Pick<Role, 'id' | 'label' | 'description' | 'icon'>;
|
||||
};
|
||||
|
||||
export const RoleSettings = ({ role }: RoleSettingsProps) => {
|
||||
return (
|
||||
<Section>
|
||||
<StyledInputsContainer>
|
||||
<StyledInputContainer>
|
||||
<IconPicker
|
||||
disabled={true}
|
||||
selectedIconKey={role.icon ?? 'IconUser'}
|
||||
onChange={() => {}}
|
||||
/>
|
||||
</StyledInputContainer>
|
||||
<TextInput value={role.label} disabled fullWidth />
|
||||
</StyledInputsContainer>
|
||||
<TextArea
|
||||
minRows={4}
|
||||
placeholder={t`Write a description`}
|
||||
value={role.description || ''}
|
||||
disabled
|
||||
/>
|
||||
</Section>
|
||||
);
|
||||
};
|
||||
+79
@@ -0,0 +1,79 @@
|
||||
import styled from '@emotion/styled';
|
||||
import { t } from '@lingui/core/macro';
|
||||
|
||||
import { settingsDraftRoleFamilyState } from '@/settings/roles/states/settingsDraftRoleFamilyState';
|
||||
import { IconPicker } from '@/ui/input/components/IconPicker';
|
||||
import { TextArea } from '@/ui/input/components/TextArea';
|
||||
import { TextInput } from '@/ui/input/components/TextInput';
|
||||
import { useRecoilState } from 'recoil';
|
||||
import { Section } from 'twenty-ui';
|
||||
|
||||
const StyledInputsContainer = styled.div`
|
||||
display: flex;
|
||||
gap: ${({ theme }) => theme.spacing(2)};
|
||||
width: 100%;
|
||||
margin-bottom: ${({ theme }) => theme.spacing(2)};
|
||||
`;
|
||||
|
||||
const StyledInputContainer = styled.div`
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
`;
|
||||
|
||||
type SettingsRoleSettingsProps = {
|
||||
roleId: string;
|
||||
isEditable: boolean;
|
||||
};
|
||||
|
||||
export const SettingsRoleSettings = ({
|
||||
roleId,
|
||||
isEditable,
|
||||
}: SettingsRoleSettingsProps) => {
|
||||
const [settingsDraftRole, setSettingsDraftRole] = useRecoilState(
|
||||
settingsDraftRoleFamilyState(roleId),
|
||||
);
|
||||
|
||||
return (
|
||||
<Section>
|
||||
<StyledInputsContainer>
|
||||
<StyledInputContainer>
|
||||
<IconPicker
|
||||
selectedIconKey={settingsDraftRole.icon ?? 'IconUser'}
|
||||
dropdownId="role-settings-icon-picker"
|
||||
onChange={({ iconKey }: { iconKey: string }) => {
|
||||
setSettingsDraftRole({
|
||||
...settingsDraftRole,
|
||||
icon: iconKey,
|
||||
});
|
||||
}}
|
||||
disabled={!isEditable}
|
||||
/>
|
||||
</StyledInputContainer>
|
||||
<TextInput
|
||||
value={settingsDraftRole.label}
|
||||
fullWidth
|
||||
onChange={(value: string) => {
|
||||
setSettingsDraftRole({
|
||||
...settingsDraftRole,
|
||||
label: value,
|
||||
});
|
||||
}}
|
||||
placeholder={t`Role name`}
|
||||
disabled={!isEditable}
|
||||
/>
|
||||
</StyledInputsContainer>
|
||||
<TextArea
|
||||
minRows={4}
|
||||
placeholder={t`Write a description`}
|
||||
value={settingsDraftRole.description || ''}
|
||||
onChange={(value: string) => {
|
||||
setSettingsDraftRole({
|
||||
...settingsDraftRole,
|
||||
description: value,
|
||||
});
|
||||
}}
|
||||
disabled={!isEditable}
|
||||
/>
|
||||
</Section>
|
||||
);
|
||||
};
|
||||
+56
@@ -0,0 +1,56 @@
|
||||
import { SettingsRoleSettings } from '@/settings/roles/role-settings/components/SettingsRoleSettings';
|
||||
import { settingsDraftRoleFamilyState } from '@/settings/roles/states/settingsDraftRoleFamilyState';
|
||||
import { Meta, StoryObj } from '@storybook/react';
|
||||
import { useSetRecoilState } from 'recoil';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { ComponentDecorator, RouterDecorator } from 'twenty-ui';
|
||||
import { PENDING_ROLE_ID } from '~/pages/settings/roles/SettingsRoleCreate';
|
||||
import { I18nFrontDecorator } from '~/testing/decorators/I18nFrontDecorator';
|
||||
import { getRolesMock } from '~/testing/mock-data/roles';
|
||||
|
||||
const SettingsRoleSettingsWrapper = (
|
||||
args: React.ComponentProps<typeof SettingsRoleSettings>,
|
||||
) => {
|
||||
const setDraftRole = useSetRecoilState(
|
||||
settingsDraftRoleFamilyState(args.roleId),
|
||||
);
|
||||
|
||||
const role = getRolesMock().find((role) => role.id === args.roleId);
|
||||
|
||||
if (isDefined(role)) {
|
||||
setDraftRole(role);
|
||||
}
|
||||
|
||||
return (
|
||||
<SettingsRoleSettings roleId={args.roleId} isEditable={args.isEditable} />
|
||||
);
|
||||
};
|
||||
|
||||
const meta: Meta<typeof SettingsRoleSettingsWrapper> = {
|
||||
title: 'Modules/Settings/Roles/RoleSettings/SettingsRoleSettings',
|
||||
component: SettingsRoleSettingsWrapper,
|
||||
decorators: [RouterDecorator, ComponentDecorator, I18nFrontDecorator],
|
||||
};
|
||||
|
||||
export default meta;
|
||||
type Story = StoryObj<typeof SettingsRoleSettingsWrapper>;
|
||||
|
||||
export const Default: Story = {
|
||||
args: {
|
||||
roleId: '1',
|
||||
isEditable: true,
|
||||
},
|
||||
};
|
||||
|
||||
export const ReadOnly: Story = {
|
||||
args: {
|
||||
roleId: '1',
|
||||
isEditable: false,
|
||||
},
|
||||
};
|
||||
|
||||
export const PendingRole: Story = {
|
||||
args: {
|
||||
roleId: PENDING_ROLE_ID,
|
||||
},
|
||||
};
|
||||
Reference in New Issue
Block a user