diff --git a/frontend/CHANGELOG.md b/frontend/CHANGELOG.md index 2334788a66..b3576de732 100644 --- a/frontend/CHANGELOG.md +++ b/frontend/CHANGELOG.md @@ -7,7 +7,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/). The latest version of this document is always available in [releases][releases-url]. - +# 4.0.0-alpha.10 +- fix: password # 4.0.0-alpha.9 - fix: optimizations - feat: user profile diff --git a/frontend/package.json b/frontend/package.json index 11be3146d8..9ddf7efada 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -1,7 +1,7 @@ { "name": "unleash-frontend", "description": "unleash your features", - "version": "4.0.0-alpha.9", + "version": "4.0.0-alpha.10", "keywords": [ "unleash", "feature toggle", diff --git a/frontend/src/component/common/drag-and-drop.jsx b/frontend/src/component/common/drag-and-drop.jsx deleted file mode 100644 index 1fd02263ae..0000000000 --- a/frontend/src/component/common/drag-and-drop.jsx +++ /dev/null @@ -1,15 +0,0 @@ -import { DndProvider } from 'react-dnd'; -import { HTML5Backend } from 'react-dnd-html5-backend'; -import React from 'react'; - -function useDNDProviderElement(props) { - - if (!props.children) return null; - - return {props.children}; -} - -export default function DragAndDrop(props) { - const DNDElement = useDNDProviderElement(props); - return {DNDElement}; -} diff --git a/frontend/src/component/feature/strategy/strategies-list-component.jsx b/frontend/src/component/feature/strategy/strategies-list-component.jsx index 9296aa4d27..889e9b2dbf 100644 --- a/frontend/src/component/feature/strategy/strategies-list-component.jsx +++ b/frontend/src/component/feature/strategy/strategies-list-component.jsx @@ -1,4 +1,4 @@ -import React, { useState, useEffect } from 'react'; +import { useState, useEffect } from 'react'; import PropTypes from 'prop-types'; import cloneDeep from 'lodash.clonedeep'; @@ -6,7 +6,6 @@ import arrayMove from 'array-move'; import { Button } from '@material-ui/core'; import { Alert } from '@material-ui/lab'; -import DragAndDrop from '../../common/drag-and-drop'; import HeaderTitle from '../../common/HeaderTitle'; import { updateIndexInArray } from '../../common/util'; import styles from './strategy.module.scss'; @@ -27,7 +26,9 @@ const StrategiesList = props => { const [delStrategy, setDelStrategy] = useState(null); const [showCreateStrategy, setShowCreateStrategy] = useState(false); const [showAlert, setShowAlert] = useState(true); - const [editableStrategies, updateEditableStrategies] = useState(cloneDeep(props.configuredStrategies)); + const [editableStrategies, updateEditableStrategies] = useState( + cloneDeep(props.configuredStrategies) + ); const [editStrategyIndex, setEditStrategyIndex] = useState(); useEffect(() => { @@ -39,7 +40,11 @@ const StrategiesList = props => { const updateStrategy = index => strategy => { const newStrategy = { ...strategy }; - const newStrategies = updateIndexInArray(editableStrategies, index, newStrategy); + const newStrategies = updateIndexInArray( + editableStrategies, + index, + newStrategy + ); updateEditableStrategies(newStrategies); }; @@ -87,9 +92,13 @@ const StrategiesList = props => { const strategy = editableStrategies[delStrategy]; if (!strategy.new) { - await props.saveStrategies(props.configuredStrategies.filter((_, i) => i !== delStrategy)); + await props.saveStrategies( + props.configuredStrategies.filter((_, i) => i !== delStrategy) + ); } - updateEditableStrategies(editableStrategies.filter((_, i) => i !== delStrategy)); + updateEditableStrategies( + editableStrategies.filter((_, i) => i !== delStrategy) + ); setDelStrategy(undefined); setShowDelDialog(null); @@ -100,7 +109,12 @@ const StrategiesList = props => { setEditStrategyIndex(undefined); }; - const { strategies, configuredStrategies, featureToggleName, editable } = props; + const { + strategies, + configuredStrategies, + featureToggleName, + editable, + } = props; const resolveStrategyDefinition = strategyName => { if (!strategies || strategies.length === 0) { @@ -139,67 +153,77 @@ const StrategiesList = props => { strategy={editingStrategy} updateStrategy={updateStrategy(editStrategyIndex)} saveStrategy={saveStrategy(editStrategyIndex)} - strategyDefinition={resolveStrategyDefinition(editingStrategy.name)} + strategyDefinition={resolveStrategyDefinition( + editingStrategy.name + )} onCancel={clearAll} /> ) : null} - - - - - } - /> - } - /> - setShowAlert(false)}> - Strategies allow you fine grained control over how to activate your features, and are - composable blocks that are executed in an OR fashion. As an example, you can have a gradual - rollout that targets 80% of users in a region of the world (using the enterprise feature of - constraints), and another gradual rollout that targets 20% of the users in another region. - If you don't add a strategy, the default strategy is activated which means that the feature - will be strictly on/off for your entire userbase. - - } - /> - - No activation strategies selected. -

