mirror of
https://github.com/strapi/strapi.git
synced 2025-12-28 23:57:32 +00:00
Add plugins and settings tabs
Signed-off-by: soupette <cyril.lpz@gmail.com>
This commit is contained in:
parent
b225028b0f
commit
7dbc795288
@ -1,11 +1,4 @@
|
||||
import React, {
|
||||
forwardRef,
|
||||
memo,
|
||||
useCallback,
|
||||
useImperativeHandle,
|
||||
useMemo,
|
||||
useReducer,
|
||||
} from 'react';
|
||||
import React, { forwardRef, memo, useCallback, useImperativeHandle, useReducer } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { Tabs } from '../../../../../../admin/src/components/Roles';
|
||||
import { roleTabsLabel as TAB_LABELS } from '../../../../../../admin/src/utils';
|
||||
@ -13,12 +6,13 @@ import { PermissionsDataManagerProvider } from '../contexts/PermissionsDataManag
|
||||
import ContentTypes from '../ContentTypes';
|
||||
import PluginsAndSettings from '../PluginsAndSettings';
|
||||
import layout from '../temp/fakeData';
|
||||
import formatLayoutForSettingsAndPlugins from './utils/formatLayoutForSettingsAndPlugins';
|
||||
import init from './init';
|
||||
import reducer, { initialState } from './reducer';
|
||||
|
||||
const Permissions = forwardRef(({ layout }, ref) => {
|
||||
const [{ modifiedData }, dispatch] = useReducer(reducer, initialState, () => init(layout));
|
||||
const [{ layouts, modifiedData }, dispatch] = useReducer(reducer, initialState, () =>
|
||||
init(layout)
|
||||
);
|
||||
|
||||
useImperativeHandle(ref, () => {
|
||||
return {
|
||||
@ -71,14 +65,6 @@ const Permissions = forwardRef(({ layout }, ref) => {
|
||||
});
|
||||
}, []);
|
||||
|
||||
const pluginsSectionLayout = useMemo(() => {
|
||||
return formatLayoutForSettingsAndPlugins(layout.sections.plugins, 'plugin');
|
||||
}, [layout.sections.plugins]);
|
||||
|
||||
const settingsSectionLayout = useMemo(() => {
|
||||
return formatLayoutForSettingsAndPlugins(layout.sections.settings, 'category');
|
||||
}, [layout.sections.settings]);
|
||||
|
||||
return (
|
||||
<PermissionsDataManagerProvider
|
||||
value={{
|
||||
@ -90,10 +76,10 @@ const Permissions = forwardRef(({ layout }, ref) => {
|
||||
}}
|
||||
>
|
||||
<Tabs tabsLabel={TAB_LABELS}>
|
||||
<ContentTypes layout={layout.sections.collectionTypes} kind="collectionTypes" />
|
||||
<ContentTypes layout={layout.sections.singleTypes} kind="singleTypes" />
|
||||
<PluginsAndSettings layout={pluginsSectionLayout} kind="plugins" />
|
||||
<PluginsAndSettings layout={settingsSectionLayout} kind="settings" />
|
||||
<ContentTypes layout={layouts.collectionTypes} kind="collectionTypes" />
|
||||
<ContentTypes layout={layouts.singleTypes} kind="singleTypes" />
|
||||
<PluginsAndSettings layout={layouts.plugins} kind="plugins" />
|
||||
<PluginsAndSettings layout={layouts.settings} kind="settings" />
|
||||
</Tabs>
|
||||
</PermissionsDataManagerProvider>
|
||||
);
|
||||
|
||||
@ -1,11 +1,33 @@
|
||||
import createDefaultForm from './utils/createdDefaultForm';
|
||||
import createDefaultCTFormFromLayout from './utils/createDefaultCTFormFromLayout';
|
||||
import createDefaultPluginsFormFromLayout from './utils/createDefaultPluginsFormFromLayout';
|
||||
import formatLayoutForSettingsAndPlugins from './utils/formatLayoutForSettingsAndPlugins';
|
||||
|
||||
const init = layout => {
|
||||
const defaultForm = createDefaultForm(layout);
|
||||
const {
|
||||
conditions,
|
||||
sections: { collectionTypes, singleTypes, plugins, settings },
|
||||
} = layout;
|
||||
const layouts = {
|
||||
collectionTypes,
|
||||
singleTypes,
|
||||
plugins: formatLayoutForSettingsAndPlugins(plugins, 'plugin'),
|
||||
settings: formatLayoutForSettingsAndPlugins(settings, 'category'),
|
||||
};
|
||||
const defaultForm = {
|
||||
collectionTypes: createDefaultCTFormFromLayout(
|
||||
collectionTypes,
|
||||
collectionTypes.actions || [],
|
||||
conditions
|
||||
),
|
||||
singleTypes: createDefaultCTFormFromLayout(singleTypes, singleTypes.actions || [], conditions),
|
||||
plugins: createDefaultPluginsFormFromLayout(layouts.plugins, conditions),
|
||||
settings: createDefaultPluginsFormFromLayout(layouts.settings, conditions),
|
||||
};
|
||||
|
||||
return {
|
||||
initialData: defaultForm,
|
||||
modifiedData: defaultForm,
|
||||
layouts,
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@ -5,6 +5,7 @@ import updateValues from './utils/updateValues';
|
||||
const initialState = {
|
||||
initialData: {},
|
||||
modifiedData: {},
|
||||
layouts: {},
|
||||
};
|
||||
|
||||
/* eslint-disable consistent-return */
|
||||
|
||||
@ -0,0 +1,31 @@
|
||||
import { createDefaultConditionsForm } from './createDefaultCTFormFromLayout';
|
||||
|
||||
const createSubCategoryForm = (actions, conditions) => {
|
||||
return actions.reduce((acc, current) => {
|
||||
acc[current.action] = {
|
||||
enabled: false,
|
||||
conditions: createDefaultConditionsForm(conditions),
|
||||
};
|
||||
|
||||
return acc;
|
||||
}, {});
|
||||
};
|
||||
|
||||
const createChildrenDefaultForm = (childrenForm, conditions) => {
|
||||
return childrenForm.reduce((acc, current) => {
|
||||
acc[current.subCategoryId] = createSubCategoryForm(current.actions, conditions);
|
||||
|
||||
return acc;
|
||||
}, {});
|
||||
};
|
||||
|
||||
const createDefaultPluginsFormFromLayout = (pluginsLayout, conditions) => {
|
||||
return pluginsLayout.reduce((acc, { categoryId, childrenForm }) => {
|
||||
const childrenDefaultForm = createChildrenDefaultForm(childrenForm, conditions);
|
||||
acc[categoryId] = childrenDefaultForm;
|
||||
|
||||
return acc;
|
||||
}, {});
|
||||
};
|
||||
|
||||
export default createDefaultPluginsFormFromLayout;
|
||||
@ -1,14 +0,0 @@
|
||||
import createDefaultCTFormFromLayout from './createDefaultCTFormFromLayout';
|
||||
|
||||
const createDefaultForm = ({ conditions, sections: { collectionTypes, singleTypes } }) => {
|
||||
return {
|
||||
collectionTypes: createDefaultCTFormFromLayout(
|
||||
collectionTypes,
|
||||
collectionTypes.actions || [],
|
||||
conditions
|
||||
),
|
||||
singleTypes: createDefaultCTFormFromLayout(singleTypes, singleTypes.actions || [], conditions),
|
||||
};
|
||||
};
|
||||
|
||||
export default createDefaultForm;
|
||||
@ -1,13 +1,20 @@
|
||||
import { chain } from 'lodash';
|
||||
|
||||
const replaceName = name => name.split(' ').join('-');
|
||||
|
||||
const formatLayout = (layout, groupByKey) => {
|
||||
return chain(layout)
|
||||
.groupBy(groupByKey)
|
||||
.map((item, itemName) => ({
|
||||
category: itemName,
|
||||
categoryId: replaceName(itemName),
|
||||
childrenForm: chain(item)
|
||||
.groupBy('subCategory')
|
||||
.map((actions, subCategoryName) => ({ subCategoryName, actions }))
|
||||
.map((actions, subCategoryName) => ({
|
||||
subCategoryName,
|
||||
subCategoryId: replaceName(subCategoryName),
|
||||
actions,
|
||||
}))
|
||||
.value(),
|
||||
}))
|
||||
.value();
|
||||
|
||||
@ -8,7 +8,15 @@ import { useIntl } from 'react-intl';
|
||||
import SubCategory from '../SubCategory';
|
||||
import RowStyle from './Wrapper';
|
||||
|
||||
const PermissionRow = ({ childrenForm, kind, name, isOpen, isWhite, onOpenCategory }) => {
|
||||
const PermissionRow = ({
|
||||
childrenForm,
|
||||
kind,
|
||||
name,
|
||||
isOpen,
|
||||
isWhite,
|
||||
onOpenCategory,
|
||||
pathToData,
|
||||
}) => {
|
||||
const { formatMessage } = useIntl();
|
||||
|
||||
const handleClick = () => {
|
||||
@ -23,12 +31,7 @@ const PermissionRow = ({ childrenForm, kind, name, isOpen, isWhite, onOpenCatego
|
||||
|
||||
return (
|
||||
<RowContainer isWhite={isWhite}>
|
||||
<RowStyle
|
||||
isWhite={isWhite}
|
||||
isActive={isOpen}
|
||||
// key={permissions.category}
|
||||
onClick={handleClick}
|
||||
>
|
||||
<RowStyle isWhite={isWhite} isActive={isOpen} onClick={handleClick}>
|
||||
<Flex alignItems="center" justifyContent="space-between">
|
||||
<div>
|
||||
<Text color="grey" fontWeight="bold" fontSize="xs" textTransform="uppercase">
|
||||
@ -47,8 +50,13 @@ const PermissionRow = ({ childrenForm, kind, name, isOpen, isWhite, onOpenCatego
|
||||
|
||||
{isOpen && (
|
||||
<PermissionsWrapper isWhite={isWhite}>
|
||||
{childrenForm.map(({ actions, subCategoryName }) => (
|
||||
<SubCategory categoryName={subCategoryName} key={subCategoryName} actions={actions} />
|
||||
{childrenForm.map(({ actions, subCategoryName, subCategoryId }) => (
|
||||
<SubCategory
|
||||
categoryName={subCategoryName}
|
||||
key={subCategoryName}
|
||||
actions={actions}
|
||||
pathToData={[...pathToData, subCategoryId]}
|
||||
/>
|
||||
))}
|
||||
</PermissionsWrapper>
|
||||
)}
|
||||
@ -65,6 +73,7 @@ PermissionRow.propTypes = {
|
||||
kind: PropTypes.string.isRequired,
|
||||
name: PropTypes.string.isRequired,
|
||||
onOpenCategory: PropTypes.func.isRequired,
|
||||
pathToData: PropTypes.array.isRequired,
|
||||
};
|
||||
|
||||
export default PermissionRow;
|
||||
|
||||
@ -1,9 +1,12 @@
|
||||
import React from 'react';
|
||||
import React, { useMemo } from 'react';
|
||||
import styled from 'styled-components';
|
||||
import PropTypes from 'prop-types';
|
||||
import { Flex, Padded, Text, Checkbox } from '@buffetjs/core';
|
||||
import { useIntl } from 'react-intl';
|
||||
import { BaselineAlignment } from 'strapi-helper-plugin';
|
||||
import { get } from 'lodash';
|
||||
import { usePermissionsDataManager } from '../../contexts/PermissionsDataManagerContext';
|
||||
import { getCheckboxState, removeConditionKeyFromData } from '../../utils';
|
||||
import ConditionsButton from '../../ConditionsButton';
|
||||
import CheckboxWrapper from './CheckboxWrapper';
|
||||
import Wrapper from './Wrapper';
|
||||
@ -16,9 +19,25 @@ const Border = styled.div`
|
||||
padding: 0px 10px;
|
||||
`;
|
||||
|
||||
const SubCategory = ({ categoryName, actions }) => {
|
||||
const SubCategory = ({ categoryName, actions, pathToData }) => {
|
||||
const {
|
||||
modifiedData,
|
||||
onChangeParentCheckbox,
|
||||
onChangeSimpleCheckbox,
|
||||
} = usePermissionsDataManager();
|
||||
const { formatMessage } = useIntl();
|
||||
|
||||
const mainData = get(modifiedData, pathToData, {});
|
||||
const dataWithoutCondition = useMemo(() => {
|
||||
return Object.keys(mainData).reduce((acc, current) => {
|
||||
acc[current] = removeConditionKeyFromData(mainData[current]);
|
||||
|
||||
return acc;
|
||||
}, {});
|
||||
}, [mainData]);
|
||||
|
||||
const { hasAllActionsSelected, hasSomeActionsSelected } = getCheckboxState(dataWithoutCondition);
|
||||
|
||||
return (
|
||||
<>
|
||||
<Wrapper>
|
||||
@ -38,31 +57,36 @@ const SubCategory = ({ categoryName, actions }) => {
|
||||
<Padded left size="sm">
|
||||
<BaselineAlignment top size="1px" />
|
||||
<Checkbox
|
||||
// name={`select-all-${categoryName}`}
|
||||
name="todo"
|
||||
name={pathToData.join('..')}
|
||||
message={formatMessage({ id: 'app.utils.select-all' })}
|
||||
disabled
|
||||
onChange={() => {}}
|
||||
someChecked={false}
|
||||
value={false}
|
||||
// TODO
|
||||
disabled={false}
|
||||
onChange={onChangeParentCheckbox}
|
||||
someChecked={hasSomeActionsSelected}
|
||||
value={hasAllActionsSelected}
|
||||
/>
|
||||
</Padded>
|
||||
</Flex>
|
||||
<BaselineAlignment top size="1px" />
|
||||
<Padded top size="xs">
|
||||
<Flex flexWrap="wrap">
|
||||
{actions.map(sc => (
|
||||
<CheckboxWrapper disabled hasConditions={false} key={sc.action}>
|
||||
<Checkbox
|
||||
value={false}
|
||||
name="todo"
|
||||
// TODO
|
||||
disabled={false}
|
||||
message={sc.displayName}
|
||||
onChange={() => {}}
|
||||
/>
|
||||
</CheckboxWrapper>
|
||||
))}
|
||||
{actions.map(sc => {
|
||||
const checkboxName = [...pathToData, sc.action, 'enabled'];
|
||||
const value = get(modifiedData, checkboxName, false);
|
||||
|
||||
return (
|
||||
<CheckboxWrapper disabled hasConditions={false} key={sc.action}>
|
||||
<Checkbox
|
||||
name={checkboxName.join('..')}
|
||||
// TODO
|
||||
disabled={false}
|
||||
message={sc.displayName}
|
||||
onChange={onChangeSimpleCheckbox}
|
||||
value={value}
|
||||
/>
|
||||
</CheckboxWrapper>
|
||||
);
|
||||
})}
|
||||
</Flex>
|
||||
<ConditionsButtonWrapper disabled={false} hasConditions={false}>
|
||||
<ConditionsButton hasConditions={false} onClick={() => {}} />
|
||||
@ -74,8 +98,9 @@ const SubCategory = ({ categoryName, actions }) => {
|
||||
};
|
||||
|
||||
SubCategory.propTypes = {
|
||||
categoryName: PropTypes.string.isRequired,
|
||||
actions: PropTypes.array.isRequired,
|
||||
categoryName: PropTypes.string.isRequired,
|
||||
pathToData: PropTypes.array.isRequired,
|
||||
};
|
||||
|
||||
export default SubCategory;
|
||||
|
||||
@ -14,10 +14,7 @@ const PluginsAndSettingsPermissions = ({ kind, layout }) => {
|
||||
return (
|
||||
<ListWrapper>
|
||||
<Padded left right size="md">
|
||||
{layout.map(({ category, childrenForm }, index) => {
|
||||
// console.log({ permissionLayout });
|
||||
console.log({ category, childrenForm });
|
||||
|
||||
{layout.map(({ category, categoryId, childrenForm }, index) => {
|
||||
return (
|
||||
<PermissionRow
|
||||
key={category}
|
||||
@ -27,7 +24,7 @@ const PluginsAndSettingsPermissions = ({ kind, layout }) => {
|
||||
isWhite={index % 2 === 1}
|
||||
name={category}
|
||||
onOpenCategory={handleOpenCategory}
|
||||
// permissions={permissionLayout}
|
||||
pathToData={[kind, categoryId]}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
@ -41,6 +38,7 @@ PluginsAndSettingsPermissions.propTypes = {
|
||||
layout: PropTypes.arrayOf(
|
||||
PropTypes.shape({
|
||||
category: PropTypes.string.isRequired,
|
||||
categoryId: PropTypes.string.isRequired,
|
||||
childrenForm: PropTypes.arrayOf(
|
||||
PropTypes.shape({
|
||||
actions: PropTypes.array.isRequired,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user