From f2b4158e53762407052a53554986cff59c56b569 Mon Sep 17 00:00:00 2001 From: Renovate Bot Date: Thu, 21 Oct 2021 08:55:45 +0000 Subject: [PATCH 1/5] chore(deps): pin dependency copy-to-clipboard to 3.3.1 --- frontend/package.json | 2 +- frontend/yarn.lock | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/frontend/package.json b/frontend/package.json index 62a66cb5a8..01fdcb6a72 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -53,7 +53,7 @@ "@welldone-software/why-did-you-render": "6.2.1", "array-move": "3.0.1", "classnames": "2.3.1", - "copy-to-clipboard": "^3.3.1", + "copy-to-clipboard": "3.3.1", "craco": "0.0.3", "css-loader": "6.4.0", "cypress": "8.6.0", diff --git a/frontend/yarn.lock b/frontend/yarn.lock index abe0470939..4fdc1ba3de 100644 --- a/frontend/yarn.lock +++ b/frontend/yarn.lock @@ -4144,7 +4144,7 @@ copy-descriptor@^0.1.0: resolved "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz" integrity sha1-Z29us8OZl8LuGsOpJP1hJHSPV40= -copy-to-clipboard@^3.3.1: +copy-to-clipboard@3.3.1: version "3.3.1" resolved "https://registry.yarnpkg.com/copy-to-clipboard/-/copy-to-clipboard-3.3.1.tgz#115aa1a9998ffab6196f93076ad6da3b913662ae" integrity sha512-i13qo6kIHTTpCm8/Wup+0b1mVWETvu2kIMzKoK8FpkLkFxlt0znUAHcMzox+T8sPlqtZXq3CulEjQHsYiGFJUw== From 3c140110fe869335f54604706aae629c54170827 Mon Sep 17 00:00:00 2001 From: Christopher Kolstad Date: Thu, 21 Oct 2021 13:04:38 +0200 Subject: [PATCH 2/5] fix: wrap link to edit context field in hasAccess check --- frontend/src/component/context/ContextList/ContextList.jsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/frontend/src/component/context/ContextList/ContextList.jsx b/frontend/src/component/context/ContextList/ContextList.jsx index 21e2d8b191..d055e93a5f 100644 --- a/frontend/src/component/context/ContextList/ContextList.jsx +++ b/frontend/src/component/context/ContextList/ContextList.jsx @@ -4,7 +4,7 @@ import HeaderTitle from '../../common/HeaderTitle'; import ConditionallyRender from '../../common/ConditionallyRender/ConditionallyRender'; import { CREATE_CONTEXT_FIELD, - DELETE_CONTEXT_FIELD, + DELETE_CONTEXT_FIELD, UPDATE_CONTEXT_FIELD, } from '../../providers/AccessProvider/permissions'; import { IconButton, @@ -39,10 +39,10 @@ const ContextList = ({ removeContextField, history, contextFields }) => { + {field.name} - } + } elseShow={{field.name}} />} secondary={field.description} /> Date: Thu, 21 Oct 2021 13:25:39 +0200 Subject: [PATCH 3/5] fix: Adds PermissionSwitch (#456) - This adds a generic way to control permission to mutations in the same way as our PermissionButton and PermissionIconButton already does the same. - This also switches the StrategiesList to use PermissionIconButton so users without ADMIN role do not believe they can deprecate/reactivate strategies. --- .../PermissionSwitch/PermissionSwitch.tsx | 40 ++++ .../FeatureToggleListNewItem.tsx | 14 +- .../FeatureOverviewMetaData.tsx | 8 +- .../AddFeatureVariant/AddFeatureVariant.tsx | 6 +- .../FeatureViewEnvironment.tsx | 13 +- .../ProjectEnvironment/ProjectEnvironment.tsx | 16 +- .../StrategiesList/StrategiesList.jsx | 90 ++++---- .../list-component-test.jsx.snap | 214 ++++++++++-------- 8 files changed, 225 insertions(+), 176 deletions(-) create mode 100644 frontend/src/component/common/PermissionSwitch/PermissionSwitch.tsx diff --git a/frontend/src/component/common/PermissionSwitch/PermissionSwitch.tsx b/frontend/src/component/common/PermissionSwitch/PermissionSwitch.tsx new file mode 100644 index 0000000000..1e9bb3eab2 --- /dev/null +++ b/frontend/src/component/common/PermissionSwitch/PermissionSwitch.tsx @@ -0,0 +1,40 @@ +import { Switch, Tooltip } from '@material-ui/core'; +import { OverridableComponent } from '@material-ui/core/OverridableComponent'; +import AccessContext from '../../../contexts/AccessContext'; +import React, { useContext } from 'react'; + +interface IPermissionSwitchProps extends OverridableComponent { + permission: string; + tooltip: string; + onChange?: (e: any) => void; + disabled?: boolean; + projectId?: string; +} + +const PermissionSwitch: React.FC = ({ + permission, + tooltip = '', + disabled, + projectId, + onChange, + ...rest +}) => { + const { hasAccess } = useContext(AccessContext); + const access = projectId + ? hasAccess(permission, projectId) + : hasAccess(permission); + + const tooltipText = access + ? tooltip + : "You don't have access to perform this operation"; + + return ( + + + + + + ) +} + +export default PermissionSwitch; diff --git a/frontend/src/component/feature/FeatureToggleListNew/FeatureToggleListNewItem/FeatureToggleListNewItem.tsx b/frontend/src/component/feature/FeatureToggleListNew/FeatureToggleListNewItem/FeatureToggleListNewItem.tsx index e65ee960fd..10c5aed07f 100644 --- a/frontend/src/component/feature/FeatureToggleListNew/FeatureToggleListNewItem/FeatureToggleListNewItem.tsx +++ b/frontend/src/component/feature/FeatureToggleListNew/FeatureToggleListNewItem/FeatureToggleListNewItem.tsx @@ -1,5 +1,5 @@ -import { useContext, useRef } from 'react'; -import { Switch, TableCell, TableRow } from '@material-ui/core'; +import { useRef } from 'react'; +import { TableCell, TableRow } from '@material-ui/core'; import { useHistory } from 'react-router'; import { useStyles } from '../FeatureToggleListNew.styles'; @@ -15,7 +15,7 @@ import classNames from 'classnames'; import CreatedAt from './CreatedAt'; import useProject from '../../../../hooks/api/getters/useProject/useProject'; import { UPDATE_FEATURE } from '../../../providers/AccessProvider/permissions'; -import AccessContext from '../../../../contexts/AccessContext'; +import PermissionSwitch from '../../../common/PermissionSwitch/PermissionSwitch'; interface IFeatureToggleListNewItemProps { name: string; @@ -34,7 +34,6 @@ const FeatureToggleListNewItem = ({ projectId, createdAt, }: IFeatureToggleListNewItemProps) => { - const { hasAccess } = useContext(AccessContext); const { toast, setToastData } = useToast(); const { toggleFeatureByEnvironment } = useToggleFeatureByEnv( projectId, @@ -127,11 +126,10 @@ const FeatureToggleListNewItem = ({ key={env.name} > - diff --git a/frontend/src/component/feature/FeatureView2/FeatureOverview/FeatureOverviewMetaData/FeatureOverviewMetaData.tsx b/frontend/src/component/feature/FeatureView2/FeatureOverview/FeatureOverviewMetaData/FeatureOverviewMetaData.tsx index 87d2d7f9fc..5bdabd12e1 100644 --- a/frontend/src/component/feature/FeatureView2/FeatureOverview/FeatureOverviewMetaData/FeatureOverviewMetaData.tsx +++ b/frontend/src/component/feature/FeatureView2/FeatureOverview/FeatureOverviewMetaData/FeatureOverviewMetaData.tsx @@ -9,6 +9,8 @@ import { useStyles } from './FeatureOverviewMetadata.styles'; import { Edit } from '@material-ui/icons'; import { IFeatureViewParams } from '../../../../../interfaces/params'; +import PermissionIconButton from '../../../../common/PermissionIconButton/PermissionIconButton'; +import { UPDATE_FEATURE } from '../../../../providers/AccessProvider/permissions'; const FeatureOverviewMetaData = () => { const styles = useStyles(); @@ -39,12 +41,14 @@ const FeatureOverviewMetaData = () => {
Description:

{description}

- - +
} diff --git a/frontend/src/component/feature/FeatureView2/FeatureVariants/FeatureVariantsList/AddFeatureVariant/AddFeatureVariant.tsx b/frontend/src/component/feature/FeatureView2/FeatureVariants/FeatureVariantsList/AddFeatureVariant/AddFeatureVariant.tsx index 0c20848aa2..45aa1221bf 100644 --- a/frontend/src/component/feature/FeatureView2/FeatureVariants/FeatureVariantsList/AddFeatureVariant/AddFeatureVariant.tsx +++ b/frontend/src/component/feature/FeatureView2/FeatureVariants/FeatureVariantsList/AddFeatureVariant/AddFeatureVariant.tsx @@ -4,7 +4,6 @@ import { FormControl, FormControlLabel, Grid, - Switch, TextField, InputAdornment, Button, @@ -20,6 +19,8 @@ import GeneralSelect from '../../../../../common/GeneralSelect/GeneralSelect'; import { useCommonStyles } from '../../../../../../common.styles'; import Dialogue from '../../../../../common/Dialogue'; import { trim, modalStyles } from '../../../../../common/util'; +import PermissionSwitch from '../../../../../common/PermissionSwitch/PermissionSwitch'; +import { UPDATE_FEATURE } from '../../../../../providers/AccessProvider/permissions'; const payloadOptions = [ { key: 'string', label: 'string' }, @@ -242,7 +243,8 @@ const AddVariant = ({ = ({ condition={env?.strategies?.length > 0} show={
- { - const { hasAccess } = useContext(AccessContext); - // api state const { toast, setToastData } = useToast(); const { uiConfig } = useUiConfig(); @@ -126,8 +124,6 @@ const ProjectEnvironmentList = ({ projectId }: ProjectEnvironmentListProps) => { enabled: project?.environments.includes(e.name), })); - const hasPermission = hasAccess(UPDATE_PROJECT, projectId); - const genLabel = (env: ProjectEnvironment) => ( <> {env.name} environment is{' '} @@ -143,9 +139,11 @@ const ProjectEnvironmentList = ({ projectId }: ProjectEnvironmentListProps) => { key={env.name} label={genLabel(env)} control={ - diff --git a/frontend/src/component/strategies/StrategiesList/StrategiesList.jsx b/frontend/src/component/strategies/StrategiesList/StrategiesList.jsx index 30dcd3ac77..88c8811376 100644 --- a/frontend/src/component/strategies/StrategiesList/StrategiesList.jsx +++ b/frontend/src/component/strategies/StrategiesList/StrategiesList.jsx @@ -4,27 +4,10 @@ import classnames from 'classnames'; import { Link, useHistory } from 'react-router-dom'; import useMediaQuery from '@material-ui/core/useMediaQuery'; -import { - List, - ListItem, - ListItemAvatar, - IconButton, - ListItemText, - Button, - Tooltip, -} from '@material-ui/core'; -import { - Add, - Visibility, - VisibilityOff, - Delete, - Extension, -} from '@material-ui/icons'; +import { IconButton, List, ListItem, ListItemAvatar, ListItemText, Tooltip } from '@material-ui/core'; +import { Add, Delete, Extension, Visibility, VisibilityOff } from '@material-ui/icons'; -import { - CREATE_STRATEGY, - DELETE_STRATEGY, -} from '../../providers/AccessProvider/permissions'; +import { CREATE_STRATEGY, DELETE_STRATEGY, UPDATE_STRATEGY } from '../../providers/AccessProvider/permissions'; import ConditionallyRender from '../../common/ConditionallyRender/ConditionallyRender'; import PageContent from '../../common/PageContent/PageContent'; @@ -34,6 +17,8 @@ import { useStyles } from './styles'; import AccessContext from '../../../contexts/AccessContext'; import Dialogue from '../../common/Dialogue'; import { ADD_NEW_STRATEGY_ID } from '../../../testIds'; +import PermissionIconButton from '../../common/PermissionIconButton/PermissionIconButton'; +import PermissionButton from '../../common/PermissionButton/PermissionButton'; const StrategiesList = ({ strategies, @@ -60,26 +45,29 @@ const StrategiesList = ({ - history.push('/strategies/create') } + permission={CREATE_STRATEGY} + tooltip={'Add new strategy'} > - - + + } elseShow={ - + } /> } @@ -98,7 +86,7 @@ const StrategiesList = ({ const reactivateButton = strategy => ( - setDialogueMetaData({ show: true, @@ -106,9 +94,9 @@ const StrategiesList = ({ onConfirm: () => reactivateStrategy(strategy), }) } - > - - + permission={UPDATE_STRATEGY} + tooltip={'Reactivate activation strategy'} + > ); @@ -119,28 +107,28 @@ const StrategiesList = ({
- +
} elseShow={ - -
- - setDialogueMetaData({ - show: true, - title: 'Really deprecate strategy?', - onConfirm: () => - deprecateStrategy(strategy), - }) - } - > - - -
-
+
+ + setDialogueMetaData({ + show: true, + title: 'Really deprecate strategy?', + onConfirm: () => + deprecateStrategy(strategy), + }) + } + permission={UPDATE_STRATEGY} + tooltip={'Deprecate activation strategy'} + > + + +
} /> ); @@ -149,8 +137,7 @@ const StrategiesList = ({ - setDialogueMetaData({ show: true, @@ -158,10 +145,11 @@ const StrategiesList = ({ onConfirm: () => removeStrategy(strategy), }) } + permission={DELETE_STRATEGY} + tooltip={'Delete strategy'} > - - + } elseShow={ diff --git a/frontend/src/component/strategies/__tests__/__snapshots__/list-component-test.jsx.snap b/frontend/src/component/strategies/__tests__/__snapshots__/list-component-test.jsx.snap index e5c87bfe99..7a872fe07e 100644 --- a/frontend/src/component/strategies/__tests__/__snapshots__/list-component-test.jsx.snap +++ b/frontend/src/component/strategies/__tests__/__snapshots__/list-component-test.jsx.snap @@ -81,53 +81,52 @@ exports[`renders correctly with one strategy 1`] = ` another's description

-
- + + + + + +
@@ -164,34 +163,49 @@ exports[`renders correctly with one strategy without permissions 1`] = `
- + + Add new strategy + + + + +
@@ -245,53 +259,55 @@ exports[`renders correctly with one strategy without permissions 1`] = ` another's description

-
- + + + + + + +
Date: Thu, 21 Oct 2021 22:28:25 +0200 Subject: [PATCH 4/5] fix: ApiToken should hide envrionment if it is not enabled yet --- .../ApiTokenCreate/ApiTokenCreate.tsx | 31 ++++++++++++------- 1 file changed, 19 insertions(+), 12 deletions(-) diff --git a/frontend/src/component/api-token/ApiTokenCreate/ApiTokenCreate.tsx b/frontend/src/component/api-token/ApiTokenCreate/ApiTokenCreate.tsx index a82cd6e1ca..3ae313f3e3 100644 --- a/frontend/src/component/api-token/ApiTokenCreate/ApiTokenCreate.tsx +++ b/frontend/src/component/api-token/ApiTokenCreate/ApiTokenCreate.tsx @@ -5,6 +5,8 @@ import { styles as commonStyles } from '../../../component/common'; import { IApiTokenCreate } from '../../../hooks/api/actions/useApiTokensApi/useApiTokensApi'; import useEnvironments from '../../../hooks/api/getters/useEnvironments/useEnvironments'; import useProjects from '../../../hooks/api/getters/useProjects/useProjects'; +import useUiConfig from '../../../hooks/api/getters/useUiConfig/useUiConfig'; +import ConditionallyRender from '../../common/ConditionallyRender'; import Dialogue from '../../common/Dialogue'; import GeneralSelect from '../../common/GeneralSelect/GeneralSelect'; @@ -41,6 +43,7 @@ const ApiTokenCreate = ({ const [error, setError] = useState({}); const { projects } = useProjects(); const { environments } = useEnvironments(); + const { uiConfig } = useUiConfig(); useEffect(() => { if ( @@ -192,18 +195,22 @@ const ApiTokenCreate = ({ className={undefined} classes={undefined} /> - + + + + } /> ); From bdf98dd8b41a138cdce999930bbd2feeee436cb1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ivar=20Conradi=20=C3=98sthus?= Date: Thu, 21 Oct 2021 22:32:14 +0200 Subject: [PATCH 5/5] 4.2.9 --- frontend/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/package.json b/frontend/package.json index 01fdcb6a72..b67c373ed5 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -1,7 +1,7 @@ { "name": "unleash-frontend", "description": "unleash your features", - "version": "4.2.8", + "version": "4.2.9", "keywords": [ "unleash", "feature toggle",