Feat: API Playground (#10376)

/claim #10283

---------

Co-authored-by: Félix Malfait <felix@twenty.com>
Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
This commit is contained in:
oliver
2025-03-07 09:03:57 -08:00
committed by GitHub
parent d1518764a8
commit fc287dac78
55 changed files with 2915 additions and 163 deletions
@@ -0,0 +1,74 @@
import { SettingsPageContainer } from '@/settings/components/SettingsPageContainer';
import { SettingsApiKeysTable } from '@/settings/developers/components/SettingsApiKeysTable';
import { PlaygroundSetupForm } from '@/settings/playground/components/PlaygroundSetupForm';
import { StyledSettingsApiPlaygroundCoverImage } from '@/settings/playground/components/SettingsPlaygroundCoverImage';
import { SettingsPath } from '@/types/SettingsPath';
import { SubMenuTopBarContainer } from '@/ui/layout/page/components/SubMenuTopBarContainer';
import styled from '@emotion/styled';
import { Trans, useLingui } from '@lingui/react/macro';
import { Button, H2Title, IconPlus, MOBILE_VIEWPORT, Section } from 'twenty-ui';
import { getSettingsPath } from '~/utils/navigation/getSettingsPath';
const StyledButtonContainer = styled.div`
display: flex;
justify-content: flex-end;
padding-top: ${({ theme }) => theme.spacing(2)};
@media (max-width: ${MOBILE_VIEWPORT}px) {
padding-top: ${({ theme }) => theme.spacing(5)};
}
`;
const StyledContainer = styled.div`
display: flex;
flex-direction: column;
overflow: hidden;
gap: ${({ theme }) => theme.spacing(2)};
`;
export const SettingsApiKeys = () => {
const { t } = useLingui();
return (
<SubMenuTopBarContainer
title={t`APIs`}
links={[
{
children: <Trans>Workspace</Trans>,
href: getSettingsPath(SettingsPath.Workspace),
},
{ children: <Trans>APIs</Trans> },
]}
>
<SettingsPageContainer>
<StyledContainer>
<Section>
<H2Title
title={t`Playground`}
description={t`Try our REST or GraphQL API playgrounds.`}
/>
<StyledSettingsApiPlaygroundCoverImage />
<PlaygroundSetupForm />
</Section>
</StyledContainer>
<StyledContainer>
<Section>
<H2Title
title={t`API keys`}
description={t`Active API keys created by you or your team.`}
/>
<SettingsApiKeysTable />
<StyledButtonContainer>
<Button
Icon={IconPlus}
title={t`Create API key`}
size="small"
variant="secondary"
to={getSettingsPath(SettingsPath.DevelopersNewApiKey)}
/>
</StyledButtonContainer>
</Section>
</StyledContainer>
</SettingsPageContainer>
</SubMenuTopBarContainer>
);
};
@@ -90,7 +90,7 @@ export const SettingsDevelopersApiKeyDetail = () => {
updateOneRecordInput: { revokedAt: DateTime.now().toString() },
});
if (redirect) {
navigate(SettingsPath.Developers);
navigate(SettingsPath.APIs);
}
} catch (err) {
enqueueSnackBar(t`Error deleting api key: ${err}`, {
@@ -166,8 +166,8 @@ export const SettingsDevelopersApiKeyDetail = () => {
href: getSettingsPath(SettingsPath.Workspace),
},
{
children: t`Developers`,
href: getSettingsPath(SettingsPath.Developers),
children: t`APIs`,
href: getSettingsPath(SettingsPath.APIs),
},
{ children: t`${apiKeyName} API Key` },
]}
@@ -86,8 +86,8 @@ export const SettingsDevelopersApiKeysNew = () => {
href: getSettingsPath(SettingsPath.Workspace),
},
{
children: t`Developers`,
href: getSettingsPath(SettingsPath.Developers),
children: t`APIs`,
href: getSettingsPath(SettingsPath.APIs),
},
{ children: t`New Key` },
]}
@@ -95,7 +95,7 @@ export const SettingsDevelopersApiKeysNew = () => {
<SaveAndCancelButtons
isSaveDisabled={!canSave}
onCancel={() => {
navigateSettings(SettingsPath.Developers);
navigateSettings(SettingsPath.APIs);
}}
onSave={handleSave}
/>