Signed-off-by: soupette <cyril.lpz@gmail.com>
This commit is contained in:
soupette 2020-08-27 15:57:20 +02:00
parent 5a7d89c807
commit 2e67e19bd6
15 changed files with 79 additions and 246 deletions

View File

@ -8,7 +8,6 @@ import React from 'react';
import { get, includes, map, tail, toLower } from 'lodash';
import { FormattedMessage } from 'react-intl';
import PropTypes from 'prop-types';
import { Header, Path, Verb, Wrapper } from './Components';
function BoundRoute({ route }) {

View File

@ -116,141 +116,3 @@ SubCategory.propTypes = {
};
export default SubCategory;
// import React, { useCallback, useMemo } from 'react';
// import { without } from 'lodash';
// import styled from 'styled-components';
// import PropTypes from 'prop-types';
// import { Flex, Padded, Text, Checkbox } from '@buffetjs/core';
// import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
// import CheckboxWrapper from '../CheckboxWrapper';
// import BaselineAlignment from '../BaselineAlignment';
// import SubCategoryWrapper from './SubCategoryWrapper';
// import { useUsersPermissions } from '../../../../contexts/UsersPermissionsContext';
// import PolicyWrapper from './PolicyWrapper';
// const Border = styled.div`
// flex: 1;
// align-self: center;
// border-top: 1px solid #f6f6f6;
// padding: 0px 10px;
// `;
// const SubCategory = ({ subCategory }) => {
// const {
// onSelectedAction,
// onSelectedPermission,
// onSelectedSubcategory,
// pluginName,
// selectedAction,
// } = useUsersPermissions();
// const actions = useMemo(() => {
// return Object.values(subCategory.actions).reduce((acc, curr, index) => {
// return [
// ...acc,
// {
// ...curr,
// name: Object.keys(subCategory.actions)[index],
// },
// ];
// }, []);
// }, [subCategory]);
// const handleSelectPermission = action => {
// onSelectedPermission(`${pluginName}.controllers.${subCategory.name}.${action}`);
// };
// const selectedActions = useMemo(() => {
// return actions.map(a => a.enabled).filter(Boolean);
// }, [actions]);
// const handleSelectPolicy = action => {
// onSelectedAction(`${pluginName}.controllers.${subCategory.name}.${action}`);
// };
// const isActionSelected = useCallback(
// action => {
// const selectedActionArr = without(selectedAction.split('.'), 'controllers');
// return (
// selectedActionArr[0] === pluginName &&
// selectedActionArr[1] === subCategory.name &&
// selectedActionArr[2] === action
// );
// },
// [pluginName, selectedAction, subCategory]
// );
// const hasAllCategoryActions = useMemo(() => {
// return selectedActions.length === actions.length;
// }, [actions, selectedActions]);
// const hasSomeCategoryActions = useMemo(() => {
// return selectedActions.length > 0 && selectedActions.length < actions.length;
// }, [actions, selectedActions]);
// const handleSubCategoryPermissions = useCallback(() => {
// const shouldEnable = selectedActions.length < actions.length;
// onSelectedSubcategory({
// subcategoryPath: `${pluginName}.controllers.${subCategory.name}`,
// shouldEnable,
// });
// // eslint-disable-next-line react-hooks/exhaustive-deps
// }, [actions, pluginName, selectedActions, subCategory]);
// return (
// <SubCategoryWrapper>
// <Flex justifyContent="space-between" alignItems="center">
// <Padded right size="sm">
// <Text
// lineHeight="18px"
// color="#919bae"
// fontWeight="bold"
// fontSize="xs"
// textTransform="uppercase"
// >
// {subCategory.name}
// </Text>
// </Padded>
// <Border />
// <Padded left size="sm">
// <BaselineAlignment />
// <Checkbox
// name={`select-all-${subCategory.name}`}
// message="Select all"
// onChange={handleSubCategoryPermissions}
// someChecked={hasSomeCategoryActions}
// value={hasAllCategoryActions}
// />
// </Padded>
// </Flex>
// <BaselineAlignment />
// <Padded top size="xs">
// <Flex flexWrap="wrap">
// {actions.map(action => (
// <CheckboxWrapper isActive={isActionSelected(action.name)} key={action.name}>
// <Checkbox
// value={action.enabled}
// name={action.name}
// message={action.name}
// onChange={() => handleSelectPermission(action.name)}
// />
// <PolicyWrapper onClick={() => handleSelectPolicy(action.name)}>
// <FontAwesomeIcon icon="cog" />
// </PolicyWrapper>
// </CheckboxWrapper>
// ))}
// </Flex>
// </Padded>
// </SubCategoryWrapper>
// );
// };
// SubCategory.propTypes = {
// subCategory: PropTypes.object.isRequired,
// };
// export default SubCategory;

View File

@ -3,7 +3,6 @@ import { Flex, Text } from '@buffetjs/core';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import PropTypes from 'prop-types';
import { useIntl } from 'react-intl';
import getTrad from '../../../utils/getTrad';
import SubCategory from './SubCategory';
import RowStyle from './RowStyle';
@ -86,86 +85,3 @@ PermissionRow.propTypes = {
};
export default PermissionRow;
// import React, { useMemo } from 'react';
// import { Flex, Text } from '@buffetjs/core';
// import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
// import PropTypes from 'prop-types';
// import { useIntl } from 'react-intl';
// import getTrad from '../../../utils/getTrad';
// import SubCategory from './SubCategory';
// import RowStyle from './RowStyle';
// import PermissionsWrapper from './PermissionsWrapper';
// const PermissionRow = ({ openedPlugin, onOpenPlugin, permissions, isWhite, permissionType }) => {
// const { formatMessage } = useIntl();
// const subCategories = useMemo(() => {
// return Object.values(permissions.controllers).reduce((acc, curr, index) => {
// return [
// ...acc,
// {
// actions: curr,
// name: Object.keys(permissions.controllers)[index],
// },
// ];
// }, []);
// }, [permissions]);
// console.log({ permissions, permissionType });
// return (
// <>
// <RowStyle
// isWhite={isWhite}
// isActive={openedPlugin === permissions.name}
// key={permissions.name}
// onClick={onOpenPlugin}
// >
// <Flex alignItems="center" justifyContent="space-between">
// <div>
// <Text color="grey" fontWeight="bold" fontSize="xs" textTransform="uppercase">
// {permissions.name}
// </Text>
// <Text lineHeight="22px" color="grey">
// {formatMessage(
// { id: getTrad('Plugin.permissions.plugins.description') },
// { name: permissions.name }
// )}
// &nbsp;{permissionType}
// </Text>
// </div>
// <div>
// <FontAwesomeIcon
// style={{ width: '11px' }}
// color="#9EA7B8"
// icon={openedPlugin === permissions.name ? 'chevron-up' : 'chevron-down'}
// />
// </div>
// </Flex>
// </RowStyle>
// {openedPlugin === permissions.name && (
// <PermissionsWrapper>
// {subCategories.map(subCategory => (
// <SubCategory key={subCategory.name} subCategory={subCategory} />
// ))}
// </PermissionsWrapper>
// )}
// </>
// );
// };
// PermissionRow.defaultProps = {
// openedPlugin: null,
// permissionType: null,
// };
// PermissionRow.propTypes = {
// openedPlugin: PropTypes.string,
// onOpenPlugin: PropTypes.func.isRequired,
// permissions: PropTypes.object.isRequired,
// isWhite: PropTypes.bool.isRequired,
// permissionType: PropTypes.string,
// };
// export default PermissionRow;

View File

@ -7,9 +7,9 @@ import init from './init';
import { initialState, reducer } from './reducer';
const Permissions = () => {
const { permissions } = useUsersPermissions();
const { modifiedData } = useUsersPermissions();
const [{ collapses }, dispatch] = useReducer(reducer, initialState, state =>
init(state, permissions)
init(state, modifiedData)
);
const handleOpenPlugin = useCallback(index => {
@ -32,7 +32,7 @@ const Permissions = () => {
isWhite={index % 2 === 1}
name={name}
onOpenPlugin={() => handleOpenPlugin(index)}
permissions={permissions[name]}
permissions={modifiedData[name]}
/>
);
})}

View File

@ -23,6 +23,12 @@ const UsersPermissions = forwardRef(({ permissions, routes, policies }, ref) =>
permissions: state.modifiedData,
};
},
resetForm: () => {
dispatch({ type: 'ON_RESET' });
},
setFormAfterSubmit: () => {
dispatch({ type: 'ON_SUBMIT_SUCCEEDED' });
},
}));
const handleChange = useCallback(({ target: { name, value } }) => {

View File

@ -1,12 +1,10 @@
const init = (state, permissions, routes, policies) => {
return {
...state,
initialData: permissions,
modifiedData: permissions,
permissions,
// TO REMOVE
routes,
policies,
pluginName: Object.keys(permissions)[0],
};
};

View File

@ -3,9 +3,8 @@ import produce from 'immer';
import { set, get, take } from 'lodash';
export const initialState = {
initialData: {},
modifiedData: {},
permissions: {},
pluginName: '',
routes: {},
selectedAction: '',
policies: [],
@ -39,12 +38,20 @@ const reducer = (state, action) =>
break;
}
case 'ON_RESET': {
draftState.modifiedData = state.initialData;
break;
}
case 'ON_SUBMIT_SUCCEEDED': {
draftState.initialData = state.modifiedData;
break;
}
case 'SELECT_ACTION': {
const { actionToSelect } = action;
draftState.selectedAction = actionToSelect === state.selectedAction ? '' : actionToSelect;
break;
}
default:
return draftState;
}

View File

@ -34,7 +34,10 @@ const CreatePage = () => {
id: getTrad('app.components.Button.reset'),
defaultMessage: 'Reset',
}),
onClick: handleReset,
onClick: () => {
handleReset();
permissionsRef.current.resetForm();
},
color: 'cancel',
type: 'button',
},

