add stories to roles components (#10503)
## Context Adding stories for roles components. Also moving modules components to the proper "modules" folder, "pages" folder being only for entry points. ## Test Run storybook <img width="1145" alt="Screenshot 2025-02-26 at 13 40 40" src="https://github.com/user-attachments/assets/bc184ab0-c590-4362-8c5a-1bf5ef176e6c" /> <img width="1149" alt="Screenshot 2025-02-26 at 13 40 32" src="https://github.com/user-attachments/assets/699cd205-31db-45e9-b9c1-caff1832bd47" /> <img width="1153" alt="Screenshot 2025-02-26 at 13 40 11" src="https://github.com/user-attachments/assets/72e45a67-ea89-4999-8b16-6f7d027d07f6" /> <img width="471" alt="Screenshot 2025-02-26 at 13 38 16" src="https://github.com/user-attachments/assets/62676943-9935-42b5-b769-5544f7eed85f" /> <img width="472" alt="Screenshot 2025-02-26 at 13 38 12" src="https://github.com/user-attachments/assets/946baab9-1be4-439e-bf99-0ebeab0995f7" />
This commit is contained in:
@ -47,6 +47,7 @@ describe('getDisplayNameFromParticipant', () => {
|
||||
updatedAt: '',
|
||||
userEmail: '',
|
||||
userId: '',
|
||||
colorScheme: 'Light',
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
@ -28,6 +28,7 @@ const mockWorkspaceMember = {
|
||||
firstName: 'John',
|
||||
lastName: 'Doe',
|
||||
},
|
||||
colorScheme: 'Light' as const,
|
||||
};
|
||||
|
||||
const createMockOptions = (): Options<any> => ({
|
||||
@ -168,6 +169,7 @@ describe('ApolloFactory', () => {
|
||||
firstName: 'John',
|
||||
lastName: 'Doe',
|
||||
},
|
||||
colorScheme: 'Light' as const,
|
||||
};
|
||||
|
||||
apolloFactory.updateWorkspaceMember(newWorkspaceMember);
|
||||
|
||||
@ -42,6 +42,7 @@ describe('useFindManyRecords', () => {
|
||||
id: '32219445-f587-4c40-b2b1-6d3205ed96da',
|
||||
name: { firstName: 'John', lastName: 'Connor' },
|
||||
locale: 'en',
|
||||
colorScheme: 'Light',
|
||||
});
|
||||
|
||||
const setMetadataItems = useSetRecoilState(objectMetadataItemsState);
|
||||
|
||||
@ -73,6 +73,7 @@ describe('useFilteredSearchRecordQuery', () => {
|
||||
id: '32219445-f587-4c40-b2b1-6d3205ed96da',
|
||||
name: { firstName: 'John', lastName: 'Connor' },
|
||||
locale: 'en',
|
||||
colorScheme: 'Light',
|
||||
});
|
||||
|
||||
const setMetadataItems = useSetRecoilState(objectMetadataItemsState);
|
||||
|
||||
@ -2,10 +2,10 @@ import { Table } from '@/ui/layout/table/components/Table';
|
||||
import styled from '@emotion/styled';
|
||||
import { t } from '@lingui/core/macro';
|
||||
|
||||
import { RolesTableHeader } from '@/settings/roles/components/RolesTableHeader';
|
||||
import { RolesTableRow } from '@/settings/roles/components/RolesTableRow';
|
||||
import { Button, H2Title, IconPlus, Section } from 'twenty-ui';
|
||||
import { Role } from '~/generated-metadata/graphql';
|
||||
import { RolesTableHeader } from '~/pages/settings/roles/components/RolesTableHeader';
|
||||
import { RolesTableRow } from '~/pages/settings/roles/components/RolesTableRow';
|
||||
|
||||
const StyledTable = styled(Table)`
|
||||
margin-top: ${({ theme }) => theme.spacing(0.5)};
|
||||
@ -44,7 +44,7 @@ export const RolesDefaultRole = ({ roles }: { roles: Role[] }) => {
|
||||
});
|
||||
};
|
||||
|
||||
if (!currentWorkspace) {
|
||||
if (!currentWorkspace || !defaultRole) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -0,0 +1,24 @@
|
||||
import { Meta, StoryObj } from '@storybook/react';
|
||||
import { ComponentDecorator, RouterDecorator } from 'twenty-ui';
|
||||
|
||||
import { Roles } from '@/settings/roles/components/Roles';
|
||||
import { I18nFrontDecorator } from '~/testing/decorators/I18nFrontDecorator';
|
||||
import { getRolesMock } from '~/testing/mock-data/roles';
|
||||
|
||||
const meta: Meta<typeof Roles> = {
|
||||
title: 'Modules/Settings/Roles/Roles',
|
||||
component: Roles,
|
||||
decorators: [ComponentDecorator, I18nFrontDecorator, RouterDecorator],
|
||||
parameters: {
|
||||
maxWidth: 800,
|
||||
},
|
||||
};
|
||||
|
||||
export default meta;
|
||||
type Story = StoryObj<typeof Roles>;
|
||||
|
||||
export const Default: Story = {
|
||||
args: {
|
||||
roles: getRolesMock(),
|
||||
},
|
||||
};
|
||||
@ -0,0 +1,43 @@
|
||||
import { currentWorkspaceState } from '@/auth/states/currentWorkspaceState';
|
||||
import { RolesDefaultRole } from '@/settings/roles/components/RolesDefaultRole';
|
||||
import { Meta, StoryObj } from '@storybook/react';
|
||||
import { RecoilRoot } from 'recoil';
|
||||
import { ComponentDecorator } from 'twenty-ui';
|
||||
import { I18nFrontDecorator } from '~/testing/decorators/I18nFrontDecorator';
|
||||
import { getRolesMock } from '~/testing/mock-data/roles';
|
||||
import { mockCurrentWorkspace } from '~/testing/mock-data/users';
|
||||
|
||||
const rolesMock = getRolesMock();
|
||||
|
||||
const RolesDefaultRoleWrapper = () => {
|
||||
return (
|
||||
<RecoilRoot
|
||||
initializeState={(snapshot) => {
|
||||
snapshot.set(currentWorkspaceState, {
|
||||
...mockCurrentWorkspace,
|
||||
defaultRole: rolesMock[1],
|
||||
});
|
||||
}}
|
||||
>
|
||||
<RolesDefaultRole roles={rolesMock} />
|
||||
</RecoilRoot>
|
||||
);
|
||||
};
|
||||
|
||||
const meta: Meta<typeof RolesDefaultRoleWrapper> = {
|
||||
title: 'Modules/Settings/Roles/RolesDefaultRole',
|
||||
component: RolesDefaultRoleWrapper,
|
||||
decorators: [ComponentDecorator, I18nFrontDecorator],
|
||||
parameters: {
|
||||
maxWidth: 800,
|
||||
},
|
||||
};
|
||||
|
||||
export default meta;
|
||||
type Story = StoryObj<typeof RolesDefaultRoleWrapper>;
|
||||
|
||||
export const Default: Story = {
|
||||
args: {
|
||||
roles: rolesMock,
|
||||
},
|
||||
};
|
||||
@ -1,5 +1,8 @@
|
||||
import { currentWorkspaceMembersState } from '@/auth/states/currentWorkspaceMembersStates';
|
||||
import { currentWorkspaceMemberState } from '@/auth/states/currentWorkspaceMemberState';
|
||||
import { RoleAssignmentTableHeader } from '@/settings/roles/role-assignment/components/RoleAssignmentTableHeader';
|
||||
import { RoleAssignmentWorkspaceMemberPickerDropdown } from '@/settings/roles/role-assignment/components/RoleAssignmentWorkspaceMemberPickerDropdown';
|
||||
import { RoleAssignmentConfirmationModalSelectedWorkspaceMember } from '@/settings/roles/role-assignment/types/RoleAssignmentConfirmationModalSelectedWorkspaceMember';
|
||||
import { SettingsPath } from '@/types/SettingsPath';
|
||||
import { TextInput } from '@/ui/input/components/TextInput';
|
||||
import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown';
|
||||
@ -25,9 +28,6 @@ import {
|
||||
useUpdateWorkspaceMemberRoleMutation,
|
||||
} from '~/generated/graphql';
|
||||
import { useNavigateSettings } from '~/hooks/useNavigateSettings';
|
||||
import { RoleAssignmentTableHeader } from '~/pages/settings/roles/role-assignment/components/RoleAssignmentTableHeader';
|
||||
import { RoleAssignmentWorkspaceMemberPickerDropdown } from '~/pages/settings/roles/role-assignment/components/RoleAssignmentWorkspaceMemberPickerDropdown';
|
||||
import { RoleAssignmentConfirmationModalSelectedWorkspaceMember } from '~/pages/settings/roles/role-assignment/types/RoleAssignmentConfirmationModalSelectedWorkspaceMember';
|
||||
import { RoleAssignmentConfirmationModal } from './RoleAssignmentConfirmationModal';
|
||||
import { RoleAssignmentTableRow } from './RoleAssignmentTableRow';
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import { RoleAssignmentConfirmationModalSubtitle } from '@/settings/roles/role-assignment/components/RoleAssignmentConfirmationModalSubtitle';
|
||||
import { RoleAssignmentConfirmationModalSelectedWorkspaceMember } from '@/settings/roles/role-assignment/types/RoleAssignmentConfirmationModalSelectedWorkspaceMember';
|
||||
import { ConfirmationModal } from '@/ui/layout/modal/components/ConfirmationModal';
|
||||
import { t } from '@lingui/core/macro';
|
||||
import { RoleAssignmentConfirmationModalSubtitle } from '~/pages/settings/roles/role-assignment/components/RoleAssignmentConfirmationModalSubtitle';
|
||||
import { RoleAssignmentConfirmationModalSelectedWorkspaceMember } from '~/pages/settings/roles/role-assignment/types/RoleAssignmentConfirmationModalSelectedWorkspaceMember';
|
||||
|
||||
type RoleAssignmentConfirmationModalProps = {
|
||||
selectedWorkspaceMember: RoleAssignmentConfirmationModalSelectedWorkspaceMember;
|
||||
@ -1,8 +1,8 @@
|
||||
import { SettingsCard } from '@/settings/components/SettingsCard';
|
||||
import { RoleAssignmentConfirmationModalSelectedWorkspaceMember } from '@/settings/roles/role-assignment/types/RoleAssignmentConfirmationModalSelectedWorkspaceMember';
|
||||
import styled from '@emotion/styled';
|
||||
import { t } from '@lingui/core/macro';
|
||||
import { IconUser } from 'twenty-ui';
|
||||
import { RoleAssignmentConfirmationModalSelectedWorkspaceMember } from '~/pages/settings/roles/role-assignment/types/RoleAssignmentConfirmationModalSelectedWorkspaceMember';
|
||||
|
||||
const StyledSettingsCardContainer = styled.div`
|
||||
margin-top: ${({ theme }) => theme.spacing(2)};
|
||||
@ -1,12 +1,12 @@
|
||||
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
|
||||
import { useSearchRecords } from '@/object-record/hooks/useSearchRecords';
|
||||
import { RoleAssignmentWorkspaceMemberPickerDropdownContent } from '@/settings/roles/role-assignment/components/RoleAssignmentWorkspaceMemberPickerDropdownContent';
|
||||
import { DropdownMenu } from '@/ui/layout/dropdown/components/DropdownMenu';
|
||||
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
|
||||
import { DropdownMenuSearchInput } from '@/ui/layout/dropdown/components/DropdownMenuSearchInput';
|
||||
import { DropdownMenuSeparator } from '@/ui/layout/dropdown/components/DropdownMenuSeparator';
|
||||
import { ChangeEvent, useState } from 'react';
|
||||
import { WorkspaceMember } from '~/generated-metadata/graphql';
|
||||
import { RoleAssignmentWorkspaceMemberPickerDropdownContent } from '~/pages/settings/roles/role-assignment/components/RoleAssignmentWorkspaceMemberPickerDropdownContent';
|
||||
|
||||
type RoleAssignmentWorkspaceMemberPickerDropdownProps = {
|
||||
excludedWorkspaceMemberIds: string[];
|
||||
@ -1,3 +1,7 @@
|
||||
import { RolePermissionsObjectsTableHeader } from '@/settings/roles/role-permissions/components/RolePermissionsObjectsTableHeader';
|
||||
import { RolePermissionsSettingsTableHeader } from '@/settings/roles/role-permissions/components/RolePermissionsSettingsTableHeader';
|
||||
import { RolePermissionsSettingsTableRow } from '@/settings/roles/role-permissions/components/RolePermissionsSettingsTableRow';
|
||||
import { RolePermissionsObjectPermission } from '@/settings/roles/types/RolePermissionsObjectPermission';
|
||||
import styled from '@emotion/styled';
|
||||
import { t } from '@lingui/core/macro';
|
||||
import {
|
||||
@ -10,10 +14,6 @@ import {
|
||||
} from 'twenty-ui';
|
||||
import { Role } from '~/generated-metadata/graphql';
|
||||
import { SettingsPermissions } from '~/generated/graphql';
|
||||
import { RolePermissionsObjectsTableHeader } from '~/pages/settings/roles/role-permissions/components/RolePermissionsObjectsTableHeader';
|
||||
import { RolePermissionsSettingsTableHeader } from '~/pages/settings/roles/role-permissions/components/RolePermissionsSettingsTableHeader';
|
||||
import { RolePermissionsSettingsTableRow } from '~/pages/settings/roles/role-permissions/components/RolePermissionsSettingsTableRow';
|
||||
import { RolePermissionsObjectPermission } from '~/pages/settings/roles/types/RolePermissionsObjectPermission';
|
||||
import { RolePermissionsObjectsTableRow } from './RolePermissionsObjectsTableRow';
|
||||
|
||||
const StyledRolePermissionsContainer = styled.div`
|
||||
@ -1,8 +1,8 @@
|
||||
import { RolePermissionsObjectPermission } from '@/settings/roles/types/RolePermissionsObjectPermission';
|
||||
import { TableCell } from '@/ui/layout/table/components/TableCell';
|
||||
import { TableRow } from '@/ui/layout/table/components/TableRow';
|
||||
import styled from '@emotion/styled';
|
||||
import { Checkbox } from 'twenty-ui';
|
||||
import { RolePermissionsObjectPermission } from '~/pages/settings/roles/types/RolePermissionsObjectPermission';
|
||||
|
||||
const StyledIconWrapper = styled.div`
|
||||
align-items: center;
|
||||
@ -1,8 +1,8 @@
|
||||
import { RolePermissionsSettingPermission } from '@/settings/roles/types/RolePermissionsSettingPermission';
|
||||
import { TableCell } from '@/ui/layout/table/components/TableCell';
|
||||
import { TableRow } from '@/ui/layout/table/components/TableRow';
|
||||
import styled from '@emotion/styled';
|
||||
import { Checkbox } from 'twenty-ui';
|
||||
import { RolePermissionsSettingPermission } from '~/pages/settings/roles/types/RolePermissionsSettingPermission';
|
||||
|
||||
const StyledLabel = styled.span`
|
||||
color: ${({ theme }) => theme.font.color.primary};
|
||||
@ -24,6 +24,7 @@ const workspaceMember: Omit<
|
||||
lastName: 'lastName',
|
||||
},
|
||||
locale: 'en',
|
||||
colorScheme: 'System',
|
||||
};
|
||||
|
||||
describe('useColorScheme', () => {
|
||||
|
||||
@ -15,7 +15,7 @@ export type WorkspaceMember = {
|
||||
};
|
||||
avatarUrl?: string | null;
|
||||
locale: string | null;
|
||||
colorScheme?: ColorScheme;
|
||||
colorScheme: ColorScheme;
|
||||
createdAt: string;
|
||||
updatedAt: string;
|
||||
userEmail: string;
|
||||
|
||||
@ -11,16 +11,17 @@ import {
|
||||
} from 'twenty-ui';
|
||||
|
||||
import { SettingsPageContainer } from '@/settings/components/SettingsPageContainer';
|
||||
import { RoleAssignment } from '@/settings/roles/role-assignment/components/RoleAssignment';
|
||||
import { RolePermissions } from '@/settings/roles/role-permissions/components/RolePermissions';
|
||||
import { RoleSettings } from '@/settings/roles/role-settings/components/RoleSettings';
|
||||
import { SettingsPath } from '@/types/SettingsPath';
|
||||
import { SubMenuTopBarContainer } from '@/ui/layout/page/components/SubMenuTopBarContainer';
|
||||
import { TabList } from '@/ui/layout/tab/components/TabList';
|
||||
import { useTabList } from '@/ui/layout/tab/hooks/useTabList';
|
||||
import { useTheme } from '@emotion/react';
|
||||
import { useGetRolesQuery } from '~/generated/graphql';
|
||||
import { useNavigateSettings } from '~/hooks/useNavigateSettings';
|
||||
import { RolePermissions } from '~/pages/settings/roles/role-permissions/components/RolePermissions';
|
||||
import { RoleSettings } from '~/pages/settings/roles/role-settings/components/RoleSettings';
|
||||
import { getSettingsPath } from '~/utils/navigation/getSettingsPath';
|
||||
import { RoleAssignment } from './role-assignment/components/RoleAssignment';
|
||||
|
||||
const StyledContentContainer = styled.div`
|
||||
flex: 1;
|
||||
@ -49,6 +50,7 @@ export const SETTINGS_ROLE_DETAIL_TABS = {
|
||||
|
||||
export const SettingsRoleEdit = () => {
|
||||
const { roleId = '' } = useParams();
|
||||
const theme = useTheme();
|
||||
const navigateSettings = useNavigateSettings();
|
||||
const { data: rolesData, loading: rolesLoading } = useGetRolesQuery({
|
||||
fetchPolicy: 'network-only',
|
||||
@ -106,7 +108,7 @@ export const SettingsRoleEdit = () => {
|
||||
<SubMenuTopBarContainer
|
||||
title={
|
||||
<StyledTitleContainer>
|
||||
<StyledIconUser size={16} />
|
||||
<StyledIconUser size={theme.icon.size.md} />
|
||||
<H3Title title={role.label} />
|
||||
</StyledTitleContainer>
|
||||
}
|
||||
|
||||
@ -1,11 +1,11 @@
|
||||
import { Trans, useLingui } from '@lingui/react/macro';
|
||||
|
||||
import { SettingsPageContainer } from '@/settings/components/SettingsPageContainer';
|
||||
import { Roles } from '@/settings/roles/components/Roles';
|
||||
import { RolesDefaultRole } from '@/settings/roles/components/RolesDefaultRole';
|
||||
import { SettingsPath } from '@/types/SettingsPath';
|
||||
import { SubMenuTopBarContainer } from '@/ui/layout/page/components/SubMenuTopBarContainer';
|
||||
import { useGetRolesQuery } from '~/generated/graphql';
|
||||
import { Roles } from '~/pages/settings/roles/components/Roles';
|
||||
import { RolesDefaultRole } from '~/pages/settings/roles/components/RolesDefaultRole';
|
||||
import { getSettingsPath } from '~/utils/navigation/getSettingsPath';
|
||||
|
||||
export const SettingsRoles = () => {
|
||||
|
||||
@ -0,0 +1,30 @@
|
||||
import { Meta, StoryObj } from '@storybook/react';
|
||||
|
||||
import {
|
||||
PageDecorator,
|
||||
PageDecoratorArgs,
|
||||
} from '~/testing/decorators/PageDecorator';
|
||||
import { graphqlMocks } from '~/testing/graphqlMocks';
|
||||
|
||||
import { SettingsRoleEdit } from '../SettingsRoleEdit';
|
||||
|
||||
const meta: Meta<PageDecoratorArgs> = {
|
||||
title: 'Pages/Settings/Roles/SettingsRoleEdit',
|
||||
component: SettingsRoleEdit,
|
||||
decorators: [PageDecorator],
|
||||
args: {
|
||||
routePath: '/settings/roles/:roleId',
|
||||
routeParams: {
|
||||
':roleId': '1',
|
||||
},
|
||||
},
|
||||
parameters: {
|
||||
msw: graphqlMocks,
|
||||
},
|
||||
};
|
||||
|
||||
export default meta;
|
||||
|
||||
export type Story = StoryObj<typeof SettingsRoleEdit>;
|
||||
|
||||
export const Default: Story = {};
|
||||
@ -0,0 +1,25 @@
|
||||
import { Meta, StoryObj } from '@storybook/react';
|
||||
|
||||
import {
|
||||
PageDecorator,
|
||||
PageDecoratorArgs,
|
||||
} from '~/testing/decorators/PageDecorator';
|
||||
import { graphqlMocks } from '~/testing/graphqlMocks';
|
||||
|
||||
import { SettingsRoles } from '../SettingsRoles';
|
||||
|
||||
const meta: Meta<PageDecoratorArgs> = {
|
||||
title: 'Pages/Settings/Roles/SettingsRoles',
|
||||
component: SettingsRoles,
|
||||
decorators: [PageDecorator],
|
||||
args: { routePath: '/settings/roles' },
|
||||
parameters: {
|
||||
msw: graphqlMocks,
|
||||
},
|
||||
};
|
||||
|
||||
export default meta;
|
||||
|
||||
export type Story = StoryObj<typeof SettingsRoles>;
|
||||
|
||||
export const Default: Story = {};
|
||||
@ -21,7 +21,9 @@ import { mockedViewsData } from '~/testing/mock-data/views';
|
||||
import { mockWorkspaceMembers } from '~/testing/mock-data/workspace-members';
|
||||
|
||||
import { GET_PUBLIC_WORKSPACE_DATA_BY_DOMAIN } from '@/auth/graphql/queries/getPublicWorkspaceDataByDomain';
|
||||
import { GET_ROLES } from '@/settings/roles/graphql/queries/getRolesQuery';
|
||||
import { mockedStandardObjectMetadataQueryResult } from '~/testing/mock-data/generated/mock-metadata-query-result';
|
||||
import { getRolesMock } from '~/testing/mock-data/roles';
|
||||
import { mockedTasks } from '~/testing/mock-data/tasks';
|
||||
import {
|
||||
getWorkflowMock,
|
||||
@ -719,6 +721,13 @@ export const graphqlMocks = {
|
||||
},
|
||||
});
|
||||
}),
|
||||
graphql.query(getOperationName(GET_ROLES) ?? '', () => {
|
||||
return HttpResponse.json({
|
||||
data: {
|
||||
getRoles: getRolesMock(),
|
||||
},
|
||||
});
|
||||
}),
|
||||
http.get('https://chat-assets.frontapp.com/v1/chat.bundle.js', () => {
|
||||
return HttpResponse.text(
|
||||
`
|
||||
|
||||
33
packages/twenty-front/src/testing/mock-data/roles.ts
Normal file
33
packages/twenty-front/src/testing/mock-data/roles.ts
Normal file
@ -0,0 +1,33 @@
|
||||
import { Role } from '~/generated/graphql';
|
||||
import { mockWorkspaceMembers } from '~/testing/mock-data/workspace-members';
|
||||
|
||||
const rolesMock: Role[] = [
|
||||
{
|
||||
__typename: 'Role',
|
||||
id: '1',
|
||||
label: 'Admin',
|
||||
canDestroyAllObjectRecords: true,
|
||||
canReadAllObjectRecords: true,
|
||||
canSoftDeleteAllObjectRecords: true,
|
||||
canUpdateAllObjectRecords: true,
|
||||
canUpdateAllSettings: true,
|
||||
isEditable: false,
|
||||
workspaceMembers: [mockWorkspaceMembers[0]],
|
||||
},
|
||||
{
|
||||
__typename: 'Role',
|
||||
id: '2',
|
||||
label: 'Guest',
|
||||
canDestroyAllObjectRecords: false,
|
||||
canReadAllObjectRecords: false,
|
||||
canSoftDeleteAllObjectRecords: false,
|
||||
canUpdateAllObjectRecords: false,
|
||||
canUpdateAllSettings: false,
|
||||
isEditable: true,
|
||||
workspaceMembers: [mockWorkspaceMembers[1]],
|
||||
},
|
||||
];
|
||||
|
||||
export const getRolesMock = () => {
|
||||
return rolesMock;
|
||||
};
|
||||
Reference in New Issue
Block a user