mirror of
https://github.com/Unleash/unleash.git
synced 2025-02-09 00:18:00 +01:00
feat: sdk connected using production snippet (#8266)
1. Fix nodejs snippet 2. Tie the snippet to the completed stage. 3. Pull out the code renderer, to shared component ![image](https://github.com/user-attachments/assets/886c9502-4407-4aa7-8b63-84035f8cdb8a)
This commit is contained in:
parent
823f6330b7
commit
d0499dbf94
88
frontend/src/component/onboarding/CodeRenderer.tsx
Normal file
88
frontend/src/component/onboarding/CodeRenderer.tsx
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
import type { CodeComponent } from 'react-markdown/lib/ast-to-react';
|
||||||
|
import type { FC } from 'react';
|
||||||
|
import copy from 'copy-to-clipboard';
|
||||||
|
import useToast from '../../hooks/useToast';
|
||||||
|
import { IconButton, styled, Tooltip } from '@mui/material';
|
||||||
|
import CopyIcon from '@mui/icons-material/FileCopy';
|
||||||
|
import type { SdkName } from './sharedTypes';
|
||||||
|
import android from './snippets/android.md?raw';
|
||||||
|
import go from './snippets/go.md?raw';
|
||||||
|
import javascript from './snippets/javascript.md?raw';
|
||||||
|
import nodejs from './snippets/nodejs.md?raw';
|
||||||
|
import python from './snippets/python.md?raw';
|
||||||
|
import ruby from './snippets/ruby.md?raw';
|
||||||
|
import svelte from './snippets/svelte.md?raw';
|
||||||
|
import vue from './snippets/vue.md?raw';
|
||||||
|
import flutter from './snippets/flutter.md?raw';
|
||||||
|
import java from './snippets/java.md?raw';
|
||||||
|
import dotnet from './snippets/dotnet.md?raw';
|
||||||
|
import php from './snippets/php.md?raw';
|
||||||
|
import react from './snippets/react.md?raw';
|
||||||
|
import rust from './snippets/rust.md?raw';
|
||||||
|
import swift from './snippets/swift.md?raw';
|
||||||
|
|
||||||
|
export const codeRenderSnippets: Record<SdkName, string> = {
|
||||||
|
Android: android,
|
||||||
|
Go: go,
|
||||||
|
JavaScript: javascript,
|
||||||
|
'Node.js': nodejs,
|
||||||
|
Python: python,
|
||||||
|
Ruby: ruby,
|
||||||
|
Svelte: svelte,
|
||||||
|
Vue: vue,
|
||||||
|
Flutter: flutter,
|
||||||
|
Java: java,
|
||||||
|
'.NET': dotnet,
|
||||||
|
PHP: php,
|
||||||
|
React: react,
|
||||||
|
Rust: rust,
|
||||||
|
Swift: swift,
|
||||||
|
};
|
||||||
|
|
||||||
|
const StyledCodeBlock = styled('pre')(({ theme }) => ({
|
||||||
|
backgroundColor: theme.palette.background.elevation1,
|
||||||
|
padding: theme.spacing(2),
|
||||||
|
borderRadius: theme.shape.borderRadius,
|
||||||
|
overflow: 'auto',
|
||||||
|
fontSize: theme.typography.body2.fontSize,
|
||||||
|
wordBreak: 'break-all',
|
||||||
|
whiteSpace: 'pre-wrap',
|
||||||
|
position: 'relative',
|
||||||
|
maxHeight: theme.spacing(34),
|
||||||
|
}));
|
||||||
|
|
||||||
|
const CopyToClipboard = styled(Tooltip)(({ theme }) => ({
|
||||||
|
position: 'absolute',
|
||||||
|
top: theme.spacing(1),
|
||||||
|
right: theme.spacing(1),
|
||||||
|
}));
|
||||||
|
|
||||||
|
const CopyBlock: FC<{ title: string; code: string }> = ({ title, code }) => {
|
||||||
|
const onCopyToClipboard = (data: string) => () => {
|
||||||
|
copy(data);
|
||||||
|
setToastData({
|
||||||
|
type: 'success',
|
||||||
|
title: 'Copied to clipboard',
|
||||||
|
});
|
||||||
|
};
|
||||||
|
const { setToastData } = useToast();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<StyledCodeBlock>
|
||||||
|
{code}
|
||||||
|
<CopyToClipboard title={title} arrow>
|
||||||
|
<IconButton onClick={onCopyToClipboard(code)} size='small'>
|
||||||
|
<CopyIcon />
|
||||||
|
</IconButton>
|
||||||
|
</CopyToClipboard>
|
||||||
|
</StyledCodeBlock>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const CodeRenderer: CodeComponent = ({ inline = false, children }) => {
|
||||||
|
if (!inline && typeof children?.[0] === 'string') {
|
||||||
|
return <CopyBlock code={children[0]} title='Copy code' />;
|
||||||
|
}
|
||||||
|
|
||||||
|
return <code>{children}</code>;
|
||||||
|
};
|
@ -1,113 +1,21 @@
|
|||||||
import type { FC } from 'react';
|
import type { FC } from 'react';
|
||||||
import { Box, IconButton, styled, Tooltip, Typography } from '@mui/material';
|
import { Box, styled, Typography } from '@mui/material';
|
||||||
import { SectionHeader, StepperBox } from './SharedComponents';
|
import { SectionHeader, StepperBox } from './SharedComponents';
|
||||||
import useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig';
|
import useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig';
|
||||||
import type { SdkName, Sdk } from './sharedTypes';
|
import type { Sdk } from './sharedTypes';
|
||||||
import copy from 'copy-to-clipboard';
|
|
||||||
import useToast from 'hooks/useToast';
|
|
||||||
import CopyIcon from '@mui/icons-material/FileCopy';
|
|
||||||
import { Stepper } from './Stepper';
|
import { Stepper } from './Stepper';
|
||||||
import { Badge } from '../common/Badge/Badge';
|
import { Badge } from '../common/Badge/Badge';
|
||||||
import { Markdown } from 'component/common/Markdown/Markdown';
|
import { Markdown } from 'component/common/Markdown/Markdown';
|
||||||
import type { CodeComponent } from 'react-markdown/lib/ast-to-react';
|
import { CodeRenderer, codeRenderSnippets } from './CodeRenderer';
|
||||||
import android from './snippets/android.md?raw';
|
|
||||||
import go from './snippets/go.md?raw';
|
|
||||||
import javascript from './snippets/javascript.md?raw';
|
|
||||||
import nodejs from './snippets/nodejs.md?raw';
|
|
||||||
import python from './snippets/python.md?raw';
|
|
||||||
import ruby from './snippets/ruby.md?raw';
|
|
||||||
import svelte from './snippets/svelte.md?raw';
|
|
||||||
import vue from './snippets/vue.md?raw';
|
|
||||||
import flutter from './snippets/flutter.md?raw';
|
|
||||||
import java from './snippets/java.md?raw';
|
|
||||||
import dotnet from './snippets/dotnet.md?raw';
|
|
||||||
import php from './snippets/php.md?raw';
|
|
||||||
import react from './snippets/react.md?raw';
|
|
||||||
import rust from './snippets/rust.md?raw';
|
|
||||||
import swift from './snippets/swift.md?raw';
|
|
||||||
|
|
||||||
const snippets: Record<SdkName, string> = {
|
|
||||||
Android: android,
|
|
||||||
Go: go,
|
|
||||||
JavaScript: javascript,
|
|
||||||
'Node.js': nodejs,
|
|
||||||
Python: python,
|
|
||||||
Ruby: ruby,
|
|
||||||
Svelte: svelte,
|
|
||||||
Vue: vue,
|
|
||||||
Flutter: flutter,
|
|
||||||
Java: java,
|
|
||||||
'.NET': dotnet,
|
|
||||||
PHP: php,
|
|
||||||
React: react,
|
|
||||||
Rust: rust,
|
|
||||||
Swift: swift,
|
|
||||||
};
|
|
||||||
|
|
||||||
const SpacedContainer = styled('div')(({ theme }) => ({
|
const SpacedContainer = styled('div')(({ theme }) => ({
|
||||||
padding: theme.spacing(5, 8, 2, 8),
|
padding: theme.spacing(5, 8, 2, 8),
|
||||||
display: 'flex',
|
display: 'flex',
|
||||||
flexDirection: 'column',
|
flexDirection: 'column',
|
||||||
gap: theme.spacing(3),
|
gap: theme.spacing(3),
|
||||||
}));
|
|
||||||
|
|
||||||
const StyledCodeBlock = styled('pre')(({ theme }) => ({
|
|
||||||
backgroundColor: theme.palette.background.elevation1,
|
|
||||||
padding: theme.spacing(2),
|
|
||||||
borderRadius: theme.shape.borderRadius,
|
|
||||||
overflow: 'auto',
|
|
||||||
fontSize: theme.typography.body2.fontSize,
|
fontSize: theme.typography.body2.fontSize,
|
||||||
wordBreak: 'break-all',
|
|
||||||
whiteSpace: 'pre-wrap',
|
|
||||||
position: 'relative',
|
|
||||||
maxHeight: theme.spacing(34),
|
|
||||||
}));
|
}));
|
||||||
|
|
||||||
const CopyToClipboard = styled(Tooltip)(({ theme }) => ({
|
|
||||||
position: 'absolute',
|
|
||||||
top: theme.spacing(1),
|
|
||||||
right: theme.spacing(1),
|
|
||||||
}));
|
|
||||||
|
|
||||||
const CopyBlock: FC<{ title: string; code: string }> = ({ title, code }) => {
|
|
||||||
const onCopyToClipboard = (data: string) => () => {
|
|
||||||
copy(data);
|
|
||||||
setToastData({
|
|
||||||
type: 'success',
|
|
||||||
title: 'Copied to clipboard',
|
|
||||||
});
|
|
||||||
};
|
|
||||||
const { setToastData } = useToast();
|
|
||||||
|
|
||||||
return (
|
|
||||||
<StyledCodeBlock>
|
|
||||||
{code}
|
|
||||||
<CopyToClipboard title={title} arrow>
|
|
||||||
<IconButton onClick={onCopyToClipboard(code)} size='small'>
|
|
||||||
<CopyIcon />
|
|
||||||
</IconButton>
|
|
||||||
</CopyToClipboard>
|
|
||||||
</StyledCodeBlock>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
const ChangeSdk = styled('div')(({ theme }) => ({
|
|
||||||
display: 'inline-flex',
|
|
||||||
gap: theme.spacing(3),
|
|
||||||
padding: theme.spacing(1, 2),
|
|
||||||
border: `1px solid ${theme.palette.divider}`,
|
|
||||||
borderRadius: theme.shape.borderRadius,
|
|
||||||
marginBottom: theme.spacing(3),
|
|
||||||
}));
|
|
||||||
|
|
||||||
const CodeRenderer: CodeComponent = ({ inline = false, children }) => {
|
|
||||||
if (!inline && typeof children?.[0] === 'string') {
|
|
||||||
return <CopyBlock code={children[0]} title='Copy code' />;
|
|
||||||
}
|
|
||||||
|
|
||||||
return <code>{children}</code>;
|
|
||||||
};
|
|
||||||
|
|
||||||
interface ISdkConnectedProps {
|
interface ISdkConnectedProps {
|
||||||
sdk: Sdk;
|
sdk: Sdk;
|
||||||
}
|
}
|
||||||
@ -119,11 +27,14 @@ export const SdkConnected: FC<ISdkConnectedProps> = ({ sdk }) => {
|
|||||||
const frontendApiUrl = `${uiConfig.unleashUrl}/api/frontend/`;
|
const frontendApiUrl = `${uiConfig.unleashUrl}/api/frontend/`;
|
||||||
const apiUrl = sdk.type === 'client' ? clientApiUrl : frontendApiUrl;
|
const apiUrl = sdk.type === 'client' ? clientApiUrl : frontendApiUrl;
|
||||||
|
|
||||||
const snippet = (snippets[sdk.name] || '').replace(
|
const snippet = (codeRenderSnippets[sdk.name] || '').replaceAll(
|
||||||
'<YOUR_API_URL>',
|
'<YOUR_API_URL>',
|
||||||
apiUrl,
|
apiUrl,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const [_connectSnippet, productionSnippet, otherResourcesSnippet] =
|
||||||
|
snippet.split('---\n');
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<SpacedContainer>
|
<SpacedContainer>
|
||||||
<Typography variant='h2'>Connect an SDK to Unleash</Typography>
|
<Typography variant='h2'>Connect an SDK to Unleash</Typography>
|
||||||
@ -139,7 +50,17 @@ export const SdkConnected: FC<ISdkConnectedProps> = ({ sdk }) => {
|
|||||||
following default settings.
|
following default settings.
|
||||||
</Typography>
|
</Typography>
|
||||||
<Markdown components={{ code: CodeRenderer }}>
|
<Markdown components={{ code: CodeRenderer }}>
|
||||||
{snippet}
|
{productionSnippet}
|
||||||
|
</Markdown>
|
||||||
|
</Box>
|
||||||
|
<Box>
|
||||||
|
<SectionHeader>Additional resources</SectionHeader>
|
||||||
|
<Typography variant='body2'>
|
||||||
|
Now that we’ve validated the connection, you might want to
|
||||||
|
look into more advanced use cases and examples:
|
||||||
|
</Typography>
|
||||||
|
<Markdown components={{ code: CodeRenderer }}>
|
||||||
|
{otherResourcesSnippet}
|
||||||
</Markdown>
|
</Markdown>
|
||||||
</Box>
|
</Box>
|
||||||
</SpacedContainer>
|
</SpacedContainer>
|
||||||
|
@ -1,57 +1,13 @@
|
|||||||
import type { FC } from 'react';
|
import type { FC } from 'react';
|
||||||
import {
|
import { Avatar, Box, Link, styled, Typography } from '@mui/material';
|
||||||
Avatar,
|
|
||||||
Box,
|
|
||||||
IconButton,
|
|
||||||
Link,
|
|
||||||
styled,
|
|
||||||
Tooltip,
|
|
||||||
Typography,
|
|
||||||
} from '@mui/material';
|
|
||||||
import { SectionHeader, StepperBox } from './SharedComponents';
|
import { SectionHeader, StepperBox } from './SharedComponents';
|
||||||
import useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig';
|
import useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig';
|
||||||
import { allSdks, type SdkName, type Sdk } from './sharedTypes';
|
import { allSdks, type Sdk } from './sharedTypes';
|
||||||
import copy from 'copy-to-clipboard';
|
|
||||||
import useToast from 'hooks/useToast';
|
|
||||||
import CopyIcon from '@mui/icons-material/FileCopy';
|
|
||||||
import { formatAssetPath } from '../../utils/formatPath';
|
import { formatAssetPath } from '../../utils/formatPath';
|
||||||
import { Stepper } from './Stepper';
|
import { Stepper } from './Stepper';
|
||||||
import { Badge } from '../common/Badge/Badge';
|
import { Badge } from '../common/Badge/Badge';
|
||||||
import { Markdown } from 'component/common/Markdown/Markdown';
|
import { Markdown } from 'component/common/Markdown/Markdown';
|
||||||
import type { CodeComponent } from 'react-markdown/lib/ast-to-react';
|
import { CodeRenderer, codeRenderSnippets } from './CodeRenderer';
|
||||||
import android from './snippets/android.md?raw';
|
|
||||||
import go from './snippets/go.md?raw';
|
|
||||||
import javascript from './snippets/javascript.md?raw';
|
|
||||||
import nodejs from './snippets/nodejs.md?raw';
|
|
||||||
import python from './snippets/python.md?raw';
|
|
||||||
import ruby from './snippets/ruby.md?raw';
|
|
||||||
import svelte from './snippets/svelte.md?raw';
|
|
||||||
import vue from './snippets/vue.md?raw';
|
|
||||||
import flutter from './snippets/flutter.md?raw';
|
|
||||||
import java from './snippets/java.md?raw';
|
|
||||||
import dotnet from './snippets/dotnet.md?raw';
|
|
||||||
import php from './snippets/php.md?raw';
|
|
||||||
import react from './snippets/react.md?raw';
|
|
||||||
import rust from './snippets/rust.md?raw';
|
|
||||||
import swift from './snippets/swift.md?raw';
|
|
||||||
|
|
||||||
const snippets: Record<SdkName, string> = {
|
|
||||||
Android: android,
|
|
||||||
Go: go,
|
|
||||||
JavaScript: javascript,
|
|
||||||
'Node.js': nodejs,
|
|
||||||
Python: python,
|
|
||||||
Ruby: ruby,
|
|
||||||
Svelte: svelte,
|
|
||||||
Vue: vue,
|
|
||||||
Flutter: flutter,
|
|
||||||
Java: java,
|
|
||||||
'.NET': dotnet,
|
|
||||||
PHP: php,
|
|
||||||
React: react,
|
|
||||||
Rust: rust,
|
|
||||||
Swift: swift,
|
|
||||||
};
|
|
||||||
|
|
||||||
const SpacedContainer = styled('div')(({ theme }) => ({
|
const SpacedContainer = styled('div')(({ theme }) => ({
|
||||||
padding: theme.spacing(5, 8, 2, 8),
|
padding: theme.spacing(5, 8, 2, 8),
|
||||||
@ -60,46 +16,6 @@ const SpacedContainer = styled('div')(({ theme }) => ({
|
|||||||
gap: theme.spacing(3),
|
gap: theme.spacing(3),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
const StyledCodeBlock = styled('pre')(({ theme }) => ({
|
|
||||||
backgroundColor: theme.palette.background.elevation1,
|
|
||||||
padding: theme.spacing(2),
|
|
||||||
borderRadius: theme.shape.borderRadius,
|
|
||||||
overflow: 'auto',
|
|
||||||
fontSize: theme.typography.body2.fontSize,
|
|
||||||
wordBreak: 'break-all',
|
|
||||||
whiteSpace: 'pre-wrap',
|
|
||||||
position: 'relative',
|
|
||||||
maxHeight: theme.spacing(34),
|
|
||||||
}));
|
|
||||||
|
|
||||||
const CopyToClipboard = styled(Tooltip)(({ theme }) => ({
|
|
||||||
position: 'absolute',
|
|
||||||
top: theme.spacing(1),
|
|
||||||
right: theme.spacing(1),
|
|
||||||
}));
|
|
||||||
|
|
||||||
const CopyBlock: FC<{ title: string; code: string }> = ({ title, code }) => {
|
|
||||||
const onCopyToClipboard = (data: string) => () => {
|
|
||||||
copy(data);
|
|
||||||
setToastData({
|
|
||||||
type: 'success',
|
|
||||||
title: 'Copied to clipboard',
|
|
||||||
});
|
|
||||||
};
|
|
||||||
const { setToastData } = useToast();
|
|
||||||
|
|
||||||
return (
|
|
||||||
<StyledCodeBlock>
|
|
||||||
{code}
|
|
||||||
<CopyToClipboard title={title} arrow>
|
|
||||||
<IconButton onClick={onCopyToClipboard(code)} size='small'>
|
|
||||||
<CopyIcon />
|
|
||||||
</IconButton>
|
|
||||||
</CopyToClipboard>
|
|
||||||
</StyledCodeBlock>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
const ChangeSdk = styled('div')(({ theme }) => ({
|
const ChangeSdk = styled('div')(({ theme }) => ({
|
||||||
display: 'inline-flex',
|
display: 'inline-flex',
|
||||||
gap: theme.spacing(3),
|
gap: theme.spacing(3),
|
||||||
@ -109,14 +25,6 @@ const ChangeSdk = styled('div')(({ theme }) => ({
|
|||||||
marginBottom: theme.spacing(3),
|
marginBottom: theme.spacing(3),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
const CodeRenderer: CodeComponent = ({ inline = false, children }) => {
|
|
||||||
if (!inline && typeof children?.[0] === 'string') {
|
|
||||||
return <CopyBlock code={children[0]} title='Copy code' />;
|
|
||||||
}
|
|
||||||
|
|
||||||
return <code>{children}</code>;
|
|
||||||
};
|
|
||||||
|
|
||||||
interface ITestSdkConnectionProps {
|
interface ITestSdkConnectionProps {
|
||||||
sdk: Sdk;
|
sdk: Sdk;
|
||||||
apiKey: string;
|
apiKey: string;
|
||||||
@ -137,7 +45,7 @@ export const TestSdkConnection: FC<ITestSdkConnectionProps> = ({
|
|||||||
const frontendApiUrl = `${uiConfig.unleashUrl}/api/frontend/`;
|
const frontendApiUrl = `${uiConfig.unleashUrl}/api/frontend/`;
|
||||||
const apiUrl = sdk.type === 'client' ? clientApiUrl : frontendApiUrl;
|
const apiUrl = sdk.type === 'client' ? clientApiUrl : frontendApiUrl;
|
||||||
|
|
||||||
const snippet = (snippets[sdk.name] || '')
|
const snippet = (codeRenderSnippets[sdk.name] || '')
|
||||||
.replace('<YOUR_API_TOKEN>', apiKey)
|
.replace('<YOUR_API_TOKEN>', apiKey)
|
||||||
.replace('<YOUR_API_URL>', apiUrl)
|
.replace('<YOUR_API_URL>', apiUrl)
|
||||||
.replaceAll('<YOUR_FLAG>', feature);
|
.replaceAll('<YOUR_FLAG>', feature);
|
||||||
|
@ -24,15 +24,13 @@ setInterval(() => {
|
|||||||
|
|
||||||
---
|
---
|
||||||
```js
|
```js
|
||||||
const { UnleashClient } = require('unleash-proxy-client');
|
const { initialize } = require('unleash-client');
|
||||||
|
|
||||||
const unleash = new UnleashClient({
|
const unleash = initialize({
|
||||||
url: '<YOUR_API_URL>',
|
url: '<YOUR_API_URL>',
|
||||||
appName: 'unleash-onboarding-node',
|
appName: 'unleash-onboarding-node',
|
||||||
customHeaders: { Authorization: process.env.UNLEASH_API_KEY },
|
customHeaders: { Authorization: process.env.UNLEASH_API_KEY },
|
||||||
});
|
});
|
||||||
|
|
||||||
unleash.start();
|
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
Loading…
Reference in New Issue
Block a user