View File

@ -26,7 +26,7 @@ const EditPage = () => {
params: { id },
} = useRouteMatch(`${settingsBaseURL}/${pluginId}/roles/:id`);
const { permissions, routes, policies, isLoading } = usePlugins();
const { role, isLoading: isRoleLoading } = useFetchRole(id);
const { role, isLoading: isRoleLoading, onSubmitSucceeded } = useFetchRole(id);
const permissionsRef = useRef();
const headerActions = (handleSubmit, handleReset) => {
@ -40,7 +40,10 @@ const EditPage = () => {
id: getTrad('app.components.Button.reset'),
defaultMessage: 'Reset',
}),
onClick: handleReset,
onClick: () => {
handleReset();
permissionsRef.current.resetForm();
},
color: 'cancel',
type: 'button',
},
@ -70,6 +73,8 @@ const EditPage = () => {
})
)
.then(() => {
onSubmitSucceeded({ name: data.name, description: data.description });
permissionsRef.current.setFormAfterSubmit();
strapi.notification.success(getTrad('Settings.roles.edited'));
})
.catch(err => {

View File

@ -1,4 +1,4 @@
import { useReducer, useEffect } from 'react';
import { useCallback, useReducer, useEffect } from 'react';
import { request } from 'strapi-helper-plugin';
import reducer, { initialState } from './reducer';
@ -15,7 +15,6 @@ const useFetchRole = id => {
dispatch({
type: 'GET_DATA_SUCCEEDED',
role: {},
permissions: {},
});
}
@ -40,7 +39,14 @@ const useFetchRole = id => {
}
};
return state;
const handleSubmitSucceeded = useCallback(data => {
dispatch({
type: 'ON_SUBMIT_SUCCEEDED',
...data,
});
}, []);
return { ...state, onSubmitSucceeded: handleSubmitSucceeded };
};
export default useFetchRole;

View File

@ -3,7 +3,6 @@ import produce from 'immer';
export const initialState = {
role: {},
permissions: {},
isLoading: true,
};
@ -19,6 +18,11 @@ const reducer = (state, action) =>
draftState.isLoading = false;
break;
}
case 'ON_SUBMIT_SUCCEEDED': {
draftState.role.name = action.name;
draftState.role.description = action.description;
break;
}
default:
return draftState;
}

View File

@ -4,7 +4,7 @@ import { useIntl } from 'react-intl';
import { get } from 'lodash';
import init from './init';
import pluginId from '../../pluginId';
import { formatPolicies, getTrad } from '../../utils';
import { cleanPermissions, formatPolicies, getTrad } from '../../utils';
import reducer, { initialState } from './reducer';
const usePlugins = (shouldFetchData = true) => {
@ -29,7 +29,7 @@ const usePlugins = (shouldFetchData = true) => {
dispatch({
type: 'GET_DATA_SUCCEEDED',
permissions,
permissions: cleanPermissions(permissions),
routes,
policies: [
{

View File

@ -0,0 +1,25 @@
import { isEmpty } from 'lodash';
const cleanPermissions = permissions =>
Object.keys(permissions).reduce((acc, current) => {
const currentPermission = permissions[current].controllers;
const cleanedControllers = Object.keys(currentPermission).reduce((acc2, curr) => {
if (isEmpty(currentPermission[curr])) {
return acc2;
}
acc2[curr] = currentPermission[curr];
return acc2;
}, {});
if (isEmpty(cleanedControllers)) {
return acc;
}
acc[current] = { controllers: cleanedControllers };
return acc;
}, {});
export default cleanPermissions;

View File

@ -1,3 +1,4 @@
export { default as cleanPermissions } from './cleanPermissions';
export { default as getRequestURL } from './getRequestURL';
export { default as getTrad } from './getTrad';
export { default as formatPolicies } from './formatPolicies';

View File

@ -64,13 +64,14 @@ module.exports = {
async getPermissions(ctx) {
try {
const { lang } = ctx.query;
const plugins = await strapi.plugins[
'users-permissions'
].services.userspermissions.getPlugins(lang);
// @alexandrebodin I am removing this as it is not needed anymore
// const { lang } = ctx.query;
// const plugins = await strapi.plugins[
// 'users-permissions'
// ].services.userspermissions.getPlugins(lang);
const permissions = await strapi.plugins[
'users-permissions'
].services.userspermissions.getActions(plugins);
].services.userspermissions.getActions();
ctx.send({ permissions });
} catch (err) {