mirror of
https://github.com/Unleash/unleash.git
synced 2025-01-20 00:08:02 +01:00
Fix/optimizations (#275)
* chore: update changelog * feat: login mobile view * fix: lists * fix: colors * fix: resolve merge conflict * fix: tests * fix: set defualt location object * fix: don't check password before length exceeds 2 * fix: check length
This commit is contained in:
parent
05334337c2
commit
b9f5585c62
@ -16,7 +16,6 @@ The latest version of this document is always available in
|
||||
|
||||
# 4.0.0-alpha.7
|
||||
- feat: add support for demo sign-in
|
||||
|
||||
# 4.0.0-alpha.5
|
||||
- fix: require ADMIN role to manage users
|
||||
- fix: add permissions for tag-types and project
|
||||
|
@ -9,12 +9,21 @@ import {
|
||||
ListItemText,
|
||||
} from '@material-ui/core';
|
||||
import ConditionallyRender from '../../../common/ConditionallyRender/ConditionallyRender';
|
||||
import { DELETE_ADDON, UPDATE_ADDON } from '../../../AccessProvider/permissions';
|
||||
import {
|
||||
DELETE_ADDON,
|
||||
UPDATE_ADDON,
|
||||
} from '../../../AccessProvider/permissions';
|
||||
import { Link } from 'react-router-dom';
|
||||
import PageContent from '../../../common/PageContent/PageContent';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
const ConfiguredAddons = ({ addons, hasAccess, removeAddon, getIcon, toggleAddon }) => {
|
||||
const ConfiguredAddons = ({
|
||||
addons,
|
||||
hasAccess,
|
||||
removeAddon,
|
||||
getIcon,
|
||||
toggleAddon,
|
||||
}) => {
|
||||
const onRemoveAddon = addon => () => removeAddon(addon);
|
||||
const renderAddon = addon => (
|
||||
<ListItem key={addon.id}>
|
||||
@ -25,7 +34,13 @@ const ConfiguredAddons = ({ addons, hasAccess, removeAddon, getIcon, toggleAddon
|
||||
<ConditionallyRender
|
||||
condition={hasAccess(UPDATE_ADDON)}
|
||||
show={
|
||||
<Link to={`/addons/edit/${addon.id}`}>
|
||||
<Link
|
||||
style={{
|
||||
textDecoration: 'none',
|
||||
color: 'inherit',
|
||||
}}
|
||||
to={`/addons/edit/${addon.id}`}
|
||||
>
|
||||
<strong>{addon.provider}</strong>
|
||||
</Link>
|
||||
}
|
||||
@ -42,17 +57,27 @@ const ConfiguredAddons = ({ addons, hasAccess, removeAddon, getIcon, toggleAddon
|
||||
show={
|
||||
<IconButton
|
||||
size="small"
|
||||
title={addon.enabled ? 'Disable addon' : 'Enable addon'}
|
||||
title={
|
||||
addon.enabled ? 'Disable addon' : 'Enable addon'
|
||||
}
|
||||
onClick={() => toggleAddon(addon)}
|
||||
>
|
||||
<Icon>{addon.enabled ? 'visibility' : 'visibility_off'}</Icon>
|
||||
<Icon>
|
||||
{addon.enabled
|
||||
? 'visibility'
|
||||
: 'visibility_off'}
|
||||
</Icon>
|
||||
</IconButton>
|
||||
}
|
||||
/>
|
||||
<ConditionallyRender
|
||||
condition={hasAccess(DELETE_ADDON)}
|
||||
show={
|
||||
<IconButton size="small" title="Remove addon" onClick={onRemoveAddon(addon)}>
|
||||
<IconButton
|
||||
size="small"
|
||||
title="Remove addon"
|
||||
onClick={onRemoveAddon(addon)}
|
||||
>
|
||||
<Icon>delete</Icon>
|
||||
</IconButton>
|
||||
}
|
||||
|
@ -135,7 +135,6 @@ const FeatureToggleList = ({
|
||||
}
|
||||
/>
|
||||
|
||||
|
||||
<ConditionallyRender
|
||||
condition={smallScreen}
|
||||
show={
|
||||
@ -144,7 +143,12 @@ const FeatureToggleList = ({
|
||||
component={Link}
|
||||
to="/features/create"
|
||||
data-test="add-feature-btn"
|
||||
disabled={!hasAccess(CREATE_FEATURE, currentProjectId)}
|
||||
disabled={
|
||||
!hasAccess(
|
||||
CREATE_FEATURE,
|
||||
currentProjectId
|
||||
)
|
||||
}
|
||||
>
|
||||
<Icon>add</Icon>
|
||||
</IconButton>
|
||||
@ -154,10 +158,15 @@ const FeatureToggleList = ({
|
||||
<Button
|
||||
to="/features/create"
|
||||
data-test="add-feature-btn"
|
||||
color="secondary"
|
||||
color="primary"
|
||||
variant="contained"
|
||||
component={Link}
|
||||
disabled={!hasAccess(CREATE_FEATURE, currentProjectId)}
|
||||
disabled={
|
||||
!hasAccess(
|
||||
CREATE_FEATURE,
|
||||
currentProjectId
|
||||
)
|
||||
}
|
||||
className={classnames({
|
||||
skeleton: loading,
|
||||
})}
|
||||
@ -166,7 +175,6 @@ const FeatureToggleList = ({
|
||||
</Button>
|
||||
}
|
||||
/>
|
||||
|
||||
</div>
|
||||
}
|
||||
/>
|
||||
|
@ -145,7 +145,7 @@ exports[`renders correctly with one feature 1`] = `
|
||||
</div>
|
||||
<a
|
||||
aria-disabled={true}
|
||||
className="MuiButtonBase-root MuiButton-root MuiButton-contained MuiButton-containedSecondary Mui-disabled Mui-disabled"
|
||||
className="MuiButtonBase-root MuiButton-root MuiButton-contained MuiButton-containedPrimary Mui-disabled Mui-disabled"
|
||||
data-test="add-feature-btn"
|
||||
href="/features/create"
|
||||
onBlur={[Function]}
|
||||
@ -351,7 +351,7 @@ exports[`renders correctly with one feature without permissions 1`] = `
|
||||
</div>
|
||||
<a
|
||||
aria-disabled={true}
|
||||
className="MuiButtonBase-root MuiButton-root MuiButton-contained MuiButton-containedSecondary Mui-disabled Mui-disabled"
|
||||
className="MuiButtonBase-root MuiButton-root MuiButton-contained MuiButton-containedPrimary Mui-disabled Mui-disabled"
|
||||
data-test="add-feature-btn"
|
||||
href="/features/create"
|
||||
onBlur={[Function]}
|
||||
|
@ -1,11 +1,11 @@
|
||||
.stale {
|
||||
background-color: var(--danger);
|
||||
background-color: #374952;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.active {
|
||||
background-color: var(--success);
|
||||
color: #000;
|
||||
background-color: #7398ab;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.stale,
|
||||
|
@ -4,8 +4,20 @@ import classnames from 'classnames';
|
||||
import { Link, useHistory } from 'react-router-dom';
|
||||
import useMediaQuery from '@material-ui/core/useMediaQuery';
|
||||
|
||||
import { List, ListItem, ListItemAvatar, IconButton, Icon, ListItemText, Button, Tooltip } from '@material-ui/core';
|
||||
import { CREATE_STRATEGY, DELETE_STRATEGY } from '../../AccessProvider/permissions';
|
||||
import {
|
||||
List,
|
||||
ListItem,
|
||||
ListItemAvatar,
|
||||
IconButton,
|
||||
Icon,
|
||||
ListItemText,
|
||||
Button,
|
||||
Tooltip,
|
||||
} from '@material-ui/core';
|
||||
import {
|
||||
CREATE_STRATEGY,
|
||||
DELETE_STRATEGY,
|
||||
} from '../../AccessProvider/permissions';
|
||||
|
||||
import ConditionallyRender from '../../common/ConditionallyRender/ConditionallyRender';
|
||||
import PageContent from '../../common/PageContent/PageContent';
|
||||
@ -39,13 +51,21 @@ const StrategiesList = ({
|
||||
condition={smallScreen}
|
||||
show={
|
||||
<Tooltip title="Add new strategy">
|
||||
<IconButton onClick={() => history.push('/strategies/create')}>
|
||||
<IconButton
|
||||
onClick={() =>
|
||||
history.push('/strategies/create')
|
||||
}
|
||||
>
|
||||
<Icon>add</Icon>
|
||||
</IconButton>
|
||||
</Tooltip>
|
||||
}
|
||||
elseShow={
|
||||
<Button onClick={() => history.push('/strategies/create')} color="primary" variant="contained">
|
||||
<Button
|
||||
onClick={() => history.push('/strategies/create')}
|
||||
color="primary"
|
||||
variant="contained"
|
||||
>
|
||||
Add new strategy
|
||||
</Button>
|
||||
}
|
||||
@ -57,7 +77,10 @@ const StrategiesList = ({
|
||||
const strategyLink = ({ name, deprecated }) => (
|
||||
<Link to={`/strategies/view/${name}`}>
|
||||
<strong>{name}</strong>
|
||||
<ConditionallyRender condition={deprecated} show={<small> (Deprecated)</small>} />
|
||||
<ConditionallyRender
|
||||
condition={deprecated}
|
||||
show={<small> (Deprecated)</small>}
|
||||
/>
|
||||
</Link>
|
||||
);
|
||||
|
||||
@ -126,20 +149,30 @@ const StrategiesList = ({
|
||||
}}
|
||||
>
|
||||
<ListItemAvatar>
|
||||
<Icon>extension</Icon>
|
||||
<Icon style={{ color: '#0000008a' }}>extension</Icon>
|
||||
</ListItemAvatar>
|
||||
<ListItemText primary={strategyLink(strategy)} secondary={strategy.description} />
|
||||
<ListItemText
|
||||
primary={strategyLink(strategy)}
|
||||
secondary={strategy.description}
|
||||
/>
|
||||
<ConditionallyRender
|
||||
condition={strategy.deprecated}
|
||||
show={reactivateButton(strategy)}
|
||||
elseShow={deprecateButton(strategy)}
|
||||
/>
|
||||
<ConditionallyRender condition={hasAccess(DELETE_STRATEGY)} show={deleteButton(strategy)} />
|
||||
<ConditionallyRender
|
||||
condition={hasAccess(DELETE_STRATEGY)}
|
||||
show={deleteButton(strategy)}
|
||||
/>
|
||||
</ListItem>
|
||||
));
|
||||
|
||||
return (
|
||||
<PageContent headerContent={<HeaderTitle title="Strategies" actions={headerButton()} />}>
|
||||
<PageContent
|
||||
headerContent={
|
||||
<HeaderTitle title="Strategies" actions={headerButton()} />
|
||||
}
|
||||
>
|
||||
<List>
|
||||
<ConditionallyRender
|
||||
condition={strategies.length > 0}
|
||||
|
@ -3,6 +3,10 @@ import { makeStyles } from '@material-ui/styles';
|
||||
export const useStyles = makeStyles(theme => ({
|
||||
listItem: {
|
||||
padding: '0',
|
||||
['& a']: {
|
||||
textDecoration: 'none',
|
||||
color: 'inherit',
|
||||
},
|
||||
},
|
||||
deprecated: {
|
||||
'& a': {
|
||||
|
@ -40,6 +40,11 @@ exports[`renders correctly with one strategy 1`] = `
|
||||
<span
|
||||
aria-hidden={true}
|
||||
className="material-icons MuiIcon-root"
|
||||
style={
|
||||
Object {
|
||||
"color": "#0000008a",
|
||||
}
|
||||
}
|
||||
>
|
||||
extension
|
||||
</span>
|
||||
@ -183,6 +188,11 @@ exports[`renders correctly with one strategy without permissions 1`] = `
|
||||
<span
|
||||
aria-hidden={true}
|
||||
className="material-icons MuiIcon-root"
|
||||
style={
|
||||
Object {
|
||||
"color": "#0000008a",
|
||||
}
|
||||
}
|
||||
>
|
||||
extension
|
||||
</span>
|
||||
|
@ -31,6 +31,11 @@
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.tagListItem * > a {
|
||||
text-decoration: none;
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
.tagTypeContainer {
|
||||
max-width: 350px;
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { makeStyles } from '@material-ui/styles';
|
||||
import { makeStyles } from '@material-ui/core/styles';
|
||||
|
||||
export const useStyles = makeStyles(theme => ({
|
||||
container: {
|
||||
@ -25,5 +25,8 @@ export const useStyles = makeStyles(theme => ({
|
||||
},
|
||||
emailField: {
|
||||
minWidth: '300px',
|
||||
[theme.breakpoints.down('xs')]: {
|
||||
minWidth: '100%',
|
||||
},
|
||||
},
|
||||
}));
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { makeStyles } from '@material-ui/styles';
|
||||
import { makeStyles } from '@material-ui/core/styles';
|
||||
|
||||
export const useStyles = makeStyles(theme => ({
|
||||
title: {
|
||||
@ -11,12 +11,21 @@ export const useStyles = makeStyles(theme => ({
|
||||
padding: '4rem 2rem',
|
||||
color: '#fff',
|
||||
position: 'relative',
|
||||
[theme.breakpoints.down('sm')]: {
|
||||
padding: '3rem 2rem',
|
||||
},
|
||||
[theme.breakpoints.down('xs')]: {
|
||||
padding: '3rem 1rem',
|
||||
},
|
||||
},
|
||||
switchesContainer: {
|
||||
position: 'fixed',
|
||||
bottom: '40px',
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
[theme.breakpoints.down('sm')]: {
|
||||
display: 'none',
|
||||
},
|
||||
},
|
||||
switchIcon: {
|
||||
height: '180px',
|
||||
@ -25,25 +34,40 @@ export const useStyles = makeStyles(theme => ({
|
||||
position: 'absolute',
|
||||
bottom: '-54px',
|
||||
left: '100px',
|
||||
[theme.breakpoints.down('sm')]: {
|
||||
display: 'none',
|
||||
},
|
||||
},
|
||||
bottomRightStar: {
|
||||
position: 'absolute',
|
||||
bottom: '-100px',
|
||||
left: '200px',
|
||||
[theme.breakpoints.down('sm')]: {
|
||||
display: 'none',
|
||||
},
|
||||
},
|
||||
midRightStar: {
|
||||
position: 'absolute',
|
||||
bottom: '-80px',
|
||||
left: '300px',
|
||||
[theme.breakpoints.down('sm')]: {
|
||||
display: 'none',
|
||||
},
|
||||
},
|
||||
midLeftStar: {
|
||||
position: 'absolute',
|
||||
top: '10px',
|
||||
left: '150px',
|
||||
[theme.breakpoints.down('sm')]: {
|
||||
display: 'none',
|
||||
},
|
||||
},
|
||||
midLeftStarTwo: {
|
||||
position: 'absolute',
|
||||
top: '25px',
|
||||
left: '350px',
|
||||
[theme.breakpoints.down('sm')]: {
|
||||
display: 'none',
|
||||
},
|
||||
},
|
||||
}));
|
||||
|
@ -11,6 +11,9 @@ export const useStyles = makeStyles(theme => ({
|
||||
width: '100%',
|
||||
},
|
||||
},
|
||||
editProfileTitle: {
|
||||
fontWeight: 'bold',
|
||||
},
|
||||
button: {
|
||||
width: '150px',
|
||||
marginTop: '1.15rem',
|
||||
|
@ -86,7 +86,7 @@ const EditProfile = ({
|
||||
<div className={styles.container} ref={ref}>
|
||||
<Typography
|
||||
variant="body1"
|
||||
style={{ fontWeight: 'bold' }}
|
||||
className={styles.editProfileTitle}
|
||||
data-loading
|
||||
>
|
||||
Update password
|
||||
|
@ -47,6 +47,7 @@ const PasswordChecker = ({ password, callback }: IPasswordCheckerProps) => {
|
||||
}, [password]);
|
||||
|
||||
const checkPassword = useCallback(async () => {
|
||||
if (password.length < 3) return;
|
||||
try {
|
||||
const res = await makeValidatePassReq();
|
||||
if (res.status === BAD_REQUEST) {
|
||||
@ -63,7 +64,7 @@ const PasswordChecker = ({ password, callback }: IPasswordCheckerProps) => {
|
||||
// ResetPasswordForm handles errors related to submitting the form.
|
||||
console.log(e);
|
||||
}
|
||||
}, [makeValidatePassReq, callback]);
|
||||
}, [makeValidatePassReq, callback, password]);
|
||||
|
||||
useEffect(() => {
|
||||
checkPassword();
|
||||
|
@ -1,11 +1,36 @@
|
||||
import { makeStyles } from '@material-ui/styles';
|
||||
import { makeStyles } from '@material-ui/core/styles';
|
||||
|
||||
export const useStyles = makeStyles(theme => ({
|
||||
container: {
|
||||
display: 'flex',
|
||||
[theme.breakpoints.down('sm')]: {
|
||||
flexDirection: 'column',
|
||||
},
|
||||
overflow: 'hidden',
|
||||
},
|
||||
leftContainer: {
|
||||
width: '40%',
|
||||
minHeight: '100vh',
|
||||
[theme.breakpoints.down('sm')]: {
|
||||
width: '100%',
|
||||
minHeight: 'auto',
|
||||
},
|
||||
},
|
||||
bannerSubtitle: {
|
||||
[theme.breakpoints.down('sm')]: {
|
||||
maxWidth: '300px',
|
||||
},
|
||||
},
|
||||
rightContainer: {
|
||||
width: '60%',
|
||||
minHeight: '100vh',
|
||||
position: 'relative',
|
||||
[theme.breakpoints.down('sm')]: {
|
||||
width: '100%',
|
||||
position: 'static',
|
||||
minHeight: 'auto',
|
||||
},
|
||||
},
|
||||
leftContainer: { width: '40%', minHeight: '100vh' },
|
||||
rightContainer: { width: '60%', minHeight: '100vh', position: 'relative' },
|
||||
menu: {
|
||||
position: 'absolute',
|
||||
right: '20px',
|
||||
@ -14,6 +39,11 @@ export const useStyles = makeStyles(theme => ({
|
||||
textDecoration: 'none',
|
||||
color: '#000',
|
||||
},
|
||||
[theme.breakpoints.down('sm')]: {
|
||||
'& a': {
|
||||
color: '#fff',
|
||||
},
|
||||
},
|
||||
},
|
||||
title: {
|
||||
fontWeight: 'bold',
|
||||
@ -22,5 +52,11 @@ export const useStyles = makeStyles(theme => ({
|
||||
},
|
||||
innerRightContainer: {
|
||||
padding: '4rem 3rem',
|
||||
[theme.breakpoints.down('sm')]: {
|
||||
padding: '2rem 2rem',
|
||||
},
|
||||
[theme.breakpoints.down('xs')]: {
|
||||
padding: '2rem 1rem',
|
||||
},
|
||||
},
|
||||
}));
|
||||
|
@ -5,7 +5,7 @@ import { Typography } from '@material-ui/core';
|
||||
|
||||
import { useStyles } from './StandaloneLayout.styles';
|
||||
import ConditionallyRender from '../../../common/ConditionallyRender';
|
||||
import { Link } from 'react-router-dom';
|
||||
import { Link, useLocation } from 'react-router-dom';
|
||||
|
||||
interface IStandaloneLayout {
|
||||
BannerComponent?: JSX.Element;
|
||||
@ -18,11 +18,12 @@ const StandaloneLayout: FC<IStandaloneLayout> = ({
|
||||
BannerComponent,
|
||||
}) => {
|
||||
const styles = useStyles();
|
||||
const location = useLocation();
|
||||
|
||||
let banner = (
|
||||
<StandaloneBanner title="Unleash">
|
||||
<Typography variant="subtitle1">
|
||||
Committed to creating new ways of developing.
|
||||
<Typography variant="subtitle1" className={styles.bannerSubtitle}>
|
||||
Committed to creating new ways of developing software.
|
||||
</Typography>
|
||||
</StandaloneBanner>
|
||||
);
|
||||
@ -31,12 +32,14 @@ const StandaloneLayout: FC<IStandaloneLayout> = ({
|
||||
banner = BannerComponent;
|
||||
}
|
||||
|
||||
const isLoginpage = location.pathname.includes('login');
|
||||
|
||||
return (
|
||||
<div className={styles.container}>
|
||||
<div className={styles.leftContainer}>{banner}</div>
|
||||
<div className={styles.rightContainer}>
|
||||
<ConditionallyRender
|
||||
condition={showMenu}
|
||||
condition={showMenu && !isLoginpage}
|
||||
show={
|
||||
<div className={styles.menu}>
|
||||
<Link to="/login">Login</Link>
|
||||
|
@ -9,7 +9,7 @@ const localStorage = window.localStorage || {
|
||||
const basePath = location ? location.pathname : '/';
|
||||
const SETTINGS = `${basePath}:settings`;
|
||||
|
||||
const DEFAULT = fromJS({});
|
||||
const DEFAULT = fromJS({ location: {} });
|
||||
|
||||
function getInitState() {
|
||||
try {
|
||||
|
@ -8,9 +8,9 @@ const theme = createMuiTheme({
|
||||
dark: '#34515e',
|
||||
},
|
||||
secondary: {
|
||||
main: '#00695c',
|
||||
light: '#439889',
|
||||
dark: '#003d33',
|
||||
main: '#0b5644',
|
||||
light: '#40836f',
|
||||
dark: '#002c1d',
|
||||
},
|
||||
neutral: {
|
||||
main: '#18243e',
|
||||
|
Loading…
Reference in New Issue
Block a user