mirror of
				https://github.com/Unleash/unleash.git
				synced 2025-10-27 11:02:16 +01: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:
		
							parent
							
								
									98376d73d3
								
							
						
					
					
						commit
						1335e02648
					
				@ -9,15 +9,15 @@ export const ApiTokenDocs = () => {
 | 
			
		||||
            <p>
 | 
			
		||||
                Read the{' '}
 | 
			
		||||
                <a
 | 
			
		||||
                    href="https://docs.getunleash.io/docs"
 | 
			
		||||
                    href="https://docs.getunleash.io/sdks"
 | 
			
		||||
                    target="_blank"
 | 
			
		||||
                    rel="noreferrer"
 | 
			
		||||
                >
 | 
			
		||||
                    Getting started guide
 | 
			
		||||
                    SDK overview
 | 
			
		||||
                </a>{' '}
 | 
			
		||||
                to learn how to connect to the Unleash API from your application
 | 
			
		||||
                or programmatically. Please note it can take up to 1 minute
 | 
			
		||||
                before a new API key is activated.
 | 
			
		||||
                to connect Unleash to your application. Please note it can take
 | 
			
		||||
                up to <strong>1 minute</strong> before a new API key is
 | 
			
		||||
                activated.
 | 
			
		||||
            </p>
 | 
			
		||||
            <br />
 | 
			
		||||
            <strong>API URL: </strong>{' '}
 | 
			
		||||
 | 
			
		||||
@ -17,6 +17,15 @@ export const useStyles = makeStyles()(theme => ({
 | 
			
		||||
            minWidth: '379px',
 | 
			
		||||
        },
 | 
			
		||||
    },
 | 
			
		||||
    radioGroup: {
 | 
			
		||||
        marginBottom: theme.spacing(2),
 | 
			
		||||
    },
 | 
			
		||||
    radioItem: {
 | 
			
		||||
        marginBottom: theme.spacing(1),
 | 
			
		||||
    },
 | 
			
		||||
    radio: {
 | 
			
		||||
        marginLeft: theme.spacing(1.5),
 | 
			
		||||
    },
 | 
			
		||||
    label: {
 | 
			
		||||
        minWidth: '300px',
 | 
			
		||||
        [theme.breakpoints.down(600)]: {
 | 
			
		||||
 | 
			
		||||
@ -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 React from 'react';
 | 
			
		||||
import { useEnvironments } from 'hooks/api/getters/useEnvironments/useEnvironments';
 | 
			
		||||
import useProjects from 'hooks/api/getters/useProjects/useProjects';
 | 
			
		||||
import GeneralSelect from 'component/common/GeneralSelect/GeneralSelect';
 | 
			
		||||
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 { ApiTokenFormErrorType } from 'component/admin/apiToken/ApiTokenForm/useApiTokenForm';
 | 
			
		||||
import { ApiTokenFormErrorType } from './useApiTokenForm';
 | 
			
		||||
import { useStyles } from './ApiTokenForm.styles';
 | 
			
		||||
 | 
			
		||||
interface IApiTokenFormProps {
 | 
			
		||||
    username: string;
 | 
			
		||||
    type: string;
 | 
			
		||||
@ -40,15 +49,32 @@ const ApiTokenForm: React.FC<IApiTokenFormProps> = ({
 | 
			
		||||
    clearErrors,
 | 
			
		||||
}) => {
 | 
			
		||||
    const TYPE_ADMIN = 'ADMIN';
 | 
			
		||||
    const { uiConfig } = useUiConfig();
 | 
			
		||||
    const { classes: styles } = useStyles();
 | 
			
		||||
    const { environments } = useEnvironments();
 | 
			
		||||
    const { projects: availableProjects } = useProjects();
 | 
			
		||||
 | 
			
		||||
    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 => ({
 | 
			
		||||
        value: project.id,
 | 
			
		||||
        label: project.name,
 | 
			
		||||
@ -81,20 +107,38 @@ const ApiTokenForm: React.FC<IApiTokenFormProps> = ({
 | 
			
		||||
                    onFocus={() => clearErrors('username')}
 | 
			
		||||
                    autoFocus
 | 
			
		||||
                />
 | 
			
		||||
                <p className={styles.inputDescription}>
 | 
			
		||||
                    What is your token type?
 | 
			
		||||
                </p>
 | 
			
		||||
                <GeneralSelect
 | 
			
		||||
                    options={selectableTypes}
 | 
			
		||||
                    value={type}
 | 
			
		||||
                    onChange={setTokenType}
 | 
			
		||||
                    label="Token Type"
 | 
			
		||||
                    id="api_key_type"
 | 
			
		||||
                    name="type"
 | 
			
		||||
                    IconComponent={KeyboardArrowDownOutlined}
 | 
			
		||||
                    fullWidth
 | 
			
		||||
                    className={styles.selectInput}
 | 
			
		||||
                />
 | 
			
		||||
                <FormControl className={styles.radioGroup}>
 | 
			
		||||
                    <label id="token-type" className={styles.inputDescription}>
 | 
			
		||||
                        What do you want to connect?
 | 
			
		||||
                    </label>
 | 
			
		||||
                    <RadioGroup
 | 
			
		||||
                        aria-labelledby="token-type"
 | 
			
		||||
                        defaultValue="CLIENT"
 | 
			
		||||
                        name="radio-buttons-group"
 | 
			
		||||
                        value={type}
 | 
			
		||||
                        onChange={(event, value) => setTokenType(value)}
 | 
			
		||||
                    >
 | 
			
		||||
                        {selectableTypes.map(({ key, label, title }) => (
 | 
			
		||||
                            <FormControlLabel
 | 
			
		||||
                                key={key}
 | 
			
		||||
                                value={key}
 | 
			
		||||
                                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}>
 | 
			
		||||
                    Which project do you want to give access to?
 | 
			
		||||
                </p>
 | 
			
		||||
 | 
			
		||||
@ -78,9 +78,14 @@ export const ApiTokenTable = () => {
 | 
			
		||||
                />
 | 
			
		||||
            }
 | 
			
		||||
        >
 | 
			
		||||
            <Box sx={{ mb: 4 }}>
 | 
			
		||||
                <ApiTokenDocs />
 | 
			
		||||
            </Box>
 | 
			
		||||
            <ConditionallyRender
 | 
			
		||||
                condition={rows.length > 0}
 | 
			
		||||
                show={
 | 
			
		||||
                    <Box sx={{ mb: 4 }}>
 | 
			
		||||
                        <ApiTokenDocs />
 | 
			
		||||
                    </Box>
 | 
			
		||||
                }
 | 
			
		||||
            />
 | 
			
		||||
            <Box sx={{ overflowX: 'auto' }}>
 | 
			
		||||
                <SearchHighlightProvider value={globalFilter}>
 | 
			
		||||
                    <Table {...getTableProps()}>
 | 
			
		||||
@ -118,7 +123,17 @@ export const ApiTokenTable = () => {
 | 
			
		||||
                        }
 | 
			
		||||
                        elseShow={
 | 
			
		||||
                            <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>
 | 
			
		||||
                        }
 | 
			
		||||
                    />
 | 
			
		||||
@ -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 = [
 | 
			
		||||
    {
 | 
			
		||||
        id: 'Icon',
 | 
			
		||||
@ -144,10 +174,13 @@ const COLUMNS = [
 | 
			
		||||
    {
 | 
			
		||||
        Header: 'Type',
 | 
			
		||||
        accessor: 'type',
 | 
			
		||||
        Cell: ({ value }: { value: string }) => (
 | 
			
		||||
            <HighlightCell value={value.toUpperCase()} />
 | 
			
		||||
        Cell: ({ value }: { value: 'admin' | 'client' | 'frontend' }) => (
 | 
			
		||||
            <HighlightCell
 | 
			
		||||
                value={tokenDescriptions[value].label}
 | 
			
		||||
                subtitle={tokenDescriptions[value].title}
 | 
			
		||||
            />
 | 
			
		||||
        ),
 | 
			
		||||
        minWidth: 100,
 | 
			
		||||
        minWidth: 280,
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
        Header: 'Project',
 | 
			
		||||
 | 
			
		||||
@ -16,6 +16,7 @@ export interface IUiConfig {
 | 
			
		||||
    toast?: IProclamationToast;
 | 
			
		||||
    segmentValuesLimit?: number;
 | 
			
		||||
    strategySegmentsLimit?: number;
 | 
			
		||||
    embedProxy?: boolean;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface IProclamationToast {
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user