diff --git a/packages/core/admin/admin/src/components/Roles/RoleRow/index.js b/packages/core/admin/admin/src/components/Roles/RoleRow/index.js
index 9bf509be55..d5044716f4 100644
--- a/packages/core/admin/admin/src/components/Roles/RoleRow/index.js
+++ b/packages/core/admin/admin/src/components/Roles/RoleRow/index.js
@@ -1,9 +1,9 @@
-import { Box, Row, Td, Text, Tr, IconButton, BaseCheckbox } from '@strapi/parts';
+import { Box, Row, Td, Text, Tr, IconButton } from '@strapi/parts';
import PropTypes from 'prop-types';
import React from 'react';
import { useIntl } from 'react-intl';
-const RoleRow = ({ onToggle, id, name, description, usersCount, isChecked, icons }) => {
+const RoleRow = ({ id, name, description, usersCount, icons }) => {
const { formatMessage } = useIntl();
const usersCountText = formatMessage(
@@ -16,19 +16,6 @@ const RoleRow = ({ onToggle, id, name, description, usersCount, isChecked, icons
return (
- {Boolean(onToggle) && (
-
- onToggle(id)}
- value={isChecked}
- aria-label={formatMessage(
- { id: `Roles.RoleRow.select-all`, defaultMessage: 'Select {name} for bulk actions' },
- { name }
- )}
- />
- |
- )}
{name}
|
@@ -53,19 +40,12 @@ const RoleRow = ({ onToggle, id, name, description, usersCount, isChecked, icons
);
};
-RoleRow.defaultProps = {
- onToggle: undefined,
- isChecked: undefined,
-};
-
RoleRow.propTypes = {
id: PropTypes.number.isRequired,
name: PropTypes.string.isRequired,
description: PropTypes.string.isRequired,
usersCount: PropTypes.number.isRequired,
icons: PropTypes.array.isRequired,
- onToggle: PropTypes.func,
- isChecked: PropTypes.bool,
};
export default RoleRow;
diff --git a/packages/core/admin/admin/src/hooks/useRolesList/index.js b/packages/core/admin/admin/src/hooks/useRolesList/index.js
index 5ace36a7e8..a96cc913fd 100644
--- a/packages/core/admin/admin/src/hooks/useRolesList/index.js
+++ b/packages/core/admin/admin/src/hooks/useRolesList/index.js
@@ -1,6 +1,7 @@
import { useEffect, useReducer, useCallback } from 'react';
-import { request, useNotification } from '@strapi/helper-plugin';
-import { get } from 'lodash';
+import { useNotification } from '@strapi/helper-plugin';
+import get from 'lodash/get';
+import { axiosInstance } from '../../core/utils';
import init from './init';
import reducer, { initialState } from './reducer';
@@ -23,7 +24,9 @@ const useRolesList = (shouldFetchData = true) => {
type: 'GET_DATA',
});
- const { data } = await request('/admin/roles', { method: 'GET' });
+ const {
+ data: { data },
+ } = await axiosInstance.get('/admin/roles');
dispatch({
type: 'GET_DATA_SUCCEEDED',
diff --git a/packages/core/admin/admin/src/pages/Users/ListPage/index.js b/packages/core/admin/admin/src/pages/Users/ListPage/index.js
index 29e6801671..547f1c4fac 100644
--- a/packages/core/admin/admin/src/pages/Users/ListPage/index.js
+++ b/packages/core/admin/admin/src/pages/Users/ListPage/index.js
@@ -1,8 +1,9 @@
import React from 'react';
import {
CustomContentLayout,
- useRBAC,
+ Search,
SettingsPageTitle,
+ useRBAC,
useNotification,
useFocusWhenNavigate,
} from '@strapi/helper-plugin';
@@ -15,7 +16,6 @@ import get from 'lodash/get';
import adminPermissions from '../../../permissions';
import DynamicTable from './DynamicTable';
import Filters from './Filters';
-import Search from './Search';
import PaginationFooter from './PaginationFooter';
import { deleteData, fetchData } from './utils/api';
import displayedFilters from './utils/displayedFilters';
diff --git a/packages/core/admin/admin/src/pages/Users/ListPage/tests/index.test.js b/packages/core/admin/admin/src/pages/Users/ListPage/tests/index.test.js
index 132fa139d4..a62b8723f6 100644
--- a/packages/core/admin/admin/src/pages/Users/ListPage/tests/index.test.js
+++ b/packages/core/admin/admin/src/pages/Users/ListPage/tests/index.test.js
@@ -699,46 +699,6 @@ describe('ADMIN | Pages | USERS | ListPage', () => {
height: 0.25rem;
}
- .c13 {
- padding-right: 56px;
- padding-left: 56px;
- }
-
- .c36 tr:last-of-type {
- border-bottom: none;
- }
-
- .c37 {
- border-bottom: 1px solid #eaeaef;
- }
-
- .c37 td,
- .c37 th {
- padding: 16px;
- }
-
- .c37 td:first-of-type,
- .c37 th:first-of-type {
- padding: 0 4px;
- }
-
- .c38 {
- vertical-align: middle;
- text-align: left;
- color: #666687;
- outline-offset: -4px;
- }
-
- .c38 input {
- vertical-align: sub;
- }
-
- .c34 {
- -webkit-transform: rotate(0deg);
- -ms-transform: rotate(0deg);
- transform: rotate(0deg);
- }
-
.c15 {
display: -webkit-box;
display: -webkit-flex;
@@ -788,6 +748,46 @@ describe('ADMIN | Pages | USERS | ListPage', () => {
fill: #666687;
}
+ .c13 {
+ padding-right: 56px;
+ padding-left: 56px;
+ }
+
+ .c36 tr:last-of-type {
+ border-bottom: none;
+ }
+
+ .c37 {
+ border-bottom: 1px solid #eaeaef;
+ }
+
+ .c37 td,
+ .c37 th {
+ padding: 16px;
+ }
+
+ .c37 td:first-of-type,
+ .c37 th:first-of-type {
+ padding: 0 4px;
+ }
+
+ .c38 {
+ vertical-align: middle;
+ text-align: left;
+ color: #666687;
+ outline-offset: -4px;
+ }
+
+ .c38 input {
+ vertical-align: sub;
+ }
+
+ .c34 {
+ -webkit-transform: rotate(0deg);
+ -ms-transform: rotate(0deg);
+ transform: rotate(0deg);
+ }
+
{
} = useRBAC(adminPermissions.settings.roles);
const { getData, roles, isLoading } = useRolesList(false);
- const query = useQuery();
- const _q = decodeURIComponent(query.get('_q') || '');
+ const [{ query }] = useQueryParams();
+ const _q = query?._q || '';
const sortedRoles = matchSorter(roles, _q, { keys: ['name', 'description'] });
useEffect(() => {
@@ -63,62 +64,33 @@ const useSortedRoles = () => {
};
};
-const useRoleActions = ({ getData, canCreate, canDelete, canUpdate, roles, sortedRoles }) => {
+const useRoleActions = ({ getData, canCreate, canDelete, canUpdate }) => {
const { formatMessage } = useIntl();
const toggleNotification = useNotification();
const [isWarningDeleteAllOpened, setIsWarningDeleteAllOpenend] = useState(false);
const { push } = useHistory();
- const [
- { selectedRoles, showModalConfirmButtonLoading, shouldRefetchData },
- dispatch,
- ] = useReducer(reducer, initialState);
+ const [{ selectedRoles, showModalConfirmButtonLoading, roleToDelete }, dispatch] = useReducer(
+ reducer,
+ initialState
+ );
- const handleClosedModal = () => {
- if (shouldRefetchData) {
- getData();
- }
-
- // Empty the selected ids when the modal closes
- dispatch({
- type: 'RESET_DATA_TO_DELETE',
- });
- };
-
- const handleConfirmDeleteData = async () => {
+ const handleDeleteData = async () => {
try {
dispatch({
type: 'ON_REMOVE_ROLES',
});
- const filteredRoles = selectedRoles.filter(currentId => {
- const currentRole = roles.find(role => role.id === currentId);
- return currentRole.usersCount === 0;
+ await axiosInstance.post('/admin/roles/batch-delete', {
+ ids: [roleToDelete],
});
- if (selectedRoles.length !== filteredRoles.length) {
- toggleNotification({
- type: 'info',
- message: { id: 'Roles.ListPage.notification.delete-all-not-allowed' },
- });
- }
+ await getData();
- if (filteredRoles.length) {
- await request('/admin/roles/batch-delete', {
- method: 'POST',
- body: {
- ids: filteredRoles,
- },
- });
-
- // Empty the selectedRolesId and set the shouldRefetchData to true so the
- // list is updated when closing the modal
- dispatch({
- type: 'ON_REMOVE_ROLES_SUCCEEDED',
- });
- }
+ dispatch({
+ type: 'RESET_DATA_TO_DELETE',
+ });
} catch (err) {
- console.error(err);
const errorIds = get(err, ['response', 'payload', 'data', 'ids'], null);
if (errorIds && Array.isArray(errorIds)) {
@@ -133,9 +105,8 @@ const useRoleActions = ({ getData, canCreate, canDelete, canUpdate, roles, sorte
message: { id: 'notification.error' },
});
}
- } finally {
- handleToggleModal();
}
+ handleToggleModal();
};
const onRoleDuplicate = useCallback(
@@ -156,19 +127,6 @@ const useRoleActions = ({ getData, canCreate, canDelete, canUpdate, roles, sorte
handleToggleModal();
}, []);
- const onRoleToggle = roleId => {
- dispatch({
- type: 'ON_SELECTION',
- id: roleId,
- });
- };
-
- const onAllRolesToggle = () =>
- dispatch({
- type: 'TOGGLE_ALL',
- ids: sortedRoles.map(r => r.id),
- });
-
const handleToggleModal = () => setIsWarningDeleteAllOpenend(prev => !prev);
const handleGoTo = useCallback(
@@ -246,16 +204,13 @@ const useRoleActions = ({ getData, canCreate, canDelete, canUpdate, roles, sorte
);
return {
- handleClosedModal,
- handleConfirmDeleteData,
handleNewRoleClick,
- onRoleToggle,
- onAllRolesToggle,
getIcons,
selectedRoles,
isWarningDeleteAllOpened,
showModalConfirmButtonLoading,
handleToggleModal,
+ handleDeleteData,
};
};
@@ -271,21 +226,16 @@ const RoleListPage = () => {
isLoading,
getData,
sortedRoles,
- roles,
} = useSortedRoles();
const {
- handleClosedModal,
- handleConfirmDeleteData,
handleNewRoleClick,
- onRoleToggle,
- onAllRolesToggle,
getIcons,
- selectedRoles,
isWarningDeleteAllOpened,
showModalConfirmButtonLoading,
handleToggleModal,
- } = useRoleActions({ getData, canCreate, canDelete, canUpdate, roles, sortedRoles });
+ handleDeleteData,
+ } = useRoleActions({ getData, canCreate, canDelete, canUpdate });
// ! TODO - Show the search bar only if the user is allowed to read - add the search input
// canRead
@@ -293,11 +243,6 @@ const RoleListPage = () => {
const rowCount = sortedRoles.length + 1;
const colCount = 6;
- const isAllEntriesIndeterminate = selectedRoles.length
- ? selectedRoles.length !== rowCount
- : false;
- const isAllChecked = selectedRoles.length ? selectedRoles.length === rowCount : false;
-
if (isLoadingForPermissions) {
return ;
}
@@ -327,6 +272,7 @@ const RoleListPage = () => {
})}
as="h2"
/>
+ {canRead && } />}
{canRead && (
{
>
- {!!onRoleToggle && (
-
-
- |
- )}
{formatMessage({
@@ -394,10 +330,6 @@ const RoleListPage = () => {
selectedRoleId === role.id) !== -1
- }
name={role.name}
description={role.description}
usersCount={role.usersCount}
@@ -409,12 +341,11 @@ const RoleListPage = () => {
{!rowCount && !isLoading && }
)}
-
);
diff --git a/packages/core/admin/ee/admin/pages/Roles/ListPage/reducer.js b/packages/core/admin/ee/admin/pages/Roles/ListPage/reducer.js
index 8b7e07b04c..5295d92757 100644
--- a/packages/core/admin/ee/admin/pages/Roles/ListPage/reducer.js
+++ b/packages/core/admin/ee/admin/pages/Roles/ListPage/reducer.js
@@ -2,7 +2,7 @@
import produce from 'immer';
export const initialState = {
- selectedRoles: [],
+ roleToDelete: null,
showModalConfirmButtonLoading: false,
shouldRefetchData: false,
};
@@ -10,57 +10,26 @@ export const initialState = {
const reducer = (state, action) =>
produce(state, draftState => {
switch (action.type) {
- case 'ON_SELECTION': {
- const { id } = action;
- const roleIndex = state.selectedRoles.findIndex(roleId => roleId === id);
-
- if (roleIndex === -1) {
- draftState.selectedRoles.push(id);
- } else {
- draftState.selectedRoles = state.selectedRoles.filter(roleId => roleId !== id);
- }
- break;
- }
- case 'TOGGLE_ALL': {
- if (state.selectedRoles.length) {
- draftState.selectedRoles = [];
- } else {
- const { ids } = action;
- draftState.selectedRoles = ids;
- }
- break;
- }
case 'ON_REMOVE_ROLES': {
draftState.showModalConfirmButtonLoading = true;
break;
}
case 'ON_REMOVE_ROLES_SUCCEEDED': {
draftState.shouldRefetchData = true;
+ draftState.roleToDelete = null;
break;
}
case 'RESET_DATA_TO_DELETE': {
draftState.shouldRefetchData = false;
- draftState.selectedRoles = [];
+ draftState.roleToDelete = null;
draftState.showModalConfirmButtonLoading = false;
break;
}
case 'SET_ROLE_TO_DELETE': {
- draftState.selectedRoles = [action.id];
+ draftState.roleToDelete = action.id;
break;
}
- // Leaving this code for the moment
- // case 'ON_DUPLICATION': {
- // const { id } = action;
- // draftState.roles = state.roles.reduce((acc, c) => {
- // if (c.id === id) {
- // return acc.concat([c, { ...c, id: state.roles.length + 1 }]);
- // }
-
- // return [...acc, c];
- // }, []);
- // break;
- // }
default:
return draftState;
}
diff --git a/packages/core/admin/ee/admin/pages/Roles/ListPage/tests/reducer.test.js b/packages/core/admin/ee/admin/pages/Roles/ListPage/tests/reducer.test.js
index e72815f5ab..f16c8d422e 100644
--- a/packages/core/admin/ee/admin/pages/Roles/ListPage/tests/reducer.test.js
+++ b/packages/core/admin/ee/admin/pages/Roles/ListPage/tests/reducer.test.js
@@ -11,54 +11,18 @@ describe('ADMIN | ee | CONTAINERS | ROLES | ListPage | reducer', () => {
});
});
- describe('ON_SELECTION', () => {
- it('should add the selected role correctly', () => {
- const action = {
- type: 'ON_SELECTION',
- id: 2,
- };
- const initialState = {
- selectedRoles: [],
- shouldRefetchData: false,
- };
- const expected = {
- selectedRoles: [2],
- shouldRefetchData: false,
- };
-
- expect(reducer(initialState, action)).toEqual(expected);
- });
-
- it('should remove the selected role correctly', () => {
- const action = {
- type: 'ON_SELECTION',
- id: 2,
- };
- const initialState = {
- selectedRoles: [1, 2],
- shouldRefetchData: false,
- };
- const expected = {
- selectedRoles: [1],
- shouldRefetchData: false,
- };
-
- expect(reducer(initialState, action)).toEqual(expected);
- });
- });
-
describe('ON_REMOVE_ROLES', () => {
it('should set the showModalConfirmButtonLoading to true', () => {
const action = {
type: 'ON_REMOVE_ROLES',
};
const initialState = {
- selectedRoles: [],
+ roleToDelete: 1,
shouldRefetchData: false,
showModalConfirmButtonLoading: false,
};
const expected = {
- selectedRoles: [],
+ roleToDelete: 1,
shouldRefetchData: false,
showModalConfirmButtonLoading: true,
};
@@ -73,12 +37,12 @@ describe('ADMIN | ee | CONTAINERS | ROLES | ListPage | reducer', () => {
type: 'ON_REMOVE_ROLES_SUCCEEDED',
};
const initialState = {
- selectedRoles: [],
+ roleToDelete: 1,
shouldRefetchData: false,
showModalConfirmButtonLoading: true,
};
const expected = {
- selectedRoles: [],
+ roleToDelete: null,
shouldRefetchData: true,
showModalConfirmButtonLoading: true,
};
@@ -87,26 +51,6 @@ describe('ADMIN | ee | CONTAINERS | ROLES | ListPage | reducer', () => {
});
});
- describe('RESET_DATA_TO_DELETE', () => {
- it('should empty the selected role array and set the shouldRefetchData to false', () => {
- const action = {
- type: 'RESET_DATA_TO_DELETE',
- };
- const initialState = {
- selectedRoles: [1, 2, 4],
- shouldRefetchData: true,
- showModalConfirmButtonLoading: true,
- };
- const expected = {
- selectedRoles: [],
- shouldRefetchData: false,
- showModalConfirmButtonLoading: false,
- };
-
- expect(reducer(initialState, action)).toEqual(expected);
- });
- });
-
describe('SET_ROLE_TO_DELETE', () => {
it('should set the selected roles property correctly', () => {
const action = {
@@ -114,11 +58,11 @@ describe('ADMIN | ee | CONTAINERS | ROLES | ListPage | reducer', () => {
id: 6,
};
const initialState = {
- selectedRoles: [1, 2, 4],
+ roleToDelete: null,
shouldRefetchData: false,
};
const expected = {
- selectedRoles: [6],
+ roleToDelete: 6,
shouldRefetchData: false,
};
diff --git a/packages/core/admin/admin/src/pages/Users/ListPage/Search/index.js b/packages/core/helper-plugin/lib/src/components/Search/index.js
similarity index 90%
rename from packages/core/admin/admin/src/pages/Users/ListPage/Search/index.js
rename to packages/core/helper-plugin/lib/src/components/Search/index.js
index eafce8e68e..7c57241b80 100644
--- a/packages/core/admin/admin/src/pages/Users/ListPage/Search/index.js
+++ b/packages/core/helper-plugin/lib/src/components/Search/index.js
@@ -1,13 +1,13 @@
import React, { useEffect, useState } from 'react';
-import { useQueryParams } from '@strapi/helper-plugin';
import { SearchIcon } from '@strapi/icons';
import { IconButton } from '@strapi/parts/IconButton';
import { TextInput } from '@strapi/parts/TextInput';
+import useQueryParams from '../../hooks/useQueryParams';
const Search = () => {
const [isOpen, setIsOpen] = useState(false);
const [{ query }, setQuery] = useQueryParams();
- const [value, setValue] = useState(query._q || '');
+ const [value, setValue] = useState(query?._q || '');
useEffect(() => {
const handler = setTimeout(() => {
diff --git a/packages/core/helper-plugin/lib/src/index.js b/packages/core/helper-plugin/lib/src/index.js
index 2a6e9c3076..8a57bc9f39 100644
--- a/packages/core/helper-plugin/lib/src/index.js
+++ b/packages/core/helper-plugin/lib/src/index.js
@@ -179,6 +179,7 @@ export { default as EmptyBodyTable } from './components/EmptyBodyTable';
export * from './components/InjectionZone';
export { default as LoadingIndicatorPage } from './components/LoadingIndicatorPage';
export { default as SettingsPageTitle } from './components/SettingsPageTitle';
+export { default as Search } from './components/Search';
export { default as Status } from './components/Status';
// New icons
|