Skip to content

Commit 2c8dda1

Browse files
committed
Partially revert twentyhq#17001
1 parent c67bf0e commit 2c8dda1

File tree

7 files changed

+223
-7
lines changed

7 files changed

+223
-7
lines changed
27.5 KB
Loading
Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
import { css } from '@emotion/react';
2+
import styled from '@emotion/styled';
3+
4+
import { type SettingsIntegration } from '@/settings/integrations/types/SettingsIntegration';
5+
import { t } from '@lingui/core/macro';
6+
import { Link } from 'react-router-dom';
7+
import { isDefined } from 'twenty-shared/utils';
8+
import { Pill } from 'twenty-ui/components';
9+
import {
10+
IconArrowUpRight,
11+
IconBolt,
12+
IconCopy,
13+
IconPlus,
14+
Status,
15+
} from 'twenty-ui/display';
16+
import { Button } from 'twenty-ui/input';
17+
import { useCopyToClipboard } from '~/hooks/useCopyToClipboard';
18+
19+
interface SettingsIntegrationComponentProps {
20+
integration: SettingsIntegration;
21+
}
22+
23+
const StyledContainer = styled.div<{ to?: string }>`
24+
align-items: center;
25+
background: ${({ theme }) => theme.background.secondary};
26+
border: 1px solid ${({ theme }) => theme.border.color.medium};
27+
border-radius: ${({ theme }) => theme.border.radius.md};
28+
font-size: ${({ theme }) => theme.font.size.md};
29+
display: flex;
30+
flex-direction: row;
31+
justify-content: space-between;
32+
padding: ${({ theme }) => theme.spacing(3)};
33+
text-decoration: none;
34+
color: ${({ theme }) => theme.font.color.primary};
35+
${({ to }) =>
36+
isDefined(to) &&
37+
css`
38+
cursor: pointer;
39+
`}
40+
`;
41+
42+
const StyledSection = styled.div`
43+
align-items: center;
44+
display: flex;
45+
flex-direction: row;
46+
gap: ${({ theme }) => theme.spacing(3)};
47+
`;
48+
49+
const StyledIntegrationLogo = styled.div`
50+
align-items: center;
51+
display: flex;
52+
flex-direction: row;
53+
gap: ${({ theme }) => theme.spacing(2)};
54+
color: ${({ theme }) => theme.border.color.strong};
55+
`;
56+
57+
const StyledSoonPill = styled(Pill)`
58+
padding: ${({ theme }) => theme.spacing(1)} ${({ theme }) => theme.spacing(2)};
59+
`;
60+
61+
const StyledLogo = styled.img`
62+
height: 24px;
63+
width: 24px;
64+
`;
65+
66+
export const SettingsIntegrationComponent = ({
67+
integration,
68+
}: SettingsIntegrationComponentProps) => {
69+
const { copyToClipboard } = useCopyToClipboard();
70+
return (
71+
<StyledContainer
72+
to={integration.type === 'Active' ? integration.link : undefined}
73+
as={integration.type === 'Active' ? Link : 'div'}
74+
>
75+
<StyledSection>
76+
<StyledIntegrationLogo>
77+
<StyledLogo src={integration.from.image} alt={integration.from.key} />
78+
{isDefined(integration.to) && (
79+
<>
80+
<div></div>
81+
<StyledLogo src={integration.to.image} alt={integration.to.key} />
82+
</>
83+
)}
84+
</StyledIntegrationLogo>
85+
{integration.text}
86+
</StyledSection>
87+
{integration.type === 'Soon' ? (
88+
<StyledSoonPill label={t`Soon`} />
89+
) : integration.type === 'Active' ? (
90+
<Status color="green" text={t`Active`} />
91+
) : integration.type === 'Add' ? (
92+
<Button
93+
to={integration.link}
94+
Icon={IconPlus}
95+
title={t`Add`}
96+
size="small"
97+
/>
98+
) : integration.type === 'Use' ? (
99+
<Button
100+
to={integration.link}
101+
target="_blank"
102+
Icon={IconBolt}
103+
title={t`Use`}
104+
size="small"
105+
/>
106+
) : integration.type === 'Copy' ? (
107+
<Button
108+
onClick={() => {
109+
if (isDefined(integration.content)) {
110+
copyToClipboard(integration.content);
111+
}
112+
}}
113+
Icon={IconCopy}
114+
title={integration.linkText}
115+
size="small"
116+
/>
117+
) : (
118+
<Button
119+
to={integration.link}
120+
target="_blank"
121+
Icon={IconArrowUpRight}
122+
title={integration.linkText}
123+
size="small"
124+
/>
125+
)}
126+
</StyledContainer>
127+
);
128+
};
Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,7 @@
11
import { SETTINGS_INTEGRATION_NATIVE_CATEGORY } from '@/settings/integrations/constants/SettingsIntegrationsNative';
2-
import { SETTINGS_INTEGRATION_REQUEST_CATEGORY } from '@/settings/integrations/constants/SettingsIntegrationRequest';
3-
import { SETTINGS_INTEGRATION_ZAPIER_CATEGORY } from '@/settings/integrations/constants/SettingsIntegrationZapier';
42
import { type SettingsIntegrationCategory } from '@/settings/integrations/types/SettingsIntegrationCategory';
53