- } - /> + + + + } + /> + } + /> + setShowAlert(false)} + > + Strategies allow you fine grained control over how to + activate your features, and are composable blocks that + are executed in an OR fashion. As an example, you can + have a gradual rollout that targets 80% of users in a + region of the world (using the enterprise feature of + constraints), and another gradual rollout that targets + 20% of the users in another region. If you don't add a + strategy, the default strategy is activated which means + that the feature will be strictly on/off for your entire + userbase. + + } + /> + + No activation strategies selected. +

+ } + /> - removeStrategy()} - onClose={() => { - setDelStrategy(null); - setShowDelDialog(false); - }} - /> - 0} - show={
{cards}
} - /> -
+ removeStrategy()} + onClose={() => { + setDelStrategy(null); + setShowDelDialog(false); + }} + /> + 0} + show={
{cards}
} + /> ); }; diff --git a/frontend/src/component/user/PasswordAuth/PasswordAuth.jsx b/frontend/src/component/user/PasswordAuth/PasswordAuth.jsx index f7c919f54b..2e043a5e39 100644 --- a/frontend/src/component/user/PasswordAuth/PasswordAuth.jsx +++ b/frontend/src/component/user/PasswordAuth/PasswordAuth.jsx @@ -1,16 +1,12 @@ import React, { useState } from 'react'; import classnames from 'classnames'; import PropTypes from 'prop-types'; -import { - Button, - TextField, - Typography, - IconButton, -} from '@material-ui/core'; +import { Button, TextField, Typography, IconButton } from '@material-ui/core'; import ConditionallyRender from '../../common/ConditionallyRender'; import { useHistory } from 'react-router'; import { useCommonStyles } from '../../../common.styles'; import { useStyles } from './PasswordAuth.styles'; +import { Link } from 'react-router-dom'; const PasswordAuth = ({ authDetails, passwordLogin, loadInitialData }) => { const commonStyles = useCommonStyles(); @@ -76,11 +72,7 @@ const PasswordAuth = ({ authDetails, passwordLogin, loadInitialData }) => { const { usernameError, passwordError, apiError } = errors; return ( -
- + {apiError} @@ -113,6 +105,11 @@ const PasswordAuth = ({ authDetails, passwordLogin, loadInitialData }) => { size="small" /> + + + Forgot your password? + + @@ -142,7 +142,7 @@ const PasswordAuth = ({ authDetails, passwordLogin, loadInitialData }) => { condition={showFields} show={renderLoginForm()} elseShow={ - + {' '} Show more options @@ -155,15 +155,12 @@ const PasswordAuth = ({ authDetails, passwordLogin, loadInitialData }) => { return (
- - {authDetails.message} - - 0} - show={renderWithOptions(options)} - elseShow={renderLoginForm()} - /> - + {authDetails.message} + 0} + show={renderWithOptions(options)} + elseShow={renderLoginForm()} + />
); }; diff --git a/frontend/src/hooks/useResetPassword.ts b/frontend/src/hooks/useResetPassword.ts index 88c1b9c854..106b3d76af 100644 --- a/frontend/src/hooks/useResetPassword.ts +++ b/frontend/src/hooks/useResetPassword.ts @@ -8,6 +8,7 @@ const getFetcher = (token: string) => () => }).then(res => res.json()); const INVALID_TOKEN_ERROR = 'InvalidTokenError'; +const USED_TOKEN_ERROR = 'UsedTokenError'; const useResetPassword = () => { const query = useQueryParams(); @@ -30,7 +31,9 @@ const useResetPassword = () => { setLoading(!error && !data); }, [data, error]); - const invalidToken = !loading && data?.name === INVALID_TOKEN_ERROR; + const invalidToken = + (!loading && data?.name === INVALID_TOKEN_ERROR) || + data?.name === USED_TOKEN_ERROR; return { token, data, error, loading, setLoading, invalidToken, retry }; }; diff --git a/frontend/src/index.tsx b/frontend/src/index.tsx index 809024718d..f20f133363 100644 --- a/frontend/src/index.tsx +++ b/frontend/src/index.tsx @@ -8,6 +8,8 @@ import { Provider } from 'react-redux'; import { ThemeProvider, CssBaseline } from '@material-ui/core'; import thunkMiddleware from 'redux-thunk'; import { createStore, applyMiddleware, compose } from 'redux'; +import { DndProvider } from 'react-dnd'; +import { HTML5Backend } from 'react-dnd-html5-backend'; import { StylesProvider } from '@material-ui/core/styles'; import mainTheme from './themes/main-theme'; @@ -39,18 +41,20 @@ metricsPoller.start(); ReactDOM.render( - - - - - - - - - - - - + + + + + + + + + + + + + + , document.getElementById('app') );