1
0
mirror of https://github.com/Unleash/unleash.git synced 2025-01-25 00:07:47 +01:00

add info box in project page + make api ui responsive

This commit is contained in:
Youssef Khedher 2021-10-07 11:44:46 +01:00
parent ddf7715d01
commit 02c17571de
4 changed files with 104 additions and 62 deletions

View File

@ -12,16 +12,33 @@ export const useStyles = makeStyles(theme => ({
maxWidth: '400px',
marginBottom: '1rem',
},
cardLink: {
color: 'inherit',
textDecoration: 'none',
border: 'none',
padding: '0',
background: 'transparent',
fontFamily: theme.typography.fontFamily,
pointer: 'cursor',
},
center: {
textAlign: 'center'
},
actionsContainer: {
textAlign: 'center',
display: 'flex-inline',
flexWrap: 'nowrap'
},
hideSM:{
[theme.breakpoints.down('sm')]: {
display: 'none'
}
},
hideMD:{
[theme.breakpoints.down('md')]: {
display: 'none'
}
},
hideXS:{
[theme.breakpoints.down('xs')]: {
display: 'none'
}
},
token:{
textAlign: 'left',
[theme.breakpoints.up('sm')]: {
display: 'none'
}
}
}));

View File

@ -1,6 +1,6 @@
import { useContext, useState } from 'react';
import { Link } from 'react-router-dom';
import { Button, IconButton, Table, TableBody, TableCell, TableHead, TableRow } from '@material-ui/core';
import { Button, IconButton, Table, TableBody, TableCell, TableHead, TableRow, } from '@material-ui/core';
import AccessContext from '../../../contexts/AccessContext';
import useToast from '../../../hooks/useToast';
import useLoading from '../../../hooks/useLoading';
@ -15,7 +15,7 @@ import { CREATE_API_TOKEN, DELETE_API_TOKEN } from '../../AccessProvider/permiss
import { useStyles } from './ApiTokenList.styles';
import { formatDateWithLocale } from '../../common/util';
import Secret from './secret';
import { Delete } from '@material-ui/icons';
import { Delete, FileCopy } from '@material-ui/icons';
import ApiTokenCreate from '../ApiTokenCreate/ApiTokenCreate';
import Dialogue from '../../common/Dialogue';
@ -73,6 +73,14 @@ const ApiTokenList = ({ location }: IApiTokenList) => {
text: 'Successfully created API token.',
});
}
const copyToken = (value: string) => {
navigator.clipboard.writeText(value);
setToastData({
type: 'success',
show: true,
text: `Token is copied to clipboard`,
});
};
const onDeleteToken = async () => {
if(delToken) {
@ -101,65 +109,81 @@ const ApiTokenList = ({ location }: IApiTokenList) => {
<Table size="small">
<TableHead>
<TableRow>
<TableCell>Created</TableCell>
<TableCell>Username</TableCell>
<TableCell className={styles.center}>Type</TableCell>
<TableCell className={styles.hideSM}>Created</TableCell>
<TableCell className={styles.hideSM}>hideSM</TableCell>
<TableCell className={`${styles.center} ${styles.hideXS}`}>Type</TableCell>
<ConditionallyRender condition={uiConfig.flags.E} show={<>
<TableCell className={styles.center}>Project</TableCell>
<TableCell className={styles.center}>Environment</TableCell>
<TableCell className={`${styles.center} ${styles.hideXS}`}>Project</TableCell>
<TableCell className={`${styles.center} ${styles.hideXS}`}>Environment</TableCell>
</>} />
<TableCell>Secret</TableCell>
<TableCell align="right">Action</TableCell>
<TableCell className={styles.hideMD}>Secret</TableCell>
<TableCell className={styles.token}>Token</TableCell>
<TableCell className={styles.actionsContainer}>Actions</TableCell>
</TableRow>
</TableHead>
<TableBody>
{tokens.map(item => {
return (
<TableRow key={item.secret}>
<TableCell align="left">
<TableCell align="left" className={styles.hideSM}>
{formatDateWithLocale(
item.createdAt,
location.locale
)}
</TableCell>
<TableCell align="left">
<TableCell align="left" className={styles.hideSM}>
{item.username}
</TableCell>
<TableCell className={styles.center}>
<TableCell className={`${styles.center} ${styles.hideXS}`}>
{item.type}
</TableCell>
<ConditionallyRender condition={uiConfig.flags.E} show={<>
<TableCell className={styles.center}>
<TableCell className={`${styles.center} ${styles.hideXS}`}>
{renderProject(item.project)}
</TableCell>
<TableCell className={styles.center}>
<TableCell className={`${styles.center} ${styles.hideXS}`}>
{item.environment}
</TableCell>
<TableCell className={styles.token}>
<b>Type:</b> {item.type}<br/>
<b>Env:</b> {item.environment}<br/>
<b>Project:</b> {renderProject(item.project)}
</TableCell>
</>} />
<TableCell>
<TableCell className={styles.hideMD}>
<Secret value={item.secret} />
</TableCell>
<ConditionallyRender
condition={hasAccess(DELETE_API_TOKEN)}
show={<TableCell
width="20"
style={{ textAlign: 'right' }}
>
<IconButton
onClick={() => {
setDeleteToken(item);
setShowDelete(true);
} }
<TableCell
className={styles.actionsContainer}
>
<IconButton
onClick={() => {
copyToken(item.secret)
} }
>
<Delete />
</IconButton>
</TableCell>} />
<FileCopy />
</IconButton>
<ConditionallyRender
condition={hasAccess(DELETE_API_TOKEN)}
show={
<IconButton
onClick={() => {
setDeleteToken(item);
setShowDelete(true);
} }
>
<Delete />
</IconButton>
} />
</TableCell>
</TableRow>
);
})}
</TableBody>
</Table>)
</Table>
)
}
return (

View File

@ -1,29 +1,9 @@
import React, { useState } from 'react';
import PropTypes from 'prop-types';
import { IconButton } from '@material-ui/core';
import { Visibility } from '@material-ui/icons';
function Secret({ value }) {
const [show, setShow] = useState(false);
const toggle = evt => {
evt.preventDefault();
setShow(!show);
};
return (
<div>
{show ? (
<input readOnly value={value} style={{ width: '250px' }} />
) : (
<span style={{ width: '250px', display: 'inline-block' }}>************************************</span>
)}
<IconButton
aria-label="Show token"
onClick={toggle}
title="Show token"
>
<Visibility style={{ marginLeft: '5px', fontSize: '1.2em' }} />
</IconButton>
<span style={{ width: '250px', display: 'inline-block' }}>************************************</span>
</div>
);
}

View File

@ -16,6 +16,9 @@ import useProject from '../../../hooks/api/getters/useProject/useProject';
import { FormControlLabel, FormGroup, Switch } from '@material-ui/core';
import useProjectApi from '../../../hooks/api/actions/useProjectApi/useProjectApi';
import EnvironmentDisableConfirm from './EnvironmentDisableConfirm/EnvironmentDisableConfirm';
import { Link } from 'react-router-dom';
import { Alert } from '@material-ui/lab';
export interface ProjectEnvironment {
name: string;
@ -42,6 +45,7 @@ const ProjectEnvironmentList = ({projectId}: ProjectEnvironmentListProps) => {
const ref = useLoading(loading);
const styles = useStyles();
const refetch = () => {
refetchEnvs();
refetchProject();
@ -132,9 +136,26 @@ const ProjectEnvironmentList = ({projectId}: ProjectEnvironmentListProps) => {
headerContent={
<HeaderTitle
title={`Configure environments for "${project?.name}"`}
/>
}
/>}
>
<Alert severity="info">
<b>Important!</b> In order for your application to ONLY retrieve feature toggle activation strategies for a specific environment, the application<br/> must use an environment-specific API key. You can look up the environment-specific API keys {' '}
<Link
to='/admin/api'
>
here.
</Link>{' '}
<br/>
<br/>
Your administrator can configure an environment-specific API key and add it to your SDK if you can't find it on the list.
If you are an administrator you can create a new API key {' '}
<Link
to='/admin/api'
>
here.
</Link>{' '}
</Alert>
<br/>
<ConditionallyRender condition={error} show={renderError()} />
<div className={styles.container}>
<ConditionallyRender