64
export const useSettingsIntegrationCategories =
75
(): SettingsIntegrationCategory[] => {
8-
return [
9-
SETTINGS_INTEGRATION_NATIVE_CATEGORY,
10-
SETTINGS_INTEGRATION_ZAPIER_CATEGORY,
11-
SETTINGS_INTEGRATION_REQUEST_CATEGORY,
12-
];
6+
return [SETTINGS_INTEGRATION_NATIVE_CATEGORY];
137
};
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
export type SettingsIntegrationType =
2+
| 'Active'
3+
| 'Add'
4+
| 'Goto'
5+
| 'Soon'
6+
| 'Use'
7+
| 'Copy';
8+
9+
export type SettingsIntegration = {
10+
from: { key: string; image: string };
11+
to?: { key: string; image: string } | null;
12+
type: SettingsIntegrationType;
13+
linkText?: string;
14+
content?: string;
15+
link: string;
16+
text: string;
17+
};
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import { type SettingsIntegration } from '@/settings/integrations/types/SettingsIntegration';
2+
3+
export type SettingsIntegrationCategory = {
4+
key: string;
5+
title: string;
6+
hyperlinkText?: string;
7+
hyperlink?: string | null;
8+
integrations: SettingsIntegration[];
9+
};
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import { SettingsPageContainer } from '@/settings/components/SettingsPageContainer';
2+
import { SettingsIntegrationGroup } from '@/settings/integrations/components/SettingsIntegrationGroup';
3+
import { useSettingsIntegrationCategories } from '@/settings/integrations/hooks/useSettingsIntegrationCategories';
4+
import { SubMenuTopBarContainer } from '@/ui/layout/page/components/SubMenuTopBarContainer';
5+
import { Trans, useLingui } from '@lingui/react/macro';
6+
import { SettingsPath } from 'twenty-shared/types';
7+
import { getSettingsPath } from 'twenty-shared/utils';
8+
9+
export const SettingsIntegrations = () => {
10+
const { t } = useLingui();
11+
const integrationCategories = useSettingsIntegrationCategories();
12+
13+
return (
14+
<SubMenuTopBarContainer
15+
title={t`Integrations`}
16+
links={[
17+
{
18+
children: <Trans>Workspace</Trans>,
19+
href: getSettingsPath(SettingsPath.Workspace),
20+
},
21+
{ children: <Trans>Integrations</Trans> },
22+
]}
23+
>
24+
<SettingsPageContainer>
25+
{integrationCategories.map((group) => (
26+
<SettingsIntegrationGroup key={group.key} integrationGroup={group} />
27+
))}
28+
</SettingsPageContainer>
29+
</SubMenuTopBarContainer>
30+
);
31+
};
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import { type Meta, type StoryObj } from '@storybook/react';
2+
import { within } from '@storybook/test';
3+
4+
import { SettingsPath } from 'twenty-shared/types';
5+
import { getSettingsPath } from 'twenty-shared/utils';
6+
import { SettingsIntegrations } from '~/pages/settings/integrations/SettingsIntegrations';
7+
import {
8+
PageDecorator,
9+
type PageDecoratorArgs,
10+
} from '~/testing/decorators/PageDecorator';
11+
import { graphqlMocks } from '~/testing/graphqlMocks';
12+
13+
import { sleep } from '~/utils/sleep';
14+
15+
const meta: Meta<PageDecoratorArgs> = {
16+
title: 'Pages/Settings/Integrations/SettingsIntegrations',
17+
component: SettingsIntegrations,
18+
decorators: [PageDecorator],
19+
args: { routePath: getSettingsPath(SettingsPath.Integrations) },
20+
parameters: {
21+
msw: graphqlMocks,
22+
},
23+
};
24+
25+
export default meta;
26+
27+
export type Story = StoryObj<typeof SettingsIntegrations>;
28+
29+
export const Default: Story = {
30+
play: async ({ canvasElement }) => {
31+
const canvas = within(canvasElement);
32+
33+
await sleep(1000);
34+
35+
await canvas.findByText('Go to GitHub');
36+
},
37+
};

0 commit comments

Comments
 (0)