feat: add Active and Add integration card displays (#4591)

* feat: add Active and Add integration card displays

Closes #4541

* docs: add PaymentSuccess page stories

* refactor: move page components
This commit is contained in:
Thaïs
2024-03-25 18:53:30 +01:00
committed by GitHub
parent 6ab43c608f
commit 8baa59b6f4
19 changed files with 242 additions and 117 deletions

View File

@ -1,43 +0,0 @@
import { useEffect } from 'react';
import { useNavigate, useSearchParams } from 'react-router-dom';
import { useRecoilValue } from 'recoil';
import { useAuth } from '@/auth/hooks/useAuth';
import { useIsLogged } from '@/auth/hooks/useIsLogged';
import { currentWorkspaceState } from '@/auth/states/currentWorkspaceState';
import { AppPath } from '@/types/AppPath';
export const VerifyEffect = () => {
const [searchParams] = useSearchParams();
const loginToken = searchParams.get('loginToken');
const currentWorkspace = useRecoilValue(currentWorkspaceState);
const isLogged = useIsLogged();
const navigate = useNavigate();
const { verify } = useAuth();
useEffect(() => {
const getTokens = async () => {
if (!loginToken) {
navigate(AppPath.SignInUp);
} else {
await verify(loginToken);
if (currentWorkspace?.activationStatus === 'active') {
navigate(AppPath.Index);
} else {
navigate(AppPath.CreateWorkspace);
}
}
};
if (!isLogged) {
getTokens();
}
// Verify only needs to run once at mount
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
return <></>;
};

View File

@ -0,0 +1,48 @@
import { getOperationName } from '@apollo/client/utilities';
import { Meta, StoryObj } from '@storybook/react';
import { within } from '@storybook/testing-library';
import { graphql, HttpResponse } from 'msw';
import { AppPath } from '@/types/AppPath';
import { GET_CURRENT_USER } from '@/users/graphql/queries/getCurrentUser';
import {
PageDecorator,
PageDecoratorArgs,
} from '~/testing/decorators/PageDecorator';
import { graphqlMocks } from '~/testing/graphqlMocks';
import { mockedOnboardingUsersData } from '~/testing/mock-data/users';
import { PaymentSuccess } from '../PaymentSuccess';
const meta: Meta<PageDecoratorArgs> = {
title: 'Pages/Auth/PaymentSuccess',
component: PaymentSuccess,
decorators: [PageDecorator],
args: { routePath: AppPath.PlanRequiredSuccess },
parameters: {
msw: {
handlers: [
graphql.query(getOperationName(GET_CURRENT_USER) ?? '', () => {
return HttpResponse.json({
data: {
currentUser: mockedOnboardingUsersData[0],
},
});
}),
graphqlMocks.handlers,
],
},
},
};
export default meta;
export type Story = StoryObj<typeof PaymentSuccess>;
export const Default: Story = {
play: async ({ canvasElement }) => {
const canvas = within(canvasElement);
await canvas.findByText('Start');
},
};

View File

@ -2,19 +2,21 @@ import { useEffect } from 'react';
import { useNavigate, useParams } from 'react-router-dom';
import { SettingsPageContainer } from '@/settings/components/SettingsPageContainer';
import { useSettingsIntegrationCategories } from '@/settings/integrations/hooks/useSettingsIntegrationCategories';
import { AppPath } from '@/types/AppPath';
import { IconSettings } from '@/ui/display/icon';
import { SubMenuTopBarContainer } from '@/ui/layout/page/SubMenuTopBarContainer';
import { Breadcrumb } from '@/ui/navigation/bread-crumb/components/Breadcrumb';
import { useIsFeatureEnabled } from '@/workspace/hooks/useIsFeatureEnabled';
import { SETTINGS_INTEGRATION_ALL_CATEGORY } from '~/pages/settings/integrations/constants/SettingsIntegrationAll';
export const SettingsIntegrationDetail = () => {
const { integrationKey = '' } = useParams();
const navigate = useNavigate();
const integrationLabel = SETTINGS_INTEGRATION_ALL_CATEGORY.integrations.find(
const [integrationCategoryAll] = useSettingsIntegrationCategories();
const integration = integrationCategoryAll.integrations.find(
({ from: { key } }) => key === integrationKey,
)?.text;
);
const isAirtableIntegrationEnabled = useIsFeatureEnabled(
'IS_AIRTABLE_INTEGRATION_ENABLED',
@ -23,23 +25,17 @@ export const SettingsIntegrationDetail = () => {
'IS_POSTGRESQL_INTEGRATION_ENABLED',
);
const isIntegrationAvailable =
(integrationKey === 'airtable' && isAirtableIntegrationEnabled) ||
(integrationKey === 'postgresql' && isPostgresqlIntegrationEnabled);
!!integration &&
((integrationKey === 'airtable' && isAirtableIntegrationEnabled) ||
(integrationKey === 'postgresql' && isPostgresqlIntegrationEnabled));
useEffect(() => {
if (!integrationLabel || !isIntegrationAvailable) {
return navigate(AppPath.NotFound);
if (!isIntegrationAvailable) {
navigate(AppPath.NotFound);
}
}, [
integrationLabel,
integrationKey,
isAirtableIntegrationEnabled,
isIntegrationAvailable,
isPostgresqlIntegrationEnabled,
navigate,
]);
}, [integration, integrationKey, navigate, isIntegrationAvailable]);
if (!integrationLabel || !isIntegrationAvailable) return null;
if (!isIntegrationAvailable) return null;
return (
<SubMenuTopBarContainer Icon={IconSettings} title="Settings">
@ -47,7 +43,7 @@ export const SettingsIntegrationDetail = () => {
<Breadcrumb
links={[
{ children: 'Integrations', href: '/settings/integrations' },
{ children: integrationLabel },
{ children: integration.text },
]}
/>
</SettingsPageContainer>

View File

@ -1,18 +1,20 @@
import { SettingsPageContainer } from '@/settings/components/SettingsPageContainer';
import { SettingsIntegrationGroup } from '@/settings/integrations/components/SettingsIntegrationGroup';
import { useSettingsIntegrationCategories } from '@/settings/integrations/hooks/useSettingsIntegrationCategories';
import { IconSettings } from '@/ui/display/icon';
import { SubMenuTopBarContainer } from '@/ui/layout/page/SubMenuTopBarContainer';
import { Breadcrumb } from '@/ui/navigation/bread-crumb/components/Breadcrumb';
import { SETTINGS_INTEGRATION_CATEGORIES } from '~/pages/settings/integrations/constants/SettingsIntegrationCategories';
export const SettingsIntegrations = () => {
const integrationCategories = useSettingsIntegrationCategories();
return (
<SubMenuTopBarContainer Icon={IconSettings} title="Settings">
<SettingsPageContainer>
<Breadcrumb links={[{ children: 'Integrations' }]} />
{SETTINGS_INTEGRATION_CATEGORIES.map((group) => {
return <SettingsIntegrationGroup integrationGroup={group} />;
})}
{integrationCategories.map((group) => (
<SettingsIntegrationGroup key={group.key} integrationGroup={group} />
))}
</SettingsPageContainer>
</SubMenuTopBarContainer>
);

View File

@ -1,26 +0,0 @@
import { SettingsIntegrationCategory } from '~/pages/settings/integrations/types/SettingsIntegrationCategory';
export const SETTINGS_INTEGRATION_ALL_CATEGORY: SettingsIntegrationCategory = {
key: 'all',
title: 'All',
integrations: [
{
from: {
key: 'airtable',
image: '/images/integrations/airtable-logo.png',
},
type: 'Soon',
text: 'Airtable',
link: '/settings/integrations/airtable',
},
{
from: {
key: 'postgresql',
image: '/images/integrations/postgresql-logo.png',
},
type: 'Soon',
text: 'PostgreSQL',
link: '/settings/integrations/postgresql',
},
],
};

View File

@ -1,12 +0,0 @@
import { SETTINGS_INTEGRATION_ALL_CATEGORY } from '~/pages/settings/integrations/constants/SettingsIntegrationAll';
import { SETTINGS_INTEGRATION_REQUEST_CATEGORY } from '~/pages/settings/integrations/constants/SettingsIntegrationRequest';
import { SETTINGS_INTEGRATION_WINDMILL_CATEGORY } from '~/pages/settings/integrations/constants/SettingsIntegrationWindmill';
import { SETTINGS_INTEGRATION_ZAPIER_CATEGORY } from '~/pages/settings/integrations/constants/SettingsIntegrationZapier';
import { SettingsIntegrationCategory } from '~/pages/settings/integrations/types/SettingsIntegrationCategory';
export const SETTINGS_INTEGRATION_CATEGORIES: SettingsIntegrationCategory[] = [
SETTINGS_INTEGRATION_ALL_CATEGORY,
SETTINGS_INTEGRATION_ZAPIER_CATEGORY,
SETTINGS_INTEGRATION_WINDMILL_CATEGORY,
SETTINGS_INTEGRATION_REQUEST_CATEGORY,
];

View File

@ -1,18 +0,0 @@
import { SettingsIntegrationCategory } from '~/pages/settings/integrations/types/SettingsIntegrationCategory';
export const SETTINGS_INTEGRATION_REQUEST_CATEGORY: SettingsIntegrationCategory =
{
key: 'request',
title: 'Request an integration',
hyperlink: null,
integrations: [
{
from: { key: 'github', image: '/images/integrations/github-logo.png' },
to: null,
type: 'Goto',
text: 'Request an integration on Github conversations',
link: 'https://github.com/twentyhq/twenty/discussions/categories/ideas',
linkText: 'Go to GitHub',
},
],
};

View File

@ -1,21 +0,0 @@
import { SettingsIntegrationCategory } from '~/pages/settings/integrations/types/SettingsIntegrationCategory';
export const SETTINGS_INTEGRATION_WINDMILL_CATEGORY: SettingsIntegrationCategory =
{
key: 'windmill',
title: 'With Windmill',
hyperlink: null,
integrations: [
{
from: {
key: 'windmill',
image: '/images/integrations/windmill-logo.png',
},
to: null,
type: 'Goto',
text: 'Create a workflow with Windmill',
link: 'https://www.windmill.dev',
linkText: 'Go to Windmill',
},
],
};

View File

@ -1,42 +0,0 @@
import { SettingsIntegrationCategory } from '~/pages/settings/integrations/types/SettingsIntegrationCategory';
export const SETTINGS_INTEGRATION_ZAPIER_CATEGORY: SettingsIntegrationCategory =
{
key: 'zapier',
title: 'With Zapier',
hyperlinkText: 'See all zaps',
hyperlink: 'https://zapier.com/apps/twenty/integrations',
integrations: [
{
from: { key: 'twenty', image: '/images/integrations/twenty-logo.svg' },
to: { key: 'slack', image: '/images/integrations/slack-logo.png' },
type: 'Use',
text: 'Post to Slack when a company is updated',
link: 'https://zapier.com/apps/twenty/integrations/slack',
},
{
from: { key: 'cal', image: '/images/integrations/cal-logo.png' },
to: { key: 'twenty', image: '/images/integrations/twenty-logo.svg' },
type: 'Use',
text: 'Create a person when Cal.com event is created',
link: 'https://zapier.com/apps/twenty/integrations/calcom',
},
{
from: {
key: 'mailchimp',
image: '/images/integrations/mailchimp-logo.png',
},
to: { key: 'twenty', image: '/images/integrations/twenty-logo.svg' },
type: 'Use',
text: 'Create a person when a MailChimp sub is created',
link: 'https://zapier.com/apps/twenty/integrations/mailchimp',
},
{
from: { key: 'tally', image: '/images/integrations/tally-logo.png' },
to: { key: 'twenty', image: '/images/integrations/twenty-logo.svg' },
type: 'Use',
text: 'Create a company when a Tally form is sent',
link: 'https://zapier.com/apps/twenty/integrations/tally',
},
],
};

View File

@ -1,10 +0,0 @@
export type SettingsIntegrationType = 'Use' | 'Goto' | 'Soon';
export type SettingsIntegration = {
from: { key: string; image: string };
to?: { key: string; image: string } | null;
type: SettingsIntegrationType;
linkText?: string;
link: string;
text: string;
};

View File

@ -1,9 +0,0 @@
import { SettingsIntegration } from '~/pages/settings/integrations/types/SettingsIntegration';
export type SettingsIntegrationCategory = {
key: string;
title: string;
hyperlinkText?: string;
hyperlink?: string | null;
integrations: SettingsIntegration[];
};