New behavior for editable fields (#1300)
* New behavior for editable fields * fix * fix * fix coverage * Add tests on NotFound * fix * fix --------- Co-authored-by: Charles Bochet <charles@twenty.com>
This commit is contained in:
@ -15,12 +15,12 @@ import { People } from '~/pages/people/People';
|
|||||||
import { PersonShow } from '~/pages/people/PersonShow';
|
import { PersonShow } from '~/pages/people/PersonShow';
|
||||||
import { SettingsExperience } from '~/pages/settings/SettingsExperience';
|
import { SettingsExperience } from '~/pages/settings/SettingsExperience';
|
||||||
import { SettingsProfile } from '~/pages/settings/SettingsProfile';
|
import { SettingsProfile } from '~/pages/settings/SettingsProfile';
|
||||||
import { SettingsWorksapce } from '~/pages/settings/SettingsWorkspace';
|
import { SettingsWorkspace } from '~/pages/settings/SettingsWorkspace';
|
||||||
import { SettingsWorkspaceMembers } from '~/pages/settings/SettingsWorkspaceMembers';
|
import { SettingsWorkspaceMembers } from '~/pages/settings/SettingsWorkspaceMembers';
|
||||||
import { Tasks } from '~/pages/tasks/Tasks';
|
import { Tasks } from '~/pages/tasks/Tasks';
|
||||||
import { AppInternalHooks } from '~/sync-hooks/AppInternalHooks';
|
import { AppInternalHooks } from '~/sync-hooks/AppInternalHooks';
|
||||||
|
|
||||||
import { NotFound } from './NotFound';
|
import { NotFound } from './pages/not-found/NotFound';
|
||||||
|
|
||||||
// TEMP FEATURE FLAG FOR VIEW FIELDS
|
// TEMP FEATURE FLAG FOR VIEW FIELDS
|
||||||
export const ACTIVATE_VIEW_FIELDS = true;
|
export const ACTIVATE_VIEW_FIELDS = true;
|
||||||
@ -64,7 +64,7 @@ export function App() {
|
|||||||
/>
|
/>
|
||||||
<Route
|
<Route
|
||||||
path={SettingsPath.Workspace}
|
path={SettingsPath.Workspace}
|
||||||
element={<SettingsWorksapce />}
|
element={<SettingsWorkspace />}
|
||||||
/>
|
/>
|
||||||
</Routes>
|
</Routes>
|
||||||
}
|
}
|
||||||
|
|||||||
@ -36,6 +36,7 @@ export function ActivityRelationEditableField({ activity }: OwnProps) {
|
|||||||
displayModeContent={
|
displayModeContent={
|
||||||
<ActivityTargetChips targets={activity?.activityTargets} />
|
<ActivityTargetChips targets={activity?.activityTargets} />
|
||||||
}
|
}
|
||||||
|
isDisplayModeContentEmpty={activity?.activityTargets?.length === 0}
|
||||||
/>
|
/>
|
||||||
</RecoilScope>
|
</RecoilScope>
|
||||||
</RecoilScope>
|
</RecoilScope>
|
||||||
|
|||||||
@ -1,26 +0,0 @@
|
|||||||
import { useRecoilState } from 'recoil';
|
|
||||||
|
|
||||||
import { useRightDrawer } from '@/ui/right-drawer/hooks/useRightDrawer';
|
|
||||||
import { RightDrawerHotkeyScope } from '@/ui/right-drawer/types/RightDrawerHotkeyScope';
|
|
||||||
import { RightDrawerPages } from '@/ui/right-drawer/types/RightDrawerPages';
|
|
||||||
import { useSetHotkeyScope } from '@/ui/utilities/hotkey/hooks/useSetHotkeyScope';
|
|
||||||
|
|
||||||
import { activityTargetableEntityArrayState } from '../states/activityTargetableEntityArrayState';
|
|
||||||
import { ActivityTargetableEntity } from '../types/ActivityTargetableEntity';
|
|
||||||
|
|
||||||
// TODO: refactor with recoil callback to avoid rerender
|
|
||||||
export function useOpenTimelineRightDrawer() {
|
|
||||||
const { openRightDrawer } = useRightDrawer();
|
|
||||||
const [, setActivityTargetableEntityArray] = useRecoilState(
|
|
||||||
activityTargetableEntityArrayState,
|
|
||||||
);
|
|
||||||
const setHotkeyScope = useSetHotkeyScope();
|
|
||||||
|
|
||||||
return function openTimelineRightDrawer(
|
|
||||||
activityTargetableEntityArray: ActivityTargetableEntity[],
|
|
||||||
) {
|
|
||||||
setHotkeyScope(RightDrawerHotkeyScope.RightDrawer, { goto: false });
|
|
||||||
setActivityTargetableEntityArray(activityTargetableEntityArray);
|
|
||||||
openRightDrawer(RightDrawerPages.Timeline);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@ -1,24 +0,0 @@
|
|||||||
import { useRecoilValue } from 'recoil';
|
|
||||||
|
|
||||||
import { activityTargetableEntityArrayState } from '@/activities/states/activityTargetableEntityArrayState';
|
|
||||||
import { Timeline } from '@/activities/timeline/components/Timeline';
|
|
||||||
|
|
||||||
export function RightDrawerTimeline() {
|
|
||||||
const activityTargetableEntityArray = useRecoilValue(
|
|
||||||
activityTargetableEntityArrayState,
|
|
||||||
);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
{activityTargetableEntityArray.map((targetableEntity) => (
|
|
||||||
<Timeline
|
|
||||||
key={targetableEntity.id}
|
|
||||||
entity={{
|
|
||||||
id: targetableEntity?.id ?? '',
|
|
||||||
type: targetableEntity.type,
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
))}
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@ -34,7 +34,6 @@ const StyledLabelAndIconContainer = styled.div`
|
|||||||
|
|
||||||
const StyledValueContainer = styled.div`
|
const StyledValueContainer = styled.div`
|
||||||
display: flex;
|
display: flex;
|
||||||
flex: 1;
|
|
||||||
max-width: calc(100% - ${({ theme }) => theme.spacing(4)});
|
max-width: calc(100% - ${({ theme }) => theme.spacing(4)});
|
||||||
`;
|
`;
|
||||||
|
|
||||||
@ -46,21 +45,28 @@ const StyledLabel = styled.div<Pick<OwnProps, 'labelFixedWidth'>>`
|
|||||||
`;
|
`;
|
||||||
|
|
||||||
const StyledEditButtonContainer = styled(motion.div)`
|
const StyledEditButtonContainer = styled(motion.div)`
|
||||||
position: absolute;
|
align-items: center;
|
||||||
right: 0;
|
display: flex;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export const StyledEditableFieldBaseContainer = styled.div`
|
const StyledClickableContainer = styled.div`
|
||||||
|
cursor: pointer;
|
||||||
|
display: flex;
|
||||||
|
gap: ${({ theme }) => theme.spacing(1)};
|
||||||
|
width: 100%;
|
||||||
|
`;
|
||||||
|
|
||||||
|
const StyledEditableFieldBaseContainer = styled.div`
|
||||||
align-items: center;
|
align-items: center;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
|
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|
||||||
gap: ${({ theme }) => theme.spacing(1)};
|
gap: ${({ theme }) => theme.spacing(1)};
|
||||||
|
|
||||||
justify-content: space-between;
|
|
||||||
position: relative;
|
position: relative;
|
||||||
|
|
||||||
user-select: none;
|
user-select: none;
|
||||||
|
|
||||||
width: 100%;
|
width: 100%;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
@ -71,11 +77,11 @@ type OwnProps = {
|
|||||||
useEditButton?: boolean;
|
useEditButton?: boolean;
|
||||||
editModeContent?: React.ReactNode;
|
editModeContent?: React.ReactNode;
|
||||||
displayModeContentOnly?: boolean;
|
displayModeContentOnly?: boolean;
|
||||||
disableHoverEffect?: boolean;
|
|
||||||
displayModeContent: React.ReactNode;
|
displayModeContent: React.ReactNode;
|
||||||
customEditHotkeyScope?: HotkeyScope;
|
customEditHotkeyScope?: HotkeyScope;
|
||||||
isDisplayModeContentEmpty?: boolean;
|
isDisplayModeContentEmpty?: boolean;
|
||||||
isDisplayModeFixHeight?: boolean;
|
isDisplayModeFixHeight?: boolean;
|
||||||
|
disableHoverEffect?: boolean;
|
||||||
onSubmit?: () => void;
|
onSubmit?: () => void;
|
||||||
onCancel?: () => void;
|
onCancel?: () => void;
|
||||||
};
|
};
|
||||||
@ -88,10 +94,10 @@ export function EditableField({
|
|||||||
editModeContent,
|
editModeContent,
|
||||||
displayModeContent,
|
displayModeContent,
|
||||||
customEditHotkeyScope,
|
customEditHotkeyScope,
|
||||||
disableHoverEffect,
|
|
||||||
isDisplayModeContentEmpty,
|
isDisplayModeContentEmpty,
|
||||||
displayModeContentOnly,
|
displayModeContentOnly,
|
||||||
isDisplayModeFixHeight,
|
isDisplayModeFixHeight,
|
||||||
|
disableHoverEffect,
|
||||||
onSubmit,
|
onSubmit,
|
||||||
onCancel,
|
onCancel,
|
||||||
}: OwnProps) {
|
}: OwnProps) {
|
||||||
@ -124,33 +130,35 @@ export function EditableField({
|
|||||||
<StyledLabel labelFixedWidth={labelFixedWidth}>{label}</StyledLabel>
|
<StyledLabel labelFixedWidth={labelFixedWidth}>{label}</StyledLabel>
|
||||||
)}
|
)}
|
||||||
</StyledLabelAndIconContainer>
|
</StyledLabelAndIconContainer>
|
||||||
|
|
||||||
<StyledValueContainer>
|
<StyledValueContainer>
|
||||||
{isFieldInEditMode && !displayModeContentOnly ? (
|
{isFieldInEditMode && !displayModeContentOnly ? (
|
||||||
<EditableFieldEditMode onSubmit={onSubmit} onCancel={onCancel}>
|
<EditableFieldEditMode onSubmit={onSubmit} onCancel={onCancel}>
|
||||||
{editModeContent}
|
{editModeContent}
|
||||||
</EditableFieldEditMode>
|
</EditableFieldEditMode>
|
||||||
) : (
|
) : (
|
||||||
<EditableFieldDisplayMode
|
<StyledClickableContainer onClick={handleDisplayModeClick}>
|
||||||
disableHoverEffect={disableHoverEffect}
|
<EditableFieldDisplayMode
|
||||||
disableClick={useEditButton}
|
disableHoverEffect={disableHoverEffect}
|
||||||
onClick={handleDisplayModeClick}
|
isDisplayModeContentEmpty={isDisplayModeContentEmpty}
|
||||||
isDisplayModeContentEmpty={isDisplayModeContentEmpty}
|
isDisplayModeFixHeight={isDisplayModeFixHeight}
|
||||||
isDisplayModeFixHeight={isDisplayModeFixHeight}
|
isHovered={isHovered}
|
||||||
>
|
>
|
||||||
{displayModeContent}
|
{displayModeContent}
|
||||||
</EditableFieldDisplayMode>
|
</EditableFieldDisplayMode>
|
||||||
|
{showEditButton && (
|
||||||
|
<StyledEditButtonContainer
|
||||||
|
initial={{ opacity: 0 }}
|
||||||
|
animate={{ opacity: 1 }}
|
||||||
|
transition={{ duration: 0.1 }}
|
||||||
|
whileHover={{ scale: 1.04 }}
|
||||||
|
>
|
||||||
|
<EditableFieldEditButton />
|
||||||
|
</StyledEditButtonContainer>
|
||||||
|
)}
|
||||||
|
</StyledClickableContainer>
|
||||||
)}
|
)}
|
||||||
</StyledValueContainer>
|
</StyledValueContainer>
|
||||||
{showEditButton && (
|
|
||||||
<StyledEditButtonContainer
|
|
||||||
initial={{ opacity: 0 }}
|
|
||||||
animate={{ opacity: 1 }}
|
|
||||||
transition={{ duration: 0.1 }}
|
|
||||||
whileHover={{ scale: 1.04 }}
|
|
||||||
>
|
|
||||||
<EditableFieldEditButton />
|
|
||||||
</StyledEditButtonContainer>
|
|
||||||
)}
|
|
||||||
</StyledEditableFieldBaseContainer>
|
</StyledEditableFieldBaseContainer>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,10 +4,10 @@ import styled from '@emotion/styled';
|
|||||||
const StyledEditableFieldNormalModeOuterContainer = styled.div<
|
const StyledEditableFieldNormalModeOuterContainer = styled.div<
|
||||||
Pick<
|
Pick<
|
||||||
OwnProps,
|
OwnProps,
|
||||||
| 'disableClick'
|
|
||||||
| 'isDisplayModeContentEmpty'
|
| 'isDisplayModeContentEmpty'
|
||||||
| 'disableHoverEffect'
|
| 'disableHoverEffect'
|
||||||
| 'isDisplayModeFixHeight'
|
| 'isDisplayModeFixHeight'
|
||||||
|
| 'isHovered'
|
||||||
>
|
>
|
||||||
>`
|
>`
|
||||||
align-items: center;
|
align-items: center;
|
||||||
@ -20,26 +20,13 @@ const StyledEditableFieldNormalModeOuterContainer = styled.div<
|
|||||||
padding: ${({ theme }) => theme.spacing(1)};
|
padding: ${({ theme }) => theme.spacing(1)};
|
||||||
|
|
||||||
${(props) => {
|
${(props) => {
|
||||||
if (!props.isDisplayModeContentEmpty) {
|
if (props.isHovered) {
|
||||||
return css`
|
return css`
|
||||||
width: fit-content;
|
background-color: ${!props.disableHoverEffect
|
||||||
`;
|
? props.theme.background.transparent.lighter
|
||||||
}
|
: 'transparent'};
|
||||||
}}
|
|
||||||
|
|
||||||
${(props) => {
|
|
||||||
if (props.disableClick) {
|
|
||||||
return css`
|
|
||||||
cursor: default;
|
|
||||||
`;
|
|
||||||
} else {
|
|
||||||
return css`
|
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
|
||||||
&:hover {
|
|
||||||
background-color: ${!props.disableHoverEffect &&
|
|
||||||
props.theme.background.transparent.light};
|
|
||||||
}
|
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
@ -64,28 +51,25 @@ const StyledEmptyField = styled.div`
|
|||||||
`;
|
`;
|
||||||
|
|
||||||
type OwnProps = {
|
type OwnProps = {
|
||||||
disableClick?: boolean;
|
|
||||||
onClick?: () => void;
|
|
||||||
isDisplayModeContentEmpty?: boolean;
|
isDisplayModeContentEmpty?: boolean;
|
||||||
disableHoverEffect?: boolean;
|
disableHoverEffect?: boolean;
|
||||||
isDisplayModeFixHeight?: boolean;
|
isDisplayModeFixHeight?: boolean;
|
||||||
|
isHovered?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
export function EditableFieldDisplayMode({
|
export function EditableFieldDisplayMode({
|
||||||
children,
|
children,
|
||||||
disableClick,
|
|
||||||
onClick,
|
|
||||||
isDisplayModeContentEmpty,
|
isDisplayModeContentEmpty,
|
||||||
disableHoverEffect,
|
disableHoverEffect,
|
||||||
isDisplayModeFixHeight,
|
isDisplayModeFixHeight,
|
||||||
|
isHovered,
|
||||||
}: React.PropsWithChildren<OwnProps>) {
|
}: React.PropsWithChildren<OwnProps>) {
|
||||||
return (
|
return (
|
||||||
<StyledEditableFieldNormalModeOuterContainer
|
<StyledEditableFieldNormalModeOuterContainer
|
||||||
onClick={disableClick ? undefined : onClick}
|
|
||||||
disableClick={disableClick}
|
|
||||||
isDisplayModeContentEmpty={isDisplayModeContentEmpty}
|
isDisplayModeContentEmpty={isDisplayModeContentEmpty}
|
||||||
disableHoverEffect={disableHoverEffect}
|
disableHoverEffect={disableHoverEffect}
|
||||||
isDisplayModeFixHeight={isDisplayModeFixHeight}
|
isDisplayModeFixHeight={isDisplayModeFixHeight}
|
||||||
|
isHovered={isHovered}
|
||||||
>
|
>
|
||||||
<StyledEditableFieldNormalModeInnerContainer>
|
<StyledEditableFieldNormalModeInnerContainer>
|
||||||
{isDisplayModeContentEmpty || !children ? (
|
{isDisplayModeContentEmpty || !children ? (
|
||||||
|
|||||||
@ -1,30 +1,8 @@
|
|||||||
import styled from '@emotion/styled';
|
|
||||||
|
|
||||||
import { IconButton } from '@/ui/button/components/IconButton';
|
import { IconButton } from '@/ui/button/components/IconButton';
|
||||||
import { IconPencil } from '@/ui/icon';
|
import { IconPencil } from '@/ui/icon';
|
||||||
import { overlayBackground } from '@/ui/theme/constants/effects';
|
|
||||||
|
|
||||||
import { useEditableField } from '../hooks/useEditableField';
|
import { useEditableField } from '../hooks/useEditableField';
|
||||||
|
|
||||||
export const StyledEditableFieldEditButton = styled.div`
|
|
||||||
align-items: center;
|
|
||||||
border: 1px solid ${({ theme }) => theme.border.color.light};
|
|
||||||
border-radius: ${({ theme }) => theme.border.radius.sm};
|
|
||||||
|
|
||||||
color: ${({ theme }) => theme.font.color.tertiary};
|
|
||||||
|
|
||||||
cursor: pointer;
|
|
||||||
display: flex;
|
|
||||||
height: 20px;
|
|
||||||
justify-content: center;
|
|
||||||
|
|
||||||
margin-left: -2px;
|
|
||||||
width: 20px;
|
|
||||||
|
|
||||||
z-index: 1;
|
|
||||||
${overlayBackground}
|
|
||||||
`;
|
|
||||||
|
|
||||||
export function EditableFieldEditButton() {
|
export function EditableFieldEditButton() {
|
||||||
const { openEditableField } = useEditableField();
|
const { openEditableField } = useEditableField();
|
||||||
|
|
||||||
|
|||||||
@ -11,8 +11,6 @@ const StyledEditableFieldEditModeContainer = styled.div<OwnProps>`
|
|||||||
|
|
||||||
margin-left: -${({ theme }) => theme.spacing(1)};
|
margin-left: -${({ theme }) => theme.spacing(1)};
|
||||||
position: relative;
|
position: relative;
|
||||||
|
|
||||||
width: 100%;
|
|
||||||
z-index: 10;
|
z-index: 10;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
|||||||
@ -37,6 +37,7 @@ export function GenericEditableURLField() {
|
|||||||
editModeContent={<GenericEditableURLFieldEditMode />}
|
editModeContent={<GenericEditableURLFieldEditMode />}
|
||||||
displayModeContent={<FieldDisplayURL URL={fieldValue} />}
|
displayModeContent={<FieldDisplayURL URL={fieldValue} />}
|
||||||
isDisplayModeContentEmpty={!fieldValue}
|
isDisplayModeContentEmpty={!fieldValue}
|
||||||
|
isDisplayModeFixHeight
|
||||||
/>
|
/>
|
||||||
</RecoilScope>
|
</RecoilScope>
|
||||||
);
|
);
|
||||||
|
|||||||
@ -3,7 +3,6 @@ import { useRecoilState } from 'recoil';
|
|||||||
|
|
||||||
import { RightDrawerCreateActivity } from '@/activities/right-drawer/components/create/RightDrawerCreateActivity';
|
import { RightDrawerCreateActivity } from '@/activities/right-drawer/components/create/RightDrawerCreateActivity';
|
||||||
import { RightDrawerEditActivity } from '@/activities/right-drawer/components/edit/RightDrawerEditActivity';
|
import { RightDrawerEditActivity } from '@/activities/right-drawer/components/edit/RightDrawerEditActivity';
|
||||||
import { RightDrawerTimeline } from '@/activities/right-drawer/components/RightDrawerTimeline';
|
|
||||||
|
|
||||||
import { rightDrawerPageState } from '../states/rightDrawerPageState';
|
import { rightDrawerPageState } from '../states/rightDrawerPageState';
|
||||||
import { RightDrawerPages } from '../types/RightDrawerPages';
|
import { RightDrawerPages } from '../types/RightDrawerPages';
|
||||||
@ -33,9 +32,6 @@ export function RightDrawerRouter() {
|
|||||||
let page = <></>;
|
let page = <></>;
|
||||||
|
|
||||||
switch (rightDrawerPage) {
|
switch (rightDrawerPage) {
|
||||||
case RightDrawerPages.Timeline:
|
|
||||||
page = <RightDrawerTimeline />;
|
|
||||||
break;
|
|
||||||
case RightDrawerPages.CreateActivity:
|
case RightDrawerPages.CreateActivity:
|
||||||
page = <RightDrawerCreateActivity />;
|
page = <RightDrawerCreateActivity />;
|
||||||
break;
|
break;
|
||||||
|
|||||||
@ -1,5 +1,4 @@
|
|||||||
export enum RightDrawerPages {
|
export enum RightDrawerPages {
|
||||||
Timeline = 'timeline',
|
|
||||||
CreateActivity = 'create-activity',
|
CreateActivity = 'create-activity',
|
||||||
EditActivity = 'edit-activity',
|
EditActivity = 'edit-activity',
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,7 +4,7 @@ import styled from '@emotion/styled';
|
|||||||
import { MainButton } from '@/ui/button/components/MainButton';
|
import { MainButton } from '@/ui/button/components/MainButton';
|
||||||
import { useIsMobile } from '@/ui/utilities/responsive/hooks/useIsMobile';
|
import { useIsMobile } from '@/ui/utilities/responsive/hooks/useIsMobile';
|
||||||
|
|
||||||
import { CompaniesMockMode } from './pages/companies/CompaniesMockMode';
|
import { CompaniesMockMode } from '../companies/CompaniesMockMode';
|
||||||
|
|
||||||
const StyledBackDrop = styled.div`
|
const StyledBackDrop = styled.div`
|
||||||
align-items: center;
|
align-items: center;
|
||||||
31
front/src/pages/not-found/__stories__/NotFound.stories.tsx
Normal file
31
front/src/pages/not-found/__stories__/NotFound.stories.tsx
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
import { Meta, StoryObj } from '@storybook/react';
|
||||||
|
import { within } from '@storybook/testing-library';
|
||||||
|
|
||||||
|
import { ComponentWithRouterDecorator } from '~/testing/decorators/ComponentWithRouterDecorator';
|
||||||
|
import { PageDecoratorArgs } from '~/testing/decorators/PageDecorator';
|
||||||
|
import { graphqlMocks } from '~/testing/graphqlMocks';
|
||||||
|
|
||||||
|
import { NotFound } from '../NotFound';
|
||||||
|
const meta: Meta<PageDecoratorArgs> = {
|
||||||
|
title: 'Pages/NotFound/Default',
|
||||||
|
component: NotFound,
|
||||||
|
decorators: [ComponentWithRouterDecorator],
|
||||||
|
args: {
|
||||||
|
routePath: 'toto-not-found',
|
||||||
|
},
|
||||||
|
parameters: {
|
||||||
|
docs: { story: 'inline', iframeHeight: '500px' },
|
||||||
|
msw: graphqlMocks,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export default meta;
|
||||||
|
|
||||||
|
export type Story = StoryObj<typeof NotFound>;
|
||||||
|
|
||||||
|
export const Default: Story = {
|
||||||
|
play: async ({ canvasElement }) => {
|
||||||
|
const canvas = within(canvasElement);
|
||||||
|
await canvas.findByText('Page not found');
|
||||||
|
},
|
||||||
|
};
|
||||||
@ -41,7 +41,7 @@ export const AddCompanyFromHeader: Story = {
|
|||||||
|
|
||||||
await button.click();
|
await button.click();
|
||||||
|
|
||||||
await canvas.findByText('Airbnb');
|
await canvas.findByText('Algolia');
|
||||||
});
|
});
|
||||||
|
|
||||||
await step('Change pipeline stage', async () => {
|
await step('Change pipeline stage', async () => {
|
||||||
|
|||||||
@ -16,7 +16,7 @@ const StyledContainer = styled.div`
|
|||||||
width: 350px;
|
width: 350px;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export function SettingsWorksapce() {
|
export function SettingsWorkspace() {
|
||||||
return (
|
return (
|
||||||
<SubMenuTopBarContainer icon={<IconSettings size={16} />} title="Settings">
|
<SubMenuTopBarContainer icon={<IconSettings size={16} />} title="Settings">
|
||||||
<div>
|
<div>
|
||||||
|
|||||||
@ -0,0 +1,26 @@
|
|||||||
|
import type { Meta, StoryObj } from '@storybook/react';
|
||||||
|
|
||||||
|
import {
|
||||||
|
PageDecorator,
|
||||||
|
type PageDecoratorArgs,
|
||||||
|
} from '~/testing/decorators/PageDecorator';
|
||||||
|
import { graphqlMocks } from '~/testing/graphqlMocks';
|
||||||
|
|
||||||
|
import { SettingsExperience } from '../SettingsExperience';
|
||||||
|
|
||||||
|
const meta: Meta<PageDecoratorArgs> = {
|
||||||
|
title: 'Pages/Settings/SettingsExperience',
|
||||||
|
component: SettingsExperience,
|
||||||
|
decorators: [PageDecorator],
|
||||||
|
args: { routePath: '/settings/experience' },
|
||||||
|
parameters: {
|
||||||
|
docs: { story: 'inline', iframeHeight: '500px' },
|
||||||
|
msw: graphqlMocks,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export default meta;
|
||||||
|
|
||||||
|
export type Story = StoryObj<typeof SettingsExperience>;
|
||||||
|
|
||||||
|
export const Default: Story = {};
|
||||||
@ -0,0 +1,26 @@
|
|||||||
|
import type { Meta, StoryObj } from '@storybook/react';
|
||||||
|
|
||||||
|
import {
|
||||||
|
PageDecorator,
|
||||||
|
type PageDecoratorArgs,
|
||||||
|
} from '~/testing/decorators/PageDecorator';
|
||||||
|
import { graphqlMocks } from '~/testing/graphqlMocks';
|
||||||
|
|
||||||
|
import { SettingsWorkspace } from '../SettingsWorkspace';
|
||||||
|
|
||||||
|
const meta: Meta<PageDecoratorArgs> = {
|
||||||
|
title: 'Pages/Settings/SettingsWorkspace',
|
||||||
|
component: SettingsWorkspace,
|
||||||
|
decorators: [PageDecorator],
|
||||||
|
args: { routePath: '/settings/workspace' },
|
||||||
|
parameters: {
|
||||||
|
docs: { story: 'inline', iframeHeight: '500px' },
|
||||||
|
msw: graphqlMocks,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export default meta;
|
||||||
|
|
||||||
|
export type Story = StoryObj<typeof SettingsWorkspace>;
|
||||||
|
|
||||||
|
export const Default: Story = {};
|
||||||
Reference in New Issue
Block a user