1
0
mirror of https://github.com/Unleash/unleash.git synced 2025-04-10 01:16:39 +02:00

feat: can select client and frontend sdk (#8066)

This commit is contained in:
Mateusz Kwasniewski 2024-09-04 08:26:16 +02:00 committed by GitHub
parent 061fa44a20
commit 8c5a3e03a4
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 135 additions and 24 deletions

View File

@ -7,8 +7,8 @@ import {
useTheme, useTheme,
} from '@mui/material'; } from '@mui/material';
import { GenrateApiKeyConcepts, GenerateApiKey } from './GenerateApiKey'; import { GenrateApiKeyConcepts, GenerateApiKey } from './GenerateApiKey';
import { useState } from 'react'; import { useEffect, useState } from 'react';
import { SelectSdk } from './SelectSdk'; import { type Sdk, SelectSdk } from './SelectSdk';
interface IConnectSDKDialogProps { interface IConnectSDKDialogProps {
open: boolean; open: boolean;
@ -57,7 +57,7 @@ const NextStepSectionSpacedContainer = styled('div')(({ theme }) => ({
type OnboardingStage = type OnboardingStage =
| { name: 'select-sdk' } | { name: 'select-sdk' }
| { name: 'generate-api-key'; sdkType: 'CLIENT' | 'FRONTEND' } | { name: 'generate-api-key' }
| { name: 'test-connection' }; | { name: 'test-connection' };
export const ConnectSdkDialog = ({ export const ConnectSdkDialog = ({
@ -68,25 +68,48 @@ export const ConnectSdkDialog = ({
}: IConnectSDKDialogProps) => { }: IConnectSDKDialogProps) => {
const theme = useTheme(); const theme = useTheme();
const isLargeScreen = useMediaQuery(theme.breakpoints.up('lg')); const isLargeScreen = useMediaQuery(theme.breakpoints.up('lg'));
const [sdk, setSdk] = useState<Sdk | null>(null);
const [environment, setEnvironment] = useState<string | null>(null);
const [stage, setStage] = useState<OnboardingStage>({ name: 'select-sdk' }); const [stage, setStage] = useState<OnboardingStage>({ name: 'select-sdk' });
useEffect(() => {
if (environments.length > 0) {
setEnvironment(environments[0]);
}
}, [JSON.stringify(environments)]);
return ( return (
<StyledDialog open={open} onClose={onClose}> <StyledDialog open={open} onClose={onClose}>
<Box sx={{ display: 'flex' }}> <Box sx={{ display: 'flex' }}>
<ConnectSdk> <ConnectSdk>
{stage.name === 'select-sdk' ? <SelectSdk /> : null} {stage.name === 'select-sdk' ? (
{stage.name === 'generate-api-key' ? ( <SelectSdk
onSelect={(sdk) => {
setSdk(sdk);
setStage({ name: 'generate-api-key' });
}}
/>
) : null}
{stage.name === 'generate-api-key' && sdk && environment ? (
<GenerateApiKey <GenerateApiKey
environments={environments} environments={environments}
environment={environment}
project={project} project={project}
sdkType={stage.sdkType} sdkType={sdk.type}
onEnvSelect={setEnvironment}
/> />
) : null} ) : null}
{stage.name === 'generate-api-key' ? ( {stage.name === 'generate-api-key' ? (
<Navigation> <Navigation>
<NextStepSectionSpacedContainer> <NextStepSectionSpacedContainer>
<Button variant='text' color='inherit'> <Button
variant='text'
color='inherit'
onClick={() => {
setStage({ name: 'select-sdk' });
}}
>
Back Back
</Button> </Button>
<Button variant='contained'>Next</Button> <Button variant='contained'>Next</Button>

View File

@ -1,4 +1,3 @@
import { useEffect, useState } from 'react';
import { useProjectApiTokens } from '../../hooks/api/getters/useProjectApiTokens/useProjectApiTokens'; import { useProjectApiTokens } from '../../hooks/api/getters/useProjectApiTokens/useProjectApiTokens';
import useProjectApiTokensApi from '../../hooks/api/actions/useProjectApiTokensApi/useProjectApiTokensApi'; import useProjectApiTokensApi from '../../hooks/api/actions/useProjectApiTokensApi/useProjectApiTokensApi';
import { parseToken } from './parseToken'; import { parseToken } from './parseToken';
@ -263,26 +262,22 @@ export const GenrateApiKeyConcepts = () => (
interface GenerateApiKeyProps { interface GenerateApiKeyProps {
project: string; project: string;
environments: string[]; environments: string[];
sdkType: 'CLIENT' | 'FRONTEND'; environment: string;
sdkType: 'client' | 'frontend';
onEnvSelect: (env: string) => void;
} }
export const GenerateApiKey = ({ export const GenerateApiKey = ({
environments, environments,
environment,
project, project,
sdkType, sdkType,
onEnvSelect,
}: GenerateApiKeyProps) => { }: GenerateApiKeyProps) => {
const [environment, setEnvironment] = useState('');
useEffect(() => {
if (environments.length > 0) {
setEnvironment(environments[0]);
}
}, [JSON.stringify(environments)]);
const { tokens, refetch: refreshTokens } = useProjectApiTokens(project); const { tokens, refetch: refreshTokens } = useProjectApiTokens(project);
const { createToken, loading: creatingToken } = useProjectApiTokensApi(); const { createToken, loading: creatingToken } = useProjectApiTokensApi();
const currentEnvironmentToken = tokens.find( const currentEnvironmentToken = tokens.find(
(token) => token.environment === environment, (token) => token.environment === environment && token.type === sdkType,
); );
const parsedToken = parseToken(currentEnvironmentToken?.secret); const parsedToken = parseToken(currentEnvironmentToken?.secret);
@ -318,7 +313,7 @@ export const GenerateApiKey = ({
<ChooseEnvironment <ChooseEnvironment
environments={environments} environments={environments}
currentEnvironment={environment} currentEnvironment={environment}
onSelect={setEnvironment} onSelect={onEnvSelect}
/> />
) : null} ) : null}
</Box> </Box>

View File

@ -1,24 +1,117 @@
import { Box, styled, Typography } from '@mui/material'; import { Box, Link, styled, Typography } from '@mui/material';
import type { FC } from 'react';
const SpacedContainer = styled('div')(({ theme }) => ({ const SpacedContainer = styled('div')(({ theme }) => ({
padding: theme.spacing(5, 8, 3, 8), padding: theme.spacing(5, 8, 8, 8),
display: 'flex', display: 'flex',
flexDirection: 'column', flexDirection: 'column',
gap: theme.spacing(3), gap: theme.spacing(3),
})); }));
const SectionHeader = styled('div')(({ theme }) => ({ const PrimarySectionHeader = styled('div')(({ theme }) => ({
fontWeight: theme.fontWeight.bold, fontWeight: theme.fontWeight.bold,
marginBottom: theme.spacing(1), marginBottom: theme.spacing(1),
fontSize: theme.fontSizes.bodySize, fontSize: theme.fontSizes.bodySize,
})); }));
export const SelectSdk = () => { const SecondarySectionHeader = styled('div')(({ theme }) => ({
marginTop: theme.spacing(4),
marginBottom: theme.spacing(2),
fontSize: theme.fontSizes.bodySize,
}));
const SdkListSection = styled('div')(({ theme }) => ({
backgroundColor: theme.palette.background.elevation1,
borderRadius: theme.shape.borderRadius,
padding: theme.spacing(3, 6),
display: 'flex',
gap: theme.spacing(2),
alignItems: 'center',
justifyContent: 'flex-start',
flexWrap: 'wrap',
}));
const SdkTile = styled('div')(({ theme }) => ({
fontSize: theme.fontSizes.smallBody,
backgroundColor: theme.palette.common.white,
borderRadius: theme.shape.borderRadius,
padding: theme.spacing(2),
display: 'flex',
justifyContent: 'space-between',
width: '170px',
}));
const serverSdks = [
{ name: 'Node' },
{ name: 'Golang' },
{ name: 'Ruby' },
{ name: 'PHP' },
{ name: 'Rust' },
{ name: 'DotNet' },
{ name: 'Java' },
{ name: 'Python' },
];
const clientSdks = [
{ name: 'Javascript' },
{ name: 'React' },
{ name: 'Vue' },
{ name: 'Svelte' },
{ name: 'Swift' },
{ name: 'Android' },
{ name: 'Flutter' },
];
type SdkType = 'client' | 'frontend';
export type Sdk = { name: string; type: SdkType };
interface ISelectSdkProps {
onSelect: (sdk: Sdk) => void;
}
export const SelectSdk: FC<ISelectSdkProps> = ({ onSelect }) => {
return ( return (
<SpacedContainer> <SpacedContainer>
<Typography variant='h2'>Connect an SDK to Unleash</Typography> <Typography variant='h2'>Connect an SDK to Unleash</Typography>
<Box sx={{ mt: 4 }}> <Box sx={{ mt: 4 }}>
<SectionHeader>Select SDK</SectionHeader> <PrimarySectionHeader>Select SDK</PrimarySectionHeader>
<SecondarySectionHeader>
Server side SDKs
</SecondarySectionHeader>
<SdkListSection>
{serverSdks.map((sdk) => (
<SdkTile>
<b>{sdk.name}</b>{' '}
<Link
onClick={() =>
onSelect({ name: sdk.name, type: 'client' })
}
component='button'
>
Select
</Link>
</SdkTile>
))}
</SdkListSection>
<SecondarySectionHeader>
Client side SDKs
</SecondarySectionHeader>
<SdkListSection>
{clientSdks.map((sdk) => (
<SdkTile>
<b>{sdk.name}</b>{' '}
<Link
onClick={() =>
onSelect({
name: sdk.name,
type: 'frontend',
})
}
component='button'
>
Select
</Link>
</SdkTile>
))}
</SdkListSection>
</Box> </Box>
</SpacedContainer> </SpacedContainer>
); );