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

Feat: embedded proxy token (#1222)

* initial frontend for embedded proxy token

* update wording on tokens

* embedded proxy feature flag

* update in-app guidance for api tokens

* simplify token form flag
This commit is contained in:
Tymoteusz Czech 2022-08-18 15:41:01 +02:00 committed by GitHub
parent 98376d73d3
commit 1335e02648
5 changed files with 118 additions and 31 deletions

View File

@ -9,15 +9,15 @@ export const ApiTokenDocs = () => {
<p> <p>
Read the{' '} Read the{' '}
<a <a
href="https://docs.getunleash.io/docs" href="https://docs.getunleash.io/sdks"
target="_blank" target="_blank"
rel="noreferrer" rel="noreferrer"
> >
Getting started guide SDK overview
</a>{' '} </a>{' '}
to learn how to connect to the Unleash API from your application to connect Unleash to your application. Please note it can take
or programmatically. Please note it can take up to 1 minute up to <strong>1 minute</strong> before a new API key is
before a new API key is activated. activated.
</p> </p>
<br /> <br />
<strong>API URL: </strong>{' '} <strong>API URL: </strong>{' '}

View File

@ -17,6 +17,15 @@ export const useStyles = makeStyles()(theme => ({
minWidth: '379px', minWidth: '379px',
}, },
}, },
radioGroup: {
marginBottom: theme.spacing(2),
},
radioItem: {
marginBottom: theme.spacing(1),
},
radio: {
marginLeft: theme.spacing(1.5),
},
label: { label: {
minWidth: '300px', minWidth: '300px',
[theme.breakpoints.down(600)]: { [theme.breakpoints.down(600)]: {

View File

@ -1,13 +1,22 @@
import { Button } from '@mui/material'; import {
Button,
FormControl,
FormControlLabel,
Radio,
RadioGroup,
Typography,
} from '@mui/material';
import { KeyboardArrowDownOutlined } from '@mui/icons-material'; import { KeyboardArrowDownOutlined } from '@mui/icons-material';
import React from 'react'; import React from 'react';
import { useEnvironments } from 'hooks/api/getters/useEnvironments/useEnvironments'; import { useEnvironments } from 'hooks/api/getters/useEnvironments/useEnvironments';
import useProjects from 'hooks/api/getters/useProjects/useProjects'; import useProjects from 'hooks/api/getters/useProjects/useProjects';
import GeneralSelect from 'component/common/GeneralSelect/GeneralSelect'; import GeneralSelect from 'component/common/GeneralSelect/GeneralSelect';
import Input from 'component/common/Input/Input'; import Input from 'component/common/Input/Input';
import { useStyles } from './ApiTokenForm.styles'; import useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig';
import { SelectProjectInput } from './SelectProjectInput/SelectProjectInput'; import { SelectProjectInput } from './SelectProjectInput/SelectProjectInput';
import { ApiTokenFormErrorType } from 'component/admin/apiToken/ApiTokenForm/useApiTokenForm'; import { ApiTokenFormErrorType } from './useApiTokenForm';
import { useStyles } from './ApiTokenForm.styles';
interface IApiTokenFormProps { interface IApiTokenFormProps {
username: string; username: string;
type: string; type: string;
@ -40,15 +49,32 @@ const ApiTokenForm: React.FC<IApiTokenFormProps> = ({
clearErrors, clearErrors,
}) => { }) => {
const TYPE_ADMIN = 'ADMIN'; const TYPE_ADMIN = 'ADMIN';
const { uiConfig } = useUiConfig();
const { classes: styles } = useStyles(); const { classes: styles } = useStyles();
const { environments } = useEnvironments(); const { environments } = useEnvironments();
const { projects: availableProjects } = useProjects(); const { projects: availableProjects } = useProjects();
const selectableTypes = [ const selectableTypes = [
{ key: 'CLIENT', label: 'Client', title: 'Client SDK token' }, {
{ key: 'ADMIN', label: 'Admin', title: 'Admin API token' }, key: 'CLIENT',
label: 'Server-side SDK (CLIENT)',
title: 'Connect server-side SDK or Unleash Proxy',
},
{
key: 'ADMIN',
label: 'ADMIN',
title: 'Full access for managing Unleash',
},
]; ];
if (uiConfig.embedProxy) {
selectableTypes.splice(1, 0, {
key: 'FRONTEND',
label: 'Client-side SDK (FRONTEND)',
title: 'Connect web and mobile SDK directly to Unleash',
});
}
const selectableProjects = availableProjects.map(project => ({ const selectableProjects = availableProjects.map(project => ({
value: project.id, value: project.id,
label: project.name, label: project.name,
@ -81,20 +107,38 @@ const ApiTokenForm: React.FC<IApiTokenFormProps> = ({
onFocus={() => clearErrors('username')} onFocus={() => clearErrors('username')}
autoFocus autoFocus
/> />
<p className={styles.inputDescription}> <FormControl className={styles.radioGroup}>
What is your token type? <label id="token-type" className={styles.inputDescription}>
</p> What do you want to connect?
<GeneralSelect </label>
options={selectableTypes} <RadioGroup
aria-labelledby="token-type"
defaultValue="CLIENT"
name="radio-buttons-group"
value={type} value={type}
onChange={setTokenType} onChange={(event, value) => setTokenType(value)}
label="Token Type" >
id="api_key_type" {selectableTypes.map(({ key, label, title }) => (
name="type" <FormControlLabel
IconComponent={KeyboardArrowDownOutlined} key={key}
fullWidth value={key}
className={styles.selectInput} className={styles.radioItem}
control={<Radio className={styles.radio} />}
label={
<>
<Typography>{label}</Typography>
<Typography
variant="body2"
color="text.secondary"
>
{title}
</Typography>
</>
}
/> />
))}
</RadioGroup>
</FormControl>
<p className={styles.inputDescription}> <p className={styles.inputDescription}>
Which project do you want to give access to? Which project do you want to give access to?
</p> </p>

View File

@ -78,9 +78,14 @@ export const ApiTokenTable = () => {
/> />
} }
> >
<ConditionallyRender
condition={rows.length > 0}
show={
<Box sx={{ mb: 4 }}> <Box sx={{ mb: 4 }}>
<ApiTokenDocs /> <ApiTokenDocs />
</Box> </Box>
}
/>
<Box sx={{ overflowX: 'auto' }}> <Box sx={{ overflowX: 'auto' }}>
<SearchHighlightProvider value={globalFilter}> <SearchHighlightProvider value={globalFilter}>
<Table {...getTableProps()}> <Table {...getTableProps()}>
@ -118,7 +123,17 @@ export const ApiTokenTable = () => {
} }
elseShow={ elseShow={
<TablePlaceholder> <TablePlaceholder>
No tokens available. Get started by adding one. <span>
{'No tokens available. Read '}
<a
href="https://docs.getunleash.io/how-to/api"
target="_blank"
rel="noreferrer"
>
API How-to guides
</a>{' '}
{' to learn more.'}
</span>
</TablePlaceholder> </TablePlaceholder>
} }
/> />
@ -128,6 +143,21 @@ export const ApiTokenTable = () => {
); );
}; };
const tokenDescriptions = {
client: {
label: 'CLIENT',
title: 'Connect server-side SDK or Unleash Proxy',
},
frontend: {
label: 'FRONTEND',
title: 'Connect web and mobile SDK',
},
admin: {
label: 'ADMIN',
title: 'Full access for managing Unleash',
},
};
const COLUMNS = [ const COLUMNS = [
{ {
id: 'Icon', id: 'Icon',
@ -144,10 +174,13 @@ const COLUMNS = [
{ {
Header: 'Type', Header: 'Type',
accessor: 'type', accessor: 'type',
Cell: ({ value }: { value: string }) => ( Cell: ({ value }: { value: 'admin' | 'client' | 'frontend' }) => (
<HighlightCell value={value.toUpperCase()} /> <HighlightCell
value={tokenDescriptions[value].label}
subtitle={tokenDescriptions[value].title}
/>
), ),
minWidth: 100, minWidth: 280,
}, },
{ {
Header: 'Project', Header: 'Project',

View File

@ -16,6 +16,7 @@ export interface IUiConfig {
toast?: IProclamationToast; toast?: IProclamationToast;
segmentValuesLimit?: number; segmentValuesLimit?: number;
strategySegmentsLimit?: number; strategySegmentsLimit?: number;
embedProxy?: boolean;
} }
export interface IProclamationToast { export interface IProclamationToast {