1
0
mirror of https://github.com/Unleash/unleash.git synced 2025-06-09 01:17:06 +02:00

Merge branch 'main' into update/remove-snackbar

This commit is contained in:
Fredrik Strand Oseberg 2022-01-27 17:31:58 +01:00 committed by GitHub
commit d1b7346688
6 changed files with 53 additions and 68 deletions

View File

@ -17,7 +17,7 @@ jobs:
- name: Run Cypress - name: Run Cypress
uses: cypress-io/github-action@v2 uses: cypress-io/github-action@v2
with: with:
env: AUTH_TOKEN=${{ secrets.UNLEASH_TOKEN }},DEFAULT_ENV="default" env: AUTH_TOKEN=${{ secrets.UNLEASH_TOKEN }},DEFAULT_ENV="development"
config: baseUrl=${{ github.event.deployment_status.target_url }} config: baseUrl=${{ github.event.deployment_status.target_url }}
record: true record: true
env: env:

View File

@ -14,7 +14,7 @@
let featureToggleName = ''; let featureToggleName = '';
let enterprise = false; let enterprise = false;
let strategyId = ''; let strategyId = '';
let defaultEnv = 'default'; let defaultEnv = 'development';
describe('feature toggle', () => { describe('feature toggle', () => {
before(() => { before(() => {
@ -94,7 +94,7 @@ describe('feature toggle', () => {
cy.url().should('include', featureToggleName); cy.url().should('include', featureToggleName);
}); });
it('Can add a gradual rollout strategy to the default environment', () => { it('Can add a gradual rollout strategy to the development environment', () => {
cy.wait(500); cy.wait(500);
cy.visit(`/projects/default/features2/${featureToggleName}/strategies`); cy.visit(`/projects/default/features2/${featureToggleName}/strategies`);
cy.get('[data-test=ADD_NEW_STRATEGY_ID]').click(); cy.get('[data-test=ADD_NEW_STRATEGY_ID]').click();
@ -134,11 +134,10 @@ describe('feature toggle', () => {
).as('addStrategyToFeature'); ).as('addStrategyToFeature');
cy.get('[data-test=ADD_NEW_STRATEGY_SAVE_ID]').first().click(); cy.get('[data-test=ADD_NEW_STRATEGY_SAVE_ID]').first().click();
cy.get('[data-test=DIALOGUE_CONFIRM_ID]').click();
cy.wait('@addStrategyToFeature'); cy.wait('@addStrategyToFeature');
}); });
it('can update a strategy in the default environment', () => { it('can update a strategy in the development environment', () => {
cy.wait(500); cy.wait(500);
cy.visit(`/projects/default/features2/${featureToggleName}/strategies`); cy.visit(`/projects/default/features2/${featureToggleName}/strategies`);
cy.get('[data-test=STRATEGY_ACCORDION_ID-flexibleRollout').click(); cy.get('[data-test=STRATEGY_ACCORDION_ID-flexibleRollout').click();
@ -182,11 +181,10 @@ describe('feature toggle', () => {
).as('updateStrategy'); ).as('updateStrategy');
cy.get('[data-test=UPDATE_STRATEGY_BUTTON_ID]').first().click(); cy.get('[data-test=UPDATE_STRATEGY_BUTTON_ID]').first().click();
cy.get('[data-test=DIALOGUE_CONFIRM_ID]').click();
cy.wait('@updateStrategy'); cy.wait('@updateStrategy');
}); });
it('can delete a strategy in the default environment', () => { it('can delete a strategy in the development environment', () => {
cy.wait(500); cy.wait(500);
cy.visit(`/projects/default/features2/${featureToggleName}/strategies`); cy.visit(`/projects/default/features2/${featureToggleName}/strategies`);
@ -205,7 +203,7 @@ describe('feature toggle', () => {
cy.wait('@deleteStrategy'); cy.wait('@deleteStrategy');
}); });
it('Can add a userid strategy to the default environment', () => { it('Can add a userid strategy to the development environment', () => {
cy.wait(500); cy.wait(500);
cy.visit(`/projects/default/features2/${featureToggleName}/strategies`); cy.visit(`/projects/default/features2/${featureToggleName}/strategies`);
cy.get('[data-test=ADD_NEW_STRATEGY_ID]').click(); cy.get('[data-test=ADD_NEW_STRATEGY_ID]').click();
@ -247,7 +245,6 @@ describe('feature toggle', () => {
).as('addStrategyToFeature'); ).as('addStrategyToFeature');
cy.get('[data-test=ADD_NEW_STRATEGY_SAVE_ID]').first().click(); cy.get('[data-test=ADD_NEW_STRATEGY_SAVE_ID]').first().click();
cy.get('[data-test=DIALOGUE_CONFIRM_ID]').click();
cy.wait('@addStrategyToFeature'); cy.wait('@addStrategyToFeature');
}); });

View File

@ -1,7 +1,7 @@
{ {
"name": "unleash-frontend", "name": "unleash-frontend",
"description": "unleash your features", "description": "unleash your features",
"version": "4.6.0-beta.7", "version": "4.6.0-beta.9",
"keywords": [ "keywords": [
"unleash", "unleash",
"feature toggle", "feature toggle",

View File

@ -1,6 +1,5 @@
/* eslint-disable no-alert */ /* eslint-disable no-alert */
import { useContext, useState } from 'react'; import React, { useContext, useState } from 'react';
import PropTypes from 'prop-types';
import { import {
Table, Table,
TableBody, TableBody,
@ -21,9 +20,14 @@ import loadingData from './loadingData';
import useLoading from '../../../../hooks/useLoading'; import useLoading from '../../../../hooks/useLoading';
import usePagination from '../../../../hooks/usePagination'; import usePagination from '../../../../hooks/usePagination';
import PaginateUI from '../../../common/PaginateUI/PaginateUI'; import PaginateUI from '../../../common/PaginateUI/PaginateUI';
import { useHistory } from 'react-router-dom';
import { IUser } from '../../../../interfaces/user';
import IRole from '../../../../interfaces/role';
import useToast from '../../../../hooks/useToast';
function UsersList({ location, closeDialog, showDialog }) { const UsersList = () => {
const { users, roles, refetch, loading } = useUsers(); const { users, roles, refetch, loading } = useUsers();
const { setToastData, setToastApiError } = useToast();
const { const {
removeUser, removeUser,
changePassword, changePassword,
@ -31,13 +35,17 @@ function UsersList({ location, closeDialog, showDialog }) {
userLoading, userLoading,
userApiErrors, userApiErrors,
} = useAdminUsersApi(); } = useAdminUsersApi();
const history = useHistory();
const { location } = history;
const { hasAccess } = useContext(AccessContext); const { hasAccess } = useContext(AccessContext);
const [pwDialog, setPwDialog] = useState({ open: false }); const [pwDialog, setPwDialog] = useState<{ open: boolean; user?: IUser }>({
open: false,
});
const [delDialog, setDelDialog] = useState(false); const [delDialog, setDelDialog] = useState(false);
const [showConfirm, setShowConfirm] = useState(false); const [showConfirm, setShowConfirm] = useState(false);
const [emailSent, setEmailSent] = useState(false); const [emailSent, setEmailSent] = useState(false);
const [inviteLink, setInviteLink] = useState(''); const [inviteLink, setInviteLink] = useState('');
const [delUser, setDelUser] = useState(); const [delUser, setDelUser] = useState<IUser>();
const ref = useLoading(loading); const ref = useLoading(loading);
const { page, pages, nextPage, prevPage, setPageIndex, pageIndex } = const { page, pages, nextPage, prevPage, setPageIndex, pageIndex } =
usePagination(users, 50); usePagination(users, 50);
@ -47,12 +55,14 @@ function UsersList({ location, closeDialog, showDialog }) {
setDelUser(undefined); setDelUser(undefined);
}; };
const openDelDialog = user => e => { const openDelDialog =
(user: IUser) => (e: React.SyntheticEvent<Element, Event>) => {
e.preventDefault(); e.preventDefault();
setDelDialog(true); setDelDialog(true);
setDelUser(user); setDelUser(user);
}; };
const openPwDialog = user => e => { const openPwDialog =
(user: IUser) => (e: React.SyntheticEvent<Element, Event>) => {
e.preventDefault(); e.preventDefault();
setPwDialog({ open: true, user }); setPwDialog({ open: true, user });
}; };
@ -61,26 +71,28 @@ function UsersList({ location, closeDialog, showDialog }) {
setPwDialog({ open: false }); setPwDialog({ open: false });
}; };
const onDeleteUser = () => { const onDeleteUser = async () => {
removeUser(delUser) try {
.then(() => { await removeUser(delUser);
setToastData({
title: `${delUser?.name} has been deleted`,
type: 'success',
});
refetch(); refetch();
closeDelDialog(); closeDelDialog();
}) } catch (e: any) {
.catch(handleCatch); setToastApiError(e.toString());
}
}; };
const handleCatch = () =>
console.log('An exception was thrown and handled.');
const closeConfirm = () => { const closeConfirm = () => {
setShowConfirm(false); setShowConfirm(false);
setEmailSent(false); setEmailSent(false);
setInviteLink(''); setInviteLink('');
}; };
const renderRole = roleId => { const renderRole = (roleId: number) => {
const role = roles.find(r => r.id === roleId); const role = roles.find((r: IRole) => r.id === roleId);
return role ? role.name : ''; return role ? role.name : '';
}; };
@ -156,7 +168,7 @@ function UsersList({ location, closeDialog, showDialog }) {
/> />
<ConditionallyRender <ConditionallyRender
condition={delUser} condition={Boolean(delUser)}
show={ show={
<DelUser <DelUser
showDialog={delDialog} showDialog={delDialog}
@ -170,10 +182,6 @@ function UsersList({ location, closeDialog, showDialog }) {
/> />
</div> </div>
); );
}
UsersList.propTypes = {
location: PropTypes.object.isRequired,
}; };
export default UsersList; export default UsersList;

View File

@ -1,6 +1,5 @@
import { useContext, useState } from 'react'; import { useContext } from 'react';
import PropTypes from 'prop-types'; import UsersList from './UsersList/UsersList';
import UsersList from './UsersList';
import AdminMenu from '../admin-menu'; import AdminMenu from '../admin-menu';
import PageContent from '../../../component/common/PageContent/PageContent'; import PageContent from '../../../component/common/PageContent/PageContent';
import AccessContext from '../../../contexts/AccessContext'; import AccessContext from '../../../contexts/AccessContext';
@ -10,21 +9,13 @@ import { Alert } from '@material-ui/lab';
import HeaderTitle from '../../../component/common/HeaderTitle'; import HeaderTitle from '../../../component/common/HeaderTitle';
import { Button } from '@material-ui/core'; import { Button } from '@material-ui/core';
import { useStyles } from './index.styles'; import { useStyles } from './index.styles';
import { useHistory } from 'react-router-dom';
const UsersAdmin = ({ history }) => { const UsersAdmin = () => {
const { hasAccess } = useContext(AccessContext); const { hasAccess } = useContext(AccessContext);
const [showDialog, setDialog] = useState(false); const history = useHistory();
const styles = useStyles(); const styles = useStyles();
const openDialog = e => {
e.preventDefault();
setDialog(true);
};
const closeDialog = () => {
setDialog(false);
};
return ( return (
<div> <div>
<AdminMenu history={history} /> <AdminMenu history={history} />
@ -59,13 +50,7 @@ const UsersAdmin = ({ history }) => {
> >
<ConditionallyRender <ConditionallyRender
condition={hasAccess(ADMIN)} condition={hasAccess(ADMIN)}
show={ show={<UsersList />}
<UsersList
openDialog={openDialog}
closeDialog={closeDialog}
showDialog={showDialog}
/>
}
elseShow={ elseShow={
<Alert severity="error"> <Alert severity="error">
You need instance admin to access this section. You need instance admin to access this section.
@ -77,9 +62,4 @@ const UsersAdmin = ({ history }) => {
); );
}; };
UsersAdmin.propTypes = {
match: PropTypes.object.isRequired,
history: PropTypes.object.isRequired,
};
export default UsersAdmin; export default UsersAdmin;

View File

@ -104,7 +104,7 @@ const ContextForm: React.FC<IContextForm> = ({
label="Context name" label="Context name"
value={contextName} value={contextName}
disabled={mode === 'Edit'} disabled={mode === 'Edit'}
onChange={e => setContextName(e.target.value)} onChange={e => setContextName(trim(e.target.value))}
error={Boolean(errors.name)} error={Boolean(errors.name)}
errorText={errors.name} errorText={errors.name}
onFocus={() => clearErrors()} onFocus={() => clearErrors()}