Fix margin on DeleteModal overlay (#998)
* Fix margin on DeleteModal overlay * Update chromatic ci triggers * Update chromatic ci triggers
This commit is contained in:
3
.github/workflows/ci-chromatic.yaml
vendored
3
.github/workflows/ci-chromatic.yaml
vendored
@ -5,9 +5,10 @@ on:
|
|||||||
branches:
|
branches:
|
||||||
- main
|
- main
|
||||||
pull_request_target:
|
pull_request_target:
|
||||||
|
types: [labeled, opened, edited]
|
||||||
jobs:
|
jobs:
|
||||||
chromatic-deployment:
|
chromatic-deployment:
|
||||||
if: ${{ github.event.label.name == 'run-chromatic' || github.event_name == 'push' }}
|
if: ${{ contains(github.event.*.labels.*.name, 'run-chromatic') }} || github.event_name == 'push' }}
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
env:
|
env:
|
||||||
REACT_APP_API_URL: http://127.0.0.1:3000/graphql
|
REACT_APP_API_URL: http://127.0.0.1:3000/graphql
|
||||||
|
|||||||
@ -4,7 +4,7 @@ import { useNavigate } from 'react-router-dom';
|
|||||||
import { useAuth } from '@/auth/hooks/useAuth';
|
import { useAuth } from '@/auth/hooks/useAuth';
|
||||||
import { AppPath } from '@/types/AppPath';
|
import { AppPath } from '@/types/AppPath';
|
||||||
import { ButtonVariant } from '@/ui/button/components/Button';
|
import { ButtonVariant } from '@/ui/button/components/Button';
|
||||||
import { SubSectionTitle } from '@/ui/title/components/SubSectionTitle';
|
import { H2Title } from '@/ui/title/components/H2Title';
|
||||||
import { useDeleteUserAccountMutation } from '~/generated/graphql';
|
import { useDeleteUserAccountMutation } from '~/generated/graphql';
|
||||||
|
|
||||||
import { DeleteModal, StyledDeleteButton } from './DeleteModal';
|
import { DeleteModal, StyledDeleteButton } from './DeleteModal';
|
||||||
@ -29,7 +29,7 @@ export function DeleteAccount() {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<SubSectionTitle
|
<H2Title
|
||||||
title="Danger zone"
|
title="Danger zone"
|
||||||
description="Delete account and all the associated data"
|
description="Delete account and all the associated data"
|
||||||
/>
|
/>
|
||||||
|
|||||||
@ -7,6 +7,8 @@ import { currentUserState } from '@/auth/states/currentUserState';
|
|||||||
import { Button, ButtonVariant } from '@/ui/button/components/Button';
|
import { Button, ButtonVariant } from '@/ui/button/components/Button';
|
||||||
import { TextInput } from '@/ui/input/components/TextInput';
|
import { TextInput } from '@/ui/input/components/TextInput';
|
||||||
import { Modal } from '@/ui/modal/components/Modal';
|
import { Modal } from '@/ui/modal/components/Modal';
|
||||||
|
import { Section, SectionAlignment } from '@/ui/section/components/Section';
|
||||||
|
import { H1Title, H1TitleFontColor } from '@/ui/title/components/H1Title';
|
||||||
import { debounce } from '~/utils/debounce';
|
import { debounce } from '~/utils/debounce';
|
||||||
|
|
||||||
interface DeleteModalProps {
|
interface DeleteModalProps {
|
||||||
@ -18,22 +20,6 @@ interface DeleteModalProps {
|
|||||||
deleteButtonText?: string;
|
deleteButtonText?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
const StyledTitle = styled.div`
|
|
||||||
font-size: ${({ theme }) => theme.font.size.lg};
|
|
||||||
font-weight: ${({ theme }) => theme.font.weight.semiBold};
|
|
||||||
`;
|
|
||||||
|
|
||||||
const StyledSubtitle = styled.div`
|
|
||||||
text-align: center;
|
|
||||||
`;
|
|
||||||
|
|
||||||
const StyledModal = styled(Modal)`
|
|
||||||
color: ${({ theme }) => theme.font.color.primary};
|
|
||||||
> * + * {
|
|
||||||
margin-top: ${({ theme }) => theme.spacing(8)};
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
|
|
||||||
const StyledCenteredButton = styled(Button)`
|
const StyledCenteredButton = styled(Button)`
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
`;
|
`;
|
||||||
@ -77,7 +63,7 @@ export function DeleteModal({
|
|||||||
return (
|
return (
|
||||||
<AnimatePresence mode="wait">
|
<AnimatePresence mode="wait">
|
||||||
<LayoutGroup>
|
<LayoutGroup>
|
||||||
<StyledModal
|
<Modal
|
||||||
isOpen={isOpen}
|
isOpen={isOpen}
|
||||||
onOutsideClick={() => {
|
onOutsideClick={() => {
|
||||||
if (isOpen) {
|
if (isOpen) {
|
||||||
@ -85,15 +71,17 @@ export function DeleteModal({
|
|||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<StyledTitle>{title}</StyledTitle>
|
<H1Title title={title} fontColor={H1TitleFontColor.Primary} />
|
||||||
<StyledSubtitle>{subtitle}</StyledSubtitle>
|
<Section alignment={SectionAlignment.Center}>{subtitle}</Section>
|
||||||
<TextInput
|
<Section>
|
||||||
value={email}
|
<TextInput
|
||||||
onChange={handleEmailChange}
|
value={email}
|
||||||
placeholder={userEmail}
|
onChange={handleEmailChange}
|
||||||
fullWidth
|
placeholder={userEmail}
|
||||||
key={'email-' + userEmail}
|
fullWidth
|
||||||
/>
|
key={'email-' + userEmail}
|
||||||
|
/>
|
||||||
|
</Section>
|
||||||
<StyledDeleteButton
|
<StyledDeleteButton
|
||||||
onClick={handleConfirmDelete}
|
onClick={handleConfirmDelete}
|
||||||
variant={ButtonVariant.Secondary}
|
variant={ButtonVariant.Secondary}
|
||||||
@ -110,7 +98,7 @@ export function DeleteModal({
|
|||||||
marginTop: 10,
|
marginTop: 10,
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</StyledModal>
|
</Modal>
|
||||||
</LayoutGroup>
|
</LayoutGroup>
|
||||||
</AnimatePresence>
|
</AnimatePresence>
|
||||||
);
|
);
|
||||||
|
|||||||
@ -4,7 +4,7 @@ import { useNavigate } from 'react-router-dom';
|
|||||||
import { useAuth } from '@/auth/hooks/useAuth';
|
import { useAuth } from '@/auth/hooks/useAuth';
|
||||||
import { AppPath } from '@/types/AppPath';
|
import { AppPath } from '@/types/AppPath';
|
||||||
import { ButtonVariant } from '@/ui/button/components/Button';
|
import { ButtonVariant } from '@/ui/button/components/Button';
|
||||||
import { SubSectionTitle } from '@/ui/title/components/SubSectionTitle';
|
import { H2Title } from '@/ui/title/components/H2Title';
|
||||||
import { useDeleteCurrentWorkspaceMutation } from '~/generated/graphql';
|
import { useDeleteCurrentWorkspaceMutation } from '~/generated/graphql';
|
||||||
|
|
||||||
import { DeleteModal, StyledDeleteButton } from './DeleteModal';
|
import { DeleteModal, StyledDeleteButton } from './DeleteModal';
|
||||||
@ -29,10 +29,7 @@ export function DeleteWorkspace() {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<SubSectionTitle
|
<H2Title title="Danger zone" description="Delete your whole workspace" />
|
||||||
title="Danger zone"
|
|
||||||
description="Delete your whole workspace"
|
|
||||||
/>
|
|
||||||
<StyledDeleteButton
|
<StyledDeleteButton
|
||||||
onClick={() => setIsDeleteWorkSpaceModalOpen(true)}
|
onClick={() => setIsDeleteWorkSpaceModalOpen(true)}
|
||||||
variant={ButtonVariant.Secondary}
|
variant={ButtonVariant.Secondary}
|
||||||
|
|||||||
@ -50,13 +50,15 @@ export const Sizes: Story = {
|
|||||||
size: { control: false },
|
size: { control: false },
|
||||||
},
|
},
|
||||||
parameters: {
|
parameters: {
|
||||||
catalog: [
|
catalog: {
|
||||||
{
|
dimensions: [
|
||||||
name: 'sizes',
|
{
|
||||||
values: Object.values(ButtonSize),
|
name: 'sizes',
|
||||||
props: (size: ButtonSize) => ({ size }),
|
values: Object.values(ButtonSize),
|
||||||
},
|
props: (size: ButtonSize) => ({ size }),
|
||||||
],
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
},
|
},
|
||||||
decorators: [CatalogDecorator],
|
decorators: [CatalogDecorator],
|
||||||
};
|
};
|
||||||
@ -68,22 +70,24 @@ export const Variants: Story = {
|
|||||||
},
|
},
|
||||||
parameters: {
|
parameters: {
|
||||||
pseudo: { hover: ['.hover'], active: ['.active'], focus: ['.focus'] },
|
pseudo: { hover: ['.hover'], active: ['.active'], focus: ['.focus'] },
|
||||||
catalog: [
|
catalog: {
|
||||||
{
|
dimensions: [
|
||||||
name: 'state',
|
{
|
||||||
values: ['default', 'disabled', 'hover', 'active', 'focus'],
|
name: 'state',
|
||||||
props: (state: string) => {
|
values: ['default', 'disabled', 'hover', 'active', 'focus'],
|
||||||
if (state === 'disabled') return { disabled: true };
|
props: (state: string) => {
|
||||||
if (state === 'default') return {};
|
if (state === 'disabled') return { disabled: true };
|
||||||
return { className: state };
|
if (state === 'default') return {};
|
||||||
|
return { className: state };
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
{
|
||||||
{
|
name: 'variants',
|
||||||
name: 'variants',
|
values: Object.values(ButtonVariant),
|
||||||
values: Object.values(ButtonVariant),
|
props: (variant: ButtonVariant) => ({ variant }),
|
||||||
props: (variant: ButtonVariant) => ({ variant }),
|
},
|
||||||
},
|
],
|
||||||
],
|
},
|
||||||
},
|
},
|
||||||
decorators: [CatalogDecorator],
|
decorators: [CatalogDecorator],
|
||||||
};
|
};
|
||||||
@ -93,30 +97,34 @@ export const Positions: Story = {
|
|||||||
position: { control: false },
|
position: { control: false },
|
||||||
},
|
},
|
||||||
parameters: {
|
parameters: {
|
||||||
catalog: [
|
catalog: {
|
||||||
{
|
dimensions: [
|
||||||
name: 'positions',
|
{
|
||||||
values: ['none', ...Object.values(ButtonPosition)],
|
name: 'positions',
|
||||||
props: (position: ButtonPosition | 'none') =>
|
values: ['none', ...Object.values(ButtonPosition)],
|
||||||
position === 'none' ? {} : { position },
|
props: (position: ButtonPosition | 'none') =>
|
||||||
},
|
position === 'none' ? {} : { position },
|
||||||
],
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
},
|
},
|
||||||
decorators: [CatalogDecorator],
|
decorators: [CatalogDecorator],
|
||||||
};
|
};
|
||||||
|
|
||||||
export const WithAdornments: Story = {
|
export const WithAdornments: Story = {
|
||||||
parameters: {
|
parameters: {
|
||||||
catalog: [
|
catalog: {
|
||||||
{
|
dimensions: [
|
||||||
name: 'adornments',
|
{
|
||||||
values: ['with icon', 'with soon pill'],
|
name: 'adornments',
|
||||||
props: (value: string) =>
|
values: ['with icon', 'with soon pill'],
|
||||||
value === 'with icon'
|
props: (value: string) =>
|
||||||
? { icon: <IconSearch size={14} /> }
|
value === 'with icon'
|
||||||
: { soon: true },
|
? { icon: <IconSearch size={14} /> }
|
||||||
},
|
: { soon: true },
|
||||||
],
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
},
|
},
|
||||||
decorators: [CatalogDecorator],
|
decorators: [CatalogDecorator],
|
||||||
};
|
};
|
||||||
|
|||||||
@ -38,29 +38,31 @@ export const Catalog: Story = {
|
|||||||
},
|
},
|
||||||
parameters: {
|
parameters: {
|
||||||
pseudo: { hover: ['.hover'], active: ['.active'] },
|
pseudo: { hover: ['.hover'], active: ['.active'] },
|
||||||
catalog: [
|
catalog: {
|
||||||
{
|
dimensions: [
|
||||||
name: 'states',
|
{
|
||||||
values: ['default', 'hover', 'active', 'disabled'],
|
name: 'states',
|
||||||
props: (state: string) =>
|
values: ['default', 'hover', 'active', 'disabled'],
|
||||||
state === 'default' ? {} : { className: state },
|
props: (state: string) =>
|
||||||
},
|
state === 'default' ? {} : { className: state },
|
||||||
{
|
},
|
||||||
name: 'variants',
|
{
|
||||||
values: Object.values(ChipVariant),
|
name: 'variants',
|
||||||
props: (variant: ChipVariant) => ({ variant }),
|
values: Object.values(ChipVariant),
|
||||||
},
|
props: (variant: ChipVariant) => ({ variant }),
|
||||||
{
|
},
|
||||||
name: 'sizes',
|
{
|
||||||
values: Object.values(ChipSize),
|
name: 'sizes',
|
||||||
props: (size: ChipSize) => ({ size }),
|
values: Object.values(ChipSize),
|
||||||
},
|
props: (size: ChipSize) => ({ size }),
|
||||||
{
|
},
|
||||||
name: 'accents',
|
{
|
||||||
values: Object.values(ChipAccent),
|
name: 'accents',
|
||||||
props: (accent: ChipAccent) => ({ accent }),
|
values: Object.values(ChipAccent),
|
||||||
},
|
props: (accent: ChipAccent) => ({ accent }),
|
||||||
],
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
},
|
},
|
||||||
decorators: [CatalogDecorator],
|
decorators: [CatalogDecorator],
|
||||||
};
|
};
|
||||||
|
|||||||
@ -39,36 +39,38 @@ export const Catalog: Story = {
|
|||||||
shape: { control: false },
|
shape: { control: false },
|
||||||
},
|
},
|
||||||
parameters: {
|
parameters: {
|
||||||
catalog: [
|
catalog: {
|
||||||
{
|
dimensions: [
|
||||||
name: 'state',
|
{
|
||||||
values: ['unchecked', 'checked', 'indeterminate'],
|
name: 'state',
|
||||||
props: (state: string) => {
|
values: ['unchecked', 'checked', 'indeterminate'],
|
||||||
if (state === 'checked') {
|
props: (state: string) => {
|
||||||
return { checked: true };
|
if (state === 'checked') {
|
||||||
}
|
return { checked: true };
|
||||||
|
}
|
||||||
|
|
||||||
if (state === 'indeterminate') {
|
if (state === 'indeterminate') {
|
||||||
return { indeterminate: true };
|
return { indeterminate: true };
|
||||||
}
|
}
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
{
|
||||||
{
|
name: 'shape',
|
||||||
name: 'shape',
|
values: Object.values(CheckboxShape),
|
||||||
values: Object.values(CheckboxShape),
|
props: (shape: CheckboxShape) => ({ shape }),
|
||||||
props: (shape: CheckboxShape) => ({ shape }),
|
},
|
||||||
},
|
{
|
||||||
{
|
name: 'variant',
|
||||||
name: 'variant',
|
values: Object.values(CheckboxVariant),
|
||||||
values: Object.values(CheckboxVariant),
|
props: (variant: CheckboxVariant) => ({ variant }),
|
||||||
props: (variant: CheckboxVariant) => ({ variant }),
|
},
|
||||||
},
|
{
|
||||||
{
|
name: 'size',
|
||||||
name: 'size',
|
values: Object.values(CheckboxSize),
|
||||||
values: Object.values(CheckboxSize),
|
props: (size: CheckboxSize) => ({ size }),
|
||||||
props: (size: CheckboxSize) => ({ size }),
|
},
|
||||||
},
|
],
|
||||||
],
|
},
|
||||||
},
|
},
|
||||||
decorators: [CatalogDecorator],
|
decorators: [CatalogDecorator],
|
||||||
};
|
};
|
||||||
|
|||||||
@ -35,26 +35,28 @@ export const Catalog = {
|
|||||||
autoStart: defaultArgTypes,
|
autoStart: defaultArgTypes,
|
||||||
},
|
},
|
||||||
parameters: {
|
parameters: {
|
||||||
catalog: [
|
catalog: {
|
||||||
{
|
dimensions: [
|
||||||
name: 'animation',
|
{
|
||||||
values: [true, false],
|
name: 'animation',
|
||||||
props: (autoStart: string) => ({ autoStart }),
|
values: [true, false],
|
||||||
labels: (autoStart: string) => `AutoStart: ${autoStart}`,
|
props: (autoStart: string) => ({ autoStart }),
|
||||||
},
|
labels: (autoStart: string) => `AutoStart: ${autoStart}`,
|
||||||
{
|
},
|
||||||
name: 'colors',
|
{
|
||||||
values: [undefined, 'blue'],
|
name: 'colors',
|
||||||
props: (barColor: string) => ({ barColor }),
|
values: [undefined, 'blue'],
|
||||||
labels: (color: string) => `Color: ${color ?? 'default'}`,
|
props: (barColor: string) => ({ barColor }),
|
||||||
},
|
labels: (color: string) => `Color: ${color ?? 'default'}`,
|
||||||
{
|
},
|
||||||
name: 'sizes',
|
{
|
||||||
values: [undefined, 10],
|
name: 'sizes',
|
||||||
props: (barHeight: number) => ({ barHeight }),
|
values: [undefined, 10],
|
||||||
labels: (size: number) => `Size: ${size ? size + ' px' : 'default'}`,
|
props: (barHeight: number) => ({ barHeight }),
|
||||||
},
|
labels: (size: number) => `Size: ${size ? size + ' px' : 'default'}`,
|
||||||
],
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
},
|
},
|
||||||
decorators: [CatalogDecorator],
|
decorators: [CatalogDecorator],
|
||||||
};
|
};
|
||||||
|
|||||||
35
front/src/modules/ui/section/components/Section.tsx
Normal file
35
front/src/modules/ui/section/components/Section.tsx
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
import { ReactNode } from 'react';
|
||||||
|
import styled from '@emotion/styled';
|
||||||
|
|
||||||
|
type OwnProps = {
|
||||||
|
children: ReactNode;
|
||||||
|
alignment?: SectionAlignment;
|
||||||
|
fullWidth?: boolean;
|
||||||
|
};
|
||||||
|
|
||||||
|
export enum SectionAlignment {
|
||||||
|
Left = 'left',
|
||||||
|
Center = 'center',
|
||||||
|
}
|
||||||
|
|
||||||
|
const StyledSection = styled.div<{
|
||||||
|
alignment: SectionAlignment;
|
||||||
|
fullWidth: boolean;
|
||||||
|
}>`
|
||||||
|
margin-bottom: ${({ theme }) => theme.spacing(4)};
|
||||||
|
margin-top: ${({ theme }) => theme.spacing(4)};
|
||||||
|
text-align: ${({ alignment }) => alignment};
|
||||||
|
width: ${({ fullWidth }) => (fullWidth ? '100%' : 'auto')};
|
||||||
|
`;
|
||||||
|
|
||||||
|
export function Section({
|
||||||
|
children,
|
||||||
|
alignment = SectionAlignment.Left,
|
||||||
|
fullWidth = true,
|
||||||
|
}: OwnProps) {
|
||||||
|
return (
|
||||||
|
<StyledSection alignment={alignment} fullWidth={fullWidth}>
|
||||||
|
{children}
|
||||||
|
</StyledSection>
|
||||||
|
);
|
||||||
|
}
|
||||||
@ -29,19 +29,21 @@ export const Catalog: Story = {
|
|||||||
},
|
},
|
||||||
parameters: {
|
parameters: {
|
||||||
pseudo: { hover: ['.hover'], active: ['.active'] },
|
pseudo: { hover: ['.hover'], active: ['.active'] },
|
||||||
catalog: [
|
catalog: {
|
||||||
{
|
dimensions: [
|
||||||
name: 'states',
|
{
|
||||||
values: ['default', 'hover', 'active'],
|
name: 'states',
|
||||||
props: (state: string) =>
|
values: ['default', 'hover', 'active'],
|
||||||
state === 'default' ? {} : { className: state },
|
props: (state: string) =>
|
||||||
},
|
state === 'default' ? {} : { className: state },
|
||||||
{
|
},
|
||||||
name: 'Active',
|
{
|
||||||
values: ['true', 'false'],
|
name: 'Active',
|
||||||
props: (active: string) => ({ active: active === 'true' }),
|
values: ['true', 'false'],
|
||||||
},
|
props: (active: string) => ({ active: active === 'true' }),
|
||||||
],
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
},
|
},
|
||||||
decorators: [CatalogDecorator],
|
decorators: [CatalogDecorator],
|
||||||
};
|
};
|
||||||
|
|||||||
30
front/src/modules/ui/title/components/H1Title.tsx
Normal file
30
front/src/modules/ui/title/components/H1Title.tsx
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
import styled from '@emotion/styled';
|
||||||
|
|
||||||
|
type OwnProps = {
|
||||||
|
title: string;
|
||||||
|
fontColor?: H1TitleFontColor;
|
||||||
|
};
|
||||||
|
|
||||||
|
export enum H1TitleFontColor {
|
||||||
|
Primary = 'primary',
|
||||||
|
Secondary = 'secondary',
|
||||||
|
Tertiary = 'tertiary',
|
||||||
|
}
|
||||||
|
|
||||||
|
const StyledTitle = styled.h2<{
|
||||||
|
fontColor: H1TitleFontColor;
|
||||||
|
}>`
|
||||||
|
color: ${({ theme, fontColor }) => theme.font.color[fontColor]};
|
||||||
|
font-size: ${({ theme }) => theme.font.size.lg};
|
||||||
|
font-weight: ${({ theme }) => theme.font.weight.semiBold};
|
||||||
|
line-height: ${({ theme }) => theme.text.lineHeight.md};
|
||||||
|
margin: 0;
|
||||||
|
margin-bottom: ${({ theme }) => theme.spacing(4)};
|
||||||
|
`;
|
||||||
|
|
||||||
|
export function H1Title({
|
||||||
|
title,
|
||||||
|
fontColor = H1TitleFontColor.Tertiary,
|
||||||
|
}: OwnProps) {
|
||||||
|
return <StyledTitle fontColor={fontColor}>{title}</StyledTitle>;
|
||||||
|
}
|
||||||
@ -23,10 +23,10 @@ const StyledDescription = styled.h3`
|
|||||||
font-size: ${({ theme }) => theme.font.size.md};
|
font-size: ${({ theme }) => theme.font.size.md};
|
||||||
font-weight: ${({ theme }) => theme.font.weight.regular};
|
font-weight: ${({ theme }) => theme.font.weight.regular};
|
||||||
margin: 0;
|
margin: 0;
|
||||||
margin-top: ${({ theme }) => theme.spacing(1)};
|
margin-top: ${({ theme }) => theme.spacing(3)};
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export function SubSectionTitle({ title, description }: Props) {
|
export function H2Title({ title, description }: Props) {
|
||||||
return (
|
return (
|
||||||
<StyledContainer>
|
<StyledContainer>
|
||||||
<StyledTitle>{title}</StyledTitle>
|
<StyledTitle>{title}</StyledTitle>
|
||||||
@ -1,18 +0,0 @@
|
|||||||
import { ReactNode } from 'react';
|
|
||||||
import styled from '@emotion/styled';
|
|
||||||
|
|
||||||
type OwnProps = {
|
|
||||||
children: ReactNode;
|
|
||||||
};
|
|
||||||
|
|
||||||
const StyledMainSectionTitle = styled.h2`
|
|
||||||
color: ${({ theme }) => theme.font.color.tertiary};
|
|
||||||
font-size: ${({ theme }) => theme.font.size.xl};
|
|
||||||
font-weight: ${({ theme }) => theme.font.weight.semiBold};
|
|
||||||
line-height: ${({ theme }) => theme.text.lineHeight.lg};
|
|
||||||
margin: 0;
|
|
||||||
`;
|
|
||||||
|
|
||||||
export function MainSectionTitle({ children }: OwnProps) {
|
|
||||||
return <StyledMainSectionTitle>{children}</StyledMainSectionTitle>;
|
|
||||||
}
|
|
||||||
@ -0,0 +1,42 @@
|
|||||||
|
import type { Meta, StoryObj } from '@storybook/react';
|
||||||
|
|
||||||
|
import { CatalogDecorator } from '~/testing/decorators/CatalogDecorator';
|
||||||
|
import { ComponentDecorator } from '~/testing/decorators/ComponentDecorator';
|
||||||
|
|
||||||
|
import { H1Title, H1TitleFontColor } from '../H1Title';
|
||||||
|
|
||||||
|
const meta: Meta<typeof H1Title> = {
|
||||||
|
title: 'UI/Title/H1Title',
|
||||||
|
component: H1Title,
|
||||||
|
decorators: [ComponentDecorator],
|
||||||
|
};
|
||||||
|
|
||||||
|
export default meta;
|
||||||
|
|
||||||
|
type Story = StoryObj<typeof H1Title>;
|
||||||
|
|
||||||
|
const args = {
|
||||||
|
title: 'Title',
|
||||||
|
fontColor: H1TitleFontColor.Primary,
|
||||||
|
};
|
||||||
|
|
||||||
|
export const Default: Story = {
|
||||||
|
args,
|
||||||
|
decorators: [ComponentDecorator],
|
||||||
|
};
|
||||||
|
|
||||||
|
export const Catalog: Story = {
|
||||||
|
args,
|
||||||
|
decorators: [CatalogDecorator],
|
||||||
|
parameters: {
|
||||||
|
catalog: {
|
||||||
|
dimensions: [
|
||||||
|
{
|
||||||
|
name: 'FontColor',
|
||||||
|
values: Object.values(H1TitleFontColor),
|
||||||
|
props: (fontColor: H1TitleFontColor) => ({ fontColor }),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
@ -2,16 +2,16 @@ import type { Meta, StoryObj } from '@storybook/react';
|
|||||||
|
|
||||||
import { ComponentDecorator } from '~/testing/decorators/ComponentDecorator';
|
import { ComponentDecorator } from '~/testing/decorators/ComponentDecorator';
|
||||||
|
|
||||||
import { SubSectionTitle } from '../SubSectionTitle';
|
import { H2Title } from '../H2Title';
|
||||||
|
|
||||||
const args = {
|
const args = {
|
||||||
title: 'Lorem ipsum',
|
title: 'Sub title',
|
||||||
description: 'Lorem ipsum dolor sit amet',
|
description: 'Lorem ipsum dolor sit amet',
|
||||||
};
|
};
|
||||||
|
|
||||||
const meta: Meta<typeof SubSectionTitle> = {
|
const meta: Meta<typeof H2Title> = {
|
||||||
title: 'UI/Title/SubSectionTitle',
|
title: 'UI/Title/H2Title',
|
||||||
component: SubSectionTitle,
|
component: H2Title,
|
||||||
decorators: [ComponentDecorator],
|
decorators: [ComponentDecorator],
|
||||||
args: {
|
args: {
|
||||||
title: args.title,
|
title: args.title,
|
||||||
@ -20,7 +20,7 @@ const meta: Meta<typeof SubSectionTitle> = {
|
|||||||
|
|
||||||
export default meta;
|
export default meta;
|
||||||
|
|
||||||
type Story = StoryObj<typeof SubSectionTitle>;
|
type Story = StoryObj<typeof H2Title>;
|
||||||
|
|
||||||
export const Default: Story = {
|
export const Default: Story = {
|
||||||
decorators: [ComponentDecorator],
|
decorators: [ComponentDecorator],
|
||||||
@ -1,24 +0,0 @@
|
|||||||
import type { Meta, StoryObj } from '@storybook/react';
|
|
||||||
|
|
||||||
import { ComponentDecorator } from '~/testing/decorators/ComponentDecorator';
|
|
||||||
|
|
||||||
import { MainSectionTitle } from '../MainSectionTitle';
|
|
||||||
|
|
||||||
const meta: Meta<typeof MainSectionTitle> = {
|
|
||||||
title: 'UI/Title/MainSectionTitle',
|
|
||||||
component: MainSectionTitle,
|
|
||||||
decorators: [ComponentDecorator],
|
|
||||||
};
|
|
||||||
|
|
||||||
export default meta;
|
|
||||||
|
|
||||||
type Story = StoryObj<typeof MainSectionTitle>;
|
|
||||||
|
|
||||||
const args = {
|
|
||||||
children: 'Lorem ipsum',
|
|
||||||
};
|
|
||||||
|
|
||||||
export const Default: Story = {
|
|
||||||
args,
|
|
||||||
decorators: [ComponentDecorator],
|
|
||||||
};
|
|
||||||
@ -42,16 +42,18 @@ export const Catalog: Story = {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
parameters: {
|
parameters: {
|
||||||
catalog: [
|
catalog: {
|
||||||
{
|
dimensions: [
|
||||||
name: 'anchorSelect',
|
{
|
||||||
values: Object.values(TooltipPosition),
|
name: 'anchorSelect',
|
||||||
props: (anchorSelect: TooltipPosition) => ({
|
values: Object.values(TooltipPosition),
|
||||||
anchorSelect: `#${anchorSelect}`,
|
props: (anchorSelect: TooltipPosition) => ({
|
||||||
place: anchorSelect,
|
anchorSelect: `#${anchorSelect}`,
|
||||||
}),
|
place: anchorSelect,
|
||||||
},
|
}),
|
||||||
],
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
},
|
},
|
||||||
decorators: [CatalogDecorator],
|
decorators: [CatalogDecorator],
|
||||||
};
|
};
|
||||||
|
|||||||
@ -17,7 +17,7 @@ import { MainButton } from '@/ui/button/components/MainButton';
|
|||||||
import { useScopedHotkeys } from '@/ui/hotkey/hooks/useScopedHotkeys';
|
import { useScopedHotkeys } from '@/ui/hotkey/hooks/useScopedHotkeys';
|
||||||
import { TextInput } from '@/ui/input/components/TextInput';
|
import { TextInput } from '@/ui/input/components/TextInput';
|
||||||
import { useSnackBar } from '@/ui/snack-bar/hooks/useSnackBar';
|
import { useSnackBar } from '@/ui/snack-bar/hooks/useSnackBar';
|
||||||
import { SubSectionTitle } from '@/ui/title/components/SubSectionTitle';
|
import { H2Title } from '@/ui/title/components/H2Title';
|
||||||
import { GET_CURRENT_USER } from '@/users/queries';
|
import { GET_CURRENT_USER } from '@/users/queries';
|
||||||
import { useUpdateUserMutation } from '~/generated/graphql';
|
import { useUpdateUserMutation } from '~/generated/graphql';
|
||||||
|
|
||||||
@ -128,11 +128,11 @@ export function CreateProfile() {
|
|||||||
<SubTitle>How you'll be identified on the app.</SubTitle>
|
<SubTitle>How you'll be identified on the app.</SubTitle>
|
||||||
<StyledContentContainer>
|
<StyledContentContainer>
|
||||||
<StyledSectionContainer>
|
<StyledSectionContainer>
|
||||||
<SubSectionTitle title="Picture" />
|
<H2Title title="Picture" />
|
||||||
<ProfilePictureUploader />
|
<ProfilePictureUploader />
|
||||||
</StyledSectionContainer>
|
</StyledSectionContainer>
|
||||||
<StyledSectionContainer>
|
<StyledSectionContainer>
|
||||||
<SubSectionTitle
|
<H2Title
|
||||||
title="Name"
|
title="Name"
|
||||||
description="Your name as it will be displayed on the app"
|
description="Your name as it will be displayed on the app"
|
||||||
/>
|
/>
|
||||||
|
|||||||
@ -14,7 +14,7 @@ import { MainButton } from '@/ui/button/components/MainButton';
|
|||||||
import { useScopedHotkeys } from '@/ui/hotkey/hooks/useScopedHotkeys';
|
import { useScopedHotkeys } from '@/ui/hotkey/hooks/useScopedHotkeys';
|
||||||
import { TextInput } from '@/ui/input/components/TextInput';
|
import { TextInput } from '@/ui/input/components/TextInput';
|
||||||
import { useSnackBar } from '@/ui/snack-bar/hooks/useSnackBar';
|
import { useSnackBar } from '@/ui/snack-bar/hooks/useSnackBar';
|
||||||
import { SubSectionTitle } from '@/ui/title/components/SubSectionTitle';
|
import { H2Title } from '@/ui/title/components/H2Title';
|
||||||
import { GET_CURRENT_USER } from '@/users/queries';
|
import { GET_CURRENT_USER } from '@/users/queries';
|
||||||
import { useUpdateWorkspaceMutation } from '~/generated/graphql';
|
import { useUpdateWorkspaceMutation } from '~/generated/graphql';
|
||||||
|
|
||||||
@ -107,11 +107,11 @@ export function CreateWorkspace() {
|
|||||||
</SubTitle>
|
</SubTitle>
|
||||||
<StyledContentContainer>
|
<StyledContentContainer>
|
||||||
<StyledSectionContainer>
|
<StyledSectionContainer>
|
||||||
<SubSectionTitle title="Workspace logo" />
|
<H2Title title="Workspace logo" />
|
||||||
<WorkspaceLogoUploader />
|
<WorkspaceLogoUploader />
|
||||||
</StyledSectionContainer>
|
</StyledSectionContainer>
|
||||||
<StyledSectionContainer>
|
<StyledSectionContainer>
|
||||||
<SubSectionTitle
|
<H2Title
|
||||||
title="Workspace name"
|
title="Workspace name"
|
||||||
description="The name of your organization"
|
description="The name of your organization"
|
||||||
/>
|
/>
|
||||||
|
|||||||
@ -3,9 +3,10 @@ import styled from '@emotion/styled';
|
|||||||
import { ColorSchemePicker } from '@/ui/color-scheme/components/ColorSchemePicker';
|
import { ColorSchemePicker } from '@/ui/color-scheme/components/ColorSchemePicker';
|
||||||
import { IconSettings } from '@/ui/icon';
|
import { IconSettings } from '@/ui/icon';
|
||||||
import { SubMenuTopBarContainer } from '@/ui/layout/components/SubMenuTopBarContainer';
|
import { SubMenuTopBarContainer } from '@/ui/layout/components/SubMenuTopBarContainer';
|
||||||
|
import { Section } from '@/ui/section/components/Section';
|
||||||
import { useColorScheme } from '@/ui/themes/hooks/useColorScheme';
|
import { useColorScheme } from '@/ui/themes/hooks/useColorScheme';
|
||||||
import { MainSectionTitle } from '@/ui/title/components/MainSectionTitle';
|
import { H1Title } from '@/ui/title/components/H1Title';
|
||||||
import { SubSectionTitle } from '@/ui/title/components/SubSectionTitle';
|
import { H2Title } from '@/ui/title/components/H2Title';
|
||||||
|
|
||||||
const StyledContainer = styled.div`
|
const StyledContainer = styled.div`
|
||||||
display: flex;
|
display: flex;
|
||||||
@ -13,15 +14,6 @@ const StyledContainer = styled.div`
|
|||||||
padding: ${({ theme }) => theme.spacing(8)};
|
padding: ${({ theme }) => theme.spacing(8)};
|
||||||
padding-bottom: ${({ theme }) => theme.spacing(10)};
|
padding-bottom: ${({ theme }) => theme.spacing(10)};
|
||||||
width: 350px;
|
width: 350px;
|
||||||
> * + * {
|
|
||||||
margin-top: ${({ theme }) => theme.spacing(8)};
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
|
|
||||||
const StyledSectionContainer = styled.div`
|
|
||||||
> * + * {
|
|
||||||
margin-top: ${({ theme }) => theme.spacing(4)};
|
|
||||||
}
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export function SettingsExperience() {
|
export function SettingsExperience() {
|
||||||
@ -29,15 +21,13 @@ export function SettingsExperience() {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<SubMenuTopBarContainer icon={<IconSettings size={16} />} title="Settings">
|
<SubMenuTopBarContainer icon={<IconSettings size={16} />} title="Settings">
|
||||||
<div>
|
<StyledContainer>
|
||||||
<StyledContainer>
|
<H1Title title="Experience" />
|
||||||
<MainSectionTitle>Experience</MainSectionTitle>
|
<Section>
|
||||||
<StyledSectionContainer>
|
<H2Title title="Appearance" />
|
||||||
<SubSectionTitle title="Appearance" />
|
<ColorSchemePicker value={colorScheme} onChange={setColorScheme} />
|
||||||
<ColorSchemePicker value={colorScheme} onChange={setColorScheme} />
|
</Section>
|
||||||
</StyledSectionContainer>
|
</StyledContainer>
|
||||||
</StyledContainer>
|
|
||||||
</div>
|
|
||||||
</SubMenuTopBarContainer>
|
</SubMenuTopBarContainer>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -6,24 +6,18 @@ import { NameFields } from '@/settings/profile/components/NameFields';
|
|||||||
import { ProfilePictureUploader } from '@/settings/profile/components/ProfilePictureUploader';
|
import { ProfilePictureUploader } from '@/settings/profile/components/ProfilePictureUploader';
|
||||||
import { IconSettings } from '@/ui/icon';
|
import { IconSettings } from '@/ui/icon';
|
||||||
import { SubMenuTopBarContainer } from '@/ui/layout/components/SubMenuTopBarContainer';
|
import { SubMenuTopBarContainer } from '@/ui/layout/components/SubMenuTopBarContainer';
|
||||||
import { MainSectionTitle } from '@/ui/title/components/MainSectionTitle';
|
import { Section } from '@/ui/section/components/Section';
|
||||||
import { SubSectionTitle } from '@/ui/title/components/SubSectionTitle';
|
import { H1Title } from '@/ui/title/components/H1Title';
|
||||||
|
import { H2Title } from '@/ui/title/components/H2Title';
|
||||||
|
|
||||||
const StyledContainer = styled.div`
|
const StyledContainer = styled.div`
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
height: fit-content;
|
||||||
padding: ${({ theme }) => theme.spacing(8)};
|
padding: ${({ theme }) => theme.spacing(8)};
|
||||||
padding-bottom: ${({ theme }) => theme.spacing(10)};
|
padding-bottom: ${({ theme }) => theme.spacing(10)};
|
||||||
|
padding-bottom: 30px;
|
||||||
width: 350px;
|
width: 350px;
|
||||||
> * + * {
|
|
||||||
margin-top: ${({ theme }) => theme.spacing(8)};
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
|
|
||||||
const StyledSectionContainer = styled.div`
|
|
||||||
> * + * {
|
|
||||||
margin-top: ${({ theme }) => theme.spacing(4)};
|
|
||||||
}
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export function SettingsProfile() {
|
export function SettingsProfile() {
|
||||||
@ -31,29 +25,28 @@ export function SettingsProfile() {
|
|||||||
<SubMenuTopBarContainer icon={<IconSettings size={16} />} title="Settings">
|
<SubMenuTopBarContainer icon={<IconSettings size={16} />} title="Settings">
|
||||||
<>
|
<>
|
||||||
<StyledContainer>
|
<StyledContainer>
|
||||||
<MainSectionTitle>Profile</MainSectionTitle>
|
<H1Title title="Profile" />
|
||||||
<StyledSectionContainer>
|
<Section>
|
||||||
<SubSectionTitle title="Picture" />
|
<H2Title title="Picture" />
|
||||||
<ProfilePictureUploader />
|
<ProfilePictureUploader />
|
||||||
</StyledSectionContainer>
|
</Section>
|
||||||
<StyledSectionContainer>
|
<Section>
|
||||||
<SubSectionTitle
|
<H2Title
|
||||||
title="Name"
|
title="Name"
|
||||||
description="Your name as it will be displayed"
|
description="Your name as it will be displayed"
|
||||||
/>
|
/>
|
||||||
<NameFields />
|
<NameFields />
|
||||||
</StyledSectionContainer>
|
</Section>
|
||||||
<StyledSectionContainer>
|
<Section>
|
||||||
<SubSectionTitle
|
<H2Title
|
||||||
title="Email"
|
title="Email"
|
||||||
description="The email associated to your account"
|
description="The email associated to your account"
|
||||||
/>
|
/>
|
||||||
<EmailField />
|
<EmailField />
|
||||||
</StyledSectionContainer>
|
</Section>
|
||||||
|
<Section>
|
||||||
<StyledSectionContainer>
|
|
||||||
<DeleteAccount />
|
<DeleteAccount />
|
||||||
</StyledSectionContainer>
|
</Section>
|
||||||
</StyledContainer>
|
</StyledContainer>
|
||||||
</>
|
</>
|
||||||
</SubMenuTopBarContainer>
|
</SubMenuTopBarContainer>
|
||||||
|
|||||||
@ -5,23 +5,15 @@ import { NameField } from '@/settings/workspace/components/NameField';
|
|||||||
import { WorkspaceLogoUploader } from '@/settings/workspace/components/WorkspaceLogoUploader';
|
import { WorkspaceLogoUploader } from '@/settings/workspace/components/WorkspaceLogoUploader';
|
||||||
import { IconSettings } from '@/ui/icon';
|
import { IconSettings } from '@/ui/icon';
|
||||||
import { SubMenuTopBarContainer } from '@/ui/layout/components/SubMenuTopBarContainer';
|
import { SubMenuTopBarContainer } from '@/ui/layout/components/SubMenuTopBarContainer';
|
||||||
import { MainSectionTitle } from '@/ui/title/components/MainSectionTitle';
|
import { Section } from '@/ui/section/components/Section';
|
||||||
import { SubSectionTitle } from '@/ui/title/components/SubSectionTitle';
|
import { H1Title } from '@/ui/title/components/H1Title';
|
||||||
|
import { H2Title } from '@/ui/title/components/H2Title';
|
||||||
|
|
||||||
const StyledContainer = styled.div`
|
const StyledContainer = styled.div`
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
padding: ${({ theme }) => theme.spacing(8)};
|
padding: ${({ theme }) => theme.spacing(8)};
|
||||||
width: 350px;
|
width: 350px;
|
||||||
> * + * {
|
|
||||||
margin-top: ${({ theme }) => theme.spacing(8)};
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
|
|
||||||
const StyledSectionContainer = styled.div`
|
|
||||||
> * + * {
|
|
||||||
margin-top: ${({ theme }) => theme.spacing(4)};
|
|
||||||
}
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export function SettingsWorksapce() {
|
export function SettingsWorksapce() {
|
||||||
@ -29,22 +21,19 @@ export function SettingsWorksapce() {
|
|||||||
<SubMenuTopBarContainer icon={<IconSettings size={16} />} title="Settings">
|
<SubMenuTopBarContainer icon={<IconSettings size={16} />} title="Settings">
|
||||||
<div>
|
<div>
|
||||||
<StyledContainer>
|
<StyledContainer>
|
||||||
<MainSectionTitle>General</MainSectionTitle>
|
<H1Title title="General" />
|
||||||
<StyledSectionContainer>
|
<Section>
|
||||||
<SubSectionTitle title="Picture" />
|
<H2Title title="Picture" />
|
||||||
<WorkspaceLogoUploader />
|
<WorkspaceLogoUploader />
|
||||||
</StyledSectionContainer>
|
</Section>
|
||||||
<StyledSectionContainer>
|
<Section>
|
||||||
<SubSectionTitle
|
<H2Title title="Name" description="Name of your workspace" />
|
||||||
title="Name"
|
|
||||||
description="Name of your workspace"
|
|
||||||
/>
|
|
||||||
<NameField />
|
<NameField />
|
||||||
</StyledSectionContainer>
|
</Section>
|
||||||
|
|
||||||
<StyledSectionContainer>
|
<Section>
|
||||||
<DeleteWorkspace />
|
<DeleteWorkspace />
|
||||||
</StyledSectionContainer>
|
</Section>
|
||||||
</StyledContainer>
|
</StyledContainer>
|
||||||
</div>
|
</div>
|
||||||
</SubMenuTopBarContainer>
|
</SubMenuTopBarContainer>
|
||||||
|
|||||||
@ -10,8 +10,9 @@ import {
|
|||||||
} from '@/ui/button/components/Button';
|
} from '@/ui/button/components/Button';
|
||||||
import { IconSettings, IconTrash } from '@/ui/icon';
|
import { IconSettings, IconTrash } from '@/ui/icon';
|
||||||
import { SubMenuTopBarContainer } from '@/ui/layout/components/SubMenuTopBarContainer';
|
import { SubMenuTopBarContainer } from '@/ui/layout/components/SubMenuTopBarContainer';
|
||||||
import { MainSectionTitle } from '@/ui/title/components/MainSectionTitle';
|
import { Section } from '@/ui/section/components/Section';
|
||||||
import { SubSectionTitle } from '@/ui/title/components/SubSectionTitle';
|
import { H1Title } from '@/ui/title/components/H1Title';
|
||||||
|
import { H2Title } from '@/ui/title/components/H2Title';
|
||||||
import { WorkspaceInviteLink } from '@/workspace/components/WorkspaceInviteLink';
|
import { WorkspaceInviteLink } from '@/workspace/components/WorkspaceInviteLink';
|
||||||
import { WorkspaceMemberCard } from '@/workspace/components/WorkspaceMemberCard';
|
import { WorkspaceMemberCard } from '@/workspace/components/WorkspaceMemberCard';
|
||||||
import {
|
import {
|
||||||
@ -22,11 +23,9 @@ import {
|
|||||||
const StyledContainer = styled.div`
|
const StyledContainer = styled.div`
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
margin-top: ${({ theme }) => theme.spacing(8)};
|
||||||
padding: ${({ theme }) => theme.spacing(8)};
|
padding: ${({ theme }) => theme.spacing(8)};
|
||||||
width: 350px;
|
width: 350px;
|
||||||
> * + * {
|
|
||||||
margin-top: ${({ theme }) => theme.spacing(8)};
|
|
||||||
}
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const ButtonContainer = styled.div`
|
const ButtonContainer = styled.div`
|
||||||
@ -81,40 +80,44 @@ export function SettingsWorkspaceMembers() {
|
|||||||
return (
|
return (
|
||||||
<SubMenuTopBarContainer icon={<IconSettings size={16} />} title="Settings">
|
<SubMenuTopBarContainer icon={<IconSettings size={16} />} title="Settings">
|
||||||
<StyledContainer>
|
<StyledContainer>
|
||||||
<MainSectionTitle>Members</MainSectionTitle>
|
<H1Title title="Members" />
|
||||||
{workspace?.inviteHash && (
|
{workspace?.inviteHash && (
|
||||||
<>
|
<Section>
|
||||||
<SubSectionTitle
|
<H2Title
|
||||||
title="Invite"
|
title="Invite"
|
||||||
description="Send an invitation to use Twenty"
|
description="Send an invitation to use Twenty"
|
||||||
/>
|
/>
|
||||||
<WorkspaceInviteLink
|
<WorkspaceInviteLink
|
||||||
inviteLink={`${window.location.origin}/invite/${workspace?.inviteHash}`}
|
inviteLink={`${window.location.origin}/invite/${workspace?.inviteHash}`}
|
||||||
/>
|
/>
|
||||||
</>
|
</Section>
|
||||||
)}
|
)}
|
||||||
<SubSectionTitle
|
<Section>
|
||||||
title="Members"
|
<H2Title
|
||||||
description="Manage the members of your space here"
|
title="Members"
|
||||||
/>
|
description="Manage the members of your space here"
|
||||||
{data?.workspaceMembers?.map((member) => (
|
|
||||||
<WorkspaceMemberCard
|
|
||||||
key={member.user.id}
|
|
||||||
workspaceMember={{ user: member.user }}
|
|
||||||
accessory={
|
|
||||||
currentUser?.id !== member.user.id && (
|
|
||||||
<ButtonContainer>
|
|
||||||
<Button
|
|
||||||
onClick={() => handleRemoveWorkspaceMember(member.user.id)}
|
|
||||||
variant={ButtonVariant.Tertiary}
|
|
||||||
size={ButtonSize.Small}
|
|
||||||
icon={<IconTrash size={theme.icon.size.md} />}
|
|
||||||
/>
|
|
||||||
</ButtonContainer>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
/>
|
/>
|
||||||
))}
|
{data?.workspaceMembers?.map((member) => (
|
||||||
|
<WorkspaceMemberCard
|
||||||
|
key={member.user.id}
|
||||||
|
workspaceMember={{ user: member.user }}
|
||||||
|
accessory={
|
||||||
|
currentUser?.id !== member.user.id && (
|
||||||
|
<ButtonContainer>
|
||||||
|
<Button
|
||||||
|
onClick={() =>
|
||||||
|
handleRemoveWorkspaceMember(member.user.id)
|
||||||
|
}
|
||||||
|
variant={ButtonVariant.Tertiary}
|
||||||
|
size={ButtonSize.Small}
|
||||||
|
icon={<IconTrash size={theme.icon.size.md} />}
|
||||||
|
/>
|
||||||
|
</ButtonContainer>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</Section>
|
||||||
</StyledContainer>
|
</StyledContainer>
|
||||||
</SubMenuTopBarContainer>
|
</SubMenuTopBarContainer>
|
||||||
);
|
);
|
||||||
|
|||||||
@ -57,6 +57,10 @@ const RowContainer = styled.div`
|
|||||||
`;
|
`;
|
||||||
|
|
||||||
export const ElementContainer = styled.div`
|
export const ElementContainer = styled.div`
|
||||||
|
display: flex;
|
||||||
|
`;
|
||||||
|
|
||||||
|
export const CellContainer = styled.div`
|
||||||
align-items: center;
|
align-items: center;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
@ -70,13 +74,15 @@ const emptyVariable = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const CatalogDecorator: Decorator = (Story, context) => {
|
export const CatalogDecorator: Decorator = (Story, context) => {
|
||||||
const { catalog } = context.parameters;
|
const {
|
||||||
|
catalog: { dimensions, options },
|
||||||
|
} = context.parameters;
|
||||||
const [
|
const [
|
||||||
variable1,
|
variable1,
|
||||||
variable2 = emptyVariable,
|
variable2 = emptyVariable,
|
||||||
variable3 = emptyVariable,
|
variable3 = emptyVariable,
|
||||||
variable4 = emptyVariable,
|
variable4 = emptyVariable,
|
||||||
] = catalog;
|
] = dimensions;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<StyledContainer>
|
<StyledContainer>
|
||||||
@ -96,22 +102,25 @@ export const CatalogDecorator: Decorator = (Story, context) => {
|
|||||||
<RowTitle>{variable2.labels?.(value2) || value2}</RowTitle>
|
<RowTitle>{variable2.labels?.(value2) || value2}</RowTitle>
|
||||||
)}
|
)}
|
||||||
{variable1.values.map((value1: string) => (
|
{variable1.values.map((value1: string) => (
|
||||||
<ElementContainer key={value1} id={value1}>
|
<CellContainer key={value1} id={value1}>
|
||||||
{(variable1.labels?.(value1) || value1) && (
|
{(variable1.labels?.(value1) || value1) && (
|
||||||
<ElementTitle>
|
<ElementTitle>
|
||||||
{variable1.labels?.(value1) || value1}
|
{variable1.labels?.(value1) || value1}
|
||||||
</ElementTitle>
|
</ElementTitle>
|
||||||
)}
|
)}
|
||||||
<Story
|
|
||||||
args={{
|
<ElementContainer {...options?.elementContainer}>
|
||||||
...context.args,
|
<Story
|
||||||
...variable1.props(value1),
|
args={{
|
||||||
...variable2.props(value2),
|
...context.args,
|
||||||
...variable3.props(value3),
|
...variable1.props(value1),
|
||||||
...variable4.props(value4),
|
...variable2.props(value2),
|
||||||
}}
|
...variable3.props(value3),
|
||||||
/>
|
...variable4.props(value4),
|
||||||
</ElementContainer>
|
}}
|
||||||
|
/>
|
||||||
|
</ElementContainer>
|
||||||
|
</CellContainer>
|
||||||
))}
|
))}
|
||||||
</RowContainer>
|
</RowContainer>
|
||||||
))}
|
))}
|
||||||
|
|||||||
Reference in New Issue
Block a user