From 82f9783fe6581ebcc66fc0d44f34136ca9658227 Mon Sep 17 00:00:00 2001 From: Mateusz Kwasniewski Date: Mon, 2 Sep 2024 15:58:00 +0200 Subject: [PATCH] feat: connect sdk step 1 (#8042) --- .../component/onboarding/ConnectSDKDialog.tsx | 234 ++++++++++++++++++ .../ProjectFeatureToggles.tsx | 8 + 2 files changed, 242 insertions(+) create mode 100644 frontend/src/component/onboarding/ConnectSDKDialog.tsx diff --git a/frontend/src/component/onboarding/ConnectSDKDialog.tsx b/frontend/src/component/onboarding/ConnectSDKDialog.tsx new file mode 100644 index 0000000000..eaad1c0e9d --- /dev/null +++ b/frontend/src/component/onboarding/ConnectSDKDialog.tsx @@ -0,0 +1,234 @@ +import { + Box, + Button, + Dialog, + styled, + type Theme, + Typography, +} from '@mui/material'; +import { SingleSelectConfigButton } from '../common/DialogFormTemplate/ConfigButtons/SingleSelectConfigButton'; +import EnvironmentsIcon from '@mui/icons-material/CloudCircle'; +import { useEffect, useState } from 'react'; +import { ProjectIcon } from 'component/common/ProjectIcon/ProjectIcon'; +import CodeIcon from '@mui/icons-material/Code'; + +interface IConnectSDKDialogProps { + open: boolean; + onClose: () => void; + project: string; + environments: string[]; +} + +const ConceptsDefinitions = styled('div')(({ theme }) => ({ + backgroundColor: theme.palette.background.sidebar, + padding: theme.spacing(8), + flexBasis: '30%', +})); + +const IconStyle = ({ theme }: { theme: Theme }) => ({ + color: theme.palette.primary.contrastText, + fontSize: theme.fontSizes.smallBody, + marginTop: theme.spacing(0.5), +}); + +const StyledProjectIcon = styled(ProjectIcon)(IconStyle); +const StyledEnvironmentsIcon = styled(EnvironmentsIcon)(IconStyle); +const StyledCodeIcon = styled(CodeIcon)(IconStyle); + +const ConceptItem = styled('div')(({ theme }) => ({ + display: 'flex', + gap: theme.spacing(1.5), + alignItems: 'flex-start', + marginTop: theme.spacing(3), +})); + +const ConceptSummary = styled('div')(({ theme }) => ({ + color: theme.palette.primary.contrastText, + fontSize: theme.fontSizes.smallBody, + fontWeight: theme.fontWeight.bold, + marginBottom: theme.spacing(2), +})); + +const ConceptDetails = styled('p')(({ theme }) => ({ + color: theme.palette.primary.contrastText, + fontSize: theme.fontSizes.smallerBody, + marginBottom: theme.spacing(2), +})); + +export const APIKeyGeneration = styled('div')(({ theme }) => ({ + backgroundColor: theme.palette.background.paper, + display: 'flex', + flexDirection: 'column', + flexBasis: '70%', +})); + +export const SpacedContainer = styled('div')(({ theme }) => ({ + padding: theme.spacing(5, 8, 3, 8), + display: 'flex', + flexDirection: 'column', + gap: theme.spacing(3), +})); + +const StyledDialog = styled(Dialog)(({ theme }) => ({ + '& .MuiDialog-paper': { + borderRadius: theme.shape.borderRadiusLarge, + maxWidth: theme.spacing(170), + width: '100%', + backgroundColor: 'transparent', + }, + padding: 0, + '& .MuiPaper-root > section': { + overflowX: 'hidden', + }, +})); + +const SectionHeader = styled('div')(({ theme }) => ({ + fontWeight: theme.fontWeight.bold, + marginBottom: theme.spacing(1), + fontSize: theme.fontSizes.bodySize, +})); + +const SectionDescription = styled('p')(({ theme }) => ({ + color: theme.palette.text.secondary, + fontSize: theme.fontSizes.smallBody, + marginBottom: theme.spacing(2), +})); + +const NextStepSection = styled('div')(({ theme }) => ({ + marginTop: 'auto', + borderTop: `1px solid ${theme.palette.divider}}`, +})); + +const NextStepSectionSpacedContainer = styled('div')(({ theme }) => ({ + display: 'flex', + justifyContent: 'space-between', + alignItems: 'center', + padding: theme.spacing(3, 8, 3, 8), +})); + +export const ConnectSDKDialog = ({ + open, + onClose, + environments, +}: IConnectSDKDialogProps) => { + const [environment, setEnvironment] = useState(''); + const longestEnv = Math.max( + ...environments.map((environment) => environment.length), + ); + + useEffect(() => { + if (environments.length > 0) { + setEnvironment(environments[0]); + } + }, [JSON.stringify(environments)]); + + return ( + + + + + + Connect an SDK to Unleash + + + Environment + + The environment SDK will connect to in order to + retrieve configuration. + + {environments.length > 0 ? ( + ({ + label: environment, + value: environment, + }), + )} + onChange={(value: any) => { + setEnvironment(value); + }} + button={{ + label: environment, + icon: , + labelWidth: `${longestEnv + 5}ch`, + }} + search={{ + label: 'Filter project mode options', + placeholder: 'Select project mode', + }} + /> + ) : null} + + + + API Key + + You currently have no active API keys for this + project/environment combination. You'll need to + generate and API key in order to proceed with + connecting your SDK. + + + + + + + + + Next: Choose SDK and connect + + + + + + + + + + + Flags live in projects + + + Projects are containers for feature flags. When + you create a feature flag it will belong to the + project you create it in. + + + + + + + + Flags have configuration in environments + + + In Unleash you can have multiple environments. + Each feature flag will have different + configuration in every environment. + + + + + + + + SDKs connect to Unleash to retrieve + configuration + + + When you connect an SDK to Unleash it will use + the API key to deduce which feature flags to + retrieve and from which environment to retrieve + configuration. + + + + + + + ); +}; diff --git a/frontend/src/component/project/Project/PaginatedProjectFeatureToggles/ProjectFeatureToggles.tsx b/frontend/src/component/project/Project/PaginatedProjectFeatureToggles/ProjectFeatureToggles.tsx index 359c2ea06b..183d150412 100644 --- a/frontend/src/component/project/Project/PaginatedProjectFeatureToggles/ProjectFeatureToggles.tsx +++ b/frontend/src/component/project/Project/PaginatedProjectFeatureToggles/ProjectFeatureToggles.tsx @@ -42,6 +42,7 @@ import { AvatarCell } from './AvatarCell'; import { ProjectOnboarding } from './ProjectOnboarding/ProjectOnboarding'; import { useUiFlag } from 'hooks/useUiFlag'; import { styled } from '@mui/material'; +import { ConnectSDKDialog } from '../../../onboarding/ConnectSDKDialog'; interface IPaginatedProjectFeatureTogglesProps { environments: string[]; @@ -489,6 +490,13 @@ export const ProjectFeatureToggles = ({ {rowActionsDialogs} {featureToggleModals} + + {}} + project={projectId} + environments={environments} + />