diff --git a/packages/strapi-admin/admin/src/containers/Admin/actions.js b/packages/strapi-admin/admin/src/containers/Admin/actions.js index 4539b60c14..cf9b93e291 100644 --- a/packages/strapi-admin/admin/src/containers/Admin/actions.js +++ b/packages/strapi-admin/admin/src/containers/Admin/actions.js @@ -4,12 +4,30 @@ * */ -import { GET_PLUGINS_FROM_MARKETPLACE_SUCCEEDED, SET_APP_ERROR } from './constants'; +import { + GET_USER_PERMISSIONS, + GET_USER_PERMISSIONS_ERROR, + GET_USER_PERMISSIONS_SUCCEEDED, + SET_APP_ERROR, +} from './constants'; -export function getPluginsFromMarketPlaceSucceeded(plugins) { +export function getUserPermissions() { return { - type: GET_PLUGINS_FROM_MARKETPLACE_SUCCEEDED, - plugins, + type: GET_USER_PERMISSIONS, + }; +} + +export function getUserPermissionsError(error) { + return { + type: GET_USER_PERMISSIONS_ERROR, + error, + }; +} + +export function getUserPermissionsSucceeded(data) { + return { + type: GET_USER_PERMISSIONS_SUCCEEDED, + data, }; } diff --git a/packages/strapi-admin/admin/src/containers/Admin/constants.js b/packages/strapi-admin/admin/src/containers/Admin/constants.js index a765ac5107..6d5dcb786b 100644 --- a/packages/strapi-admin/admin/src/containers/Admin/constants.js +++ b/packages/strapi-admin/admin/src/containers/Admin/constants.js @@ -4,6 +4,7 @@ * */ -export const GET_PLUGINS_FROM_MARKETPLACE_SUCCEEDED = - 'StrapiAdmin/Admin/GET_PLUGINS_FROM_MARKETPLACE_SUCCEEDED'; export const SET_APP_ERROR = 'StrapiAdmin/Admin/SET_APP_ERROR'; +export const GET_USER_PERMISSIONS = 'StrapiAdmin/Admin/GET_USER_PERMISSIONS'; +export const GET_USER_PERMISSIONS_ERROR = 'StrapiAdmin/Admin/GET_USER_PERMISSIONS_ERROR'; +export const GET_USER_PERMISSIONS_SUCCEEDED = 'StrapiAdmin/Admin/GET_USER_PERMISSIONS_SUCCEEDED'; diff --git a/packages/strapi-admin/admin/src/containers/Admin/index.js b/packages/strapi-admin/admin/src/containers/Admin/index.js index 890f80f7ac..028cf61040 100644 --- a/packages/strapi-admin/admin/src/containers/Admin/index.js +++ b/packages/strapi-admin/admin/src/containers/Admin/index.js @@ -45,7 +45,12 @@ import { updatePlugin, } from '../App/actions'; import makeSelecApp from '../App/selectors'; -import { setAppError } from './actions'; +import { + getUserPermissions, + getUserPermissionsError, + getUserPermissionsSucceeded, + setAppError, +} from './actions'; import makeSelectAdmin from './selectors'; import Wrapper from './Wrapper'; import Content from './Content'; @@ -62,6 +67,9 @@ export class Admin extends React.Component { componentDidMount() { this.emitEvent('didAccessAuthenticatedAdministration'); + // TODO: remove the user1 it is just for testing until + // Api is ready + this.fetchUserPermissions('user1', true); } shouldComponentUpdate(prevProps) { @@ -100,6 +108,28 @@ export class Admin extends React.Component { } }; + fetchUserPermissions = async (user = 'user1', resetState = false) => { + const { getUserPermissions, getUserPermissionsError, getUserPermissionsSucceeded } = this.props; + + if (resetState) { + // Show a loader + getUserPermissions(); + } + + try { + const data = await new Promise(resolve => + setTimeout(() => { + resolve(fakePermissionsData[user]); + }, 2000) + ); + + getUserPermissionsSucceeded(data); + } catch (err) { + console.error(err); + getUserPermissionsError(err); + } + }; + hasApluginNotReady = props => { const { global: { plugins }, @@ -144,6 +174,7 @@ export class Admin extends React.Component { render() { const { + admin: { isLoading, userPermissions }, global: { autoReload, blockApp, @@ -169,6 +200,13 @@ export class Admin extends React.Component { ); } + // Show a loader while permissions are being fetched + // TODO: we might need to improve this behavior for the ctb + // since we will need to update the permissions + if (isLoading) { + return ; + } + return ( - + @@ -243,9 +282,14 @@ Admin.defaultProps = { Admin.propTypes = { admin: PropTypes.shape({ appError: PropTypes.bool, + isLoading: PropTypes.bool, + userPermissions: PropTypes.array, }).isRequired, disableGlobalOverlayBlocker: PropTypes.func.isRequired, enableGlobalOverlayBlocker: PropTypes.func.isRequired, + getUserPermissions: PropTypes.func.isRequired, + getUserPermissionsError: PropTypes.func.isRequired, + getUserPermissionsSucceeded: PropTypes.func.isRequired, global: PropTypes.shape({ autoReload: PropTypes.bool, blockApp: PropTypes.bool, @@ -275,6 +319,9 @@ export function mapDispatchToProps(dispatch) { { disableGlobalOverlayBlocker, enableGlobalOverlayBlocker, + getUserPermissions, + getUserPermissionsError, + getUserPermissionsSucceeded, setAppError, updatePlugin, }, diff --git a/packages/strapi-admin/admin/src/containers/Admin/reducer.js b/packages/strapi-admin/admin/src/containers/Admin/reducer.js index b5065f0fe0..8494d2054e 100644 --- a/packages/strapi-admin/admin/src/containers/Admin/reducer.js +++ b/packages/strapi-admin/admin/src/containers/Admin/reducer.js @@ -4,23 +4,48 @@ * */ -import { fromJS } from 'immutable'; -import { GET_PLUGINS_FROM_MARKETPLACE_SUCCEEDED, SET_APP_ERROR } from './constants'; +import produce from 'immer'; -const initialState = fromJS({ +import { + GET_USER_PERMISSIONS, + GET_USER_PERMISSIONS_ERROR, + GET_USER_PERMISSIONS_SUCCEEDED, + SET_APP_ERROR, +} from './constants'; + +const initialState = { appError: false, - pluginsFromMarketplace: [], -}); + isLoading: true, + userPermissions: [], +}; -function adminReducer(state = initialState, action) { - switch (action.type) { - case GET_PLUGINS_FROM_MARKETPLACE_SUCCEEDED: - return state.update('pluginsFromMarketplace', () => fromJS(action.plugins)); - case SET_APP_ERROR: - return state.update('appError', () => true); - default: - return state; - } -} +const reducer = (state = initialState, action) => + // eslint-disable-next-line consistent-return + produce(state, draftState => { + switch (action.type) { + case GET_USER_PERMISSIONS: { + draftState.isLoading = true; + break; + } -export default adminReducer; + case GET_USER_PERMISSIONS_ERROR: { + draftState.error = action.error; + draftState.isLoading = false; + break; + } + case GET_USER_PERMISSIONS_SUCCEEDED: { + draftState.isLoading = false; + draftState.userPermissions = action.data; + break; + } + case SET_APP_ERROR: { + draftState.appError = true; + break; + } + default: + return state; + } + }); + +export default reducer; +export { initialState }; diff --git a/packages/strapi-admin/admin/src/containers/Admin/selectors.js b/packages/strapi-admin/admin/src/containers/Admin/selectors.js index 47e60260fa..f2781dcde6 100644 --- a/packages/strapi-admin/admin/src/containers/Admin/selectors.js +++ b/packages/strapi-admin/admin/src/containers/Admin/selectors.js @@ -1,9 +1,12 @@ import { createSelector } from 'reselect'; +import { initialState } from './reducer'; /** * Direct selector to the admin state domain */ -const selectAdminDomain = () => state => state.get('admin'); +const selectAdminDomain = () => state => { + return state.get('admin') || initialState; +}; /** * Other specific selectors @@ -13,12 +16,7 @@ const selectAdminDomain = () => state => state.get('admin'); * Default selector used by Admin */ -const makeSelectAdmin = () => createSelector(selectAdminDomain(), substate => substate.toJS()); - -const makeSelectPluginsFromMarketplace = () => - createSelector(selectAdminDomain(), substate => substate.get('pluginsFromMarketplace').toJS()); - -const makeSelectUuid = () => createSelector(selectAdminDomain(), substate => substate.get('uuid')); +const makeSelectAdmin = () => createSelector(selectAdminDomain(), substate => substate); export default makeSelectAdmin; -export { makeSelectUuid, selectAdminDomain, makeSelectPluginsFromMarketplace }; +export { selectAdminDomain }; diff --git a/packages/strapi-admin/admin/src/containers/Admin/tests/index.test.js b/packages/strapi-admin/admin/src/containers/Admin/tests/index.test.js index 107a3d93ba..c781d2774a 100644 --- a/packages/strapi-admin/admin/src/containers/Admin/tests/index.test.js +++ b/packages/strapi-admin/admin/src/containers/Admin/tests/index.test.js @@ -22,6 +22,9 @@ describe('', () => { disableGlobalOverlayBlocker: jest.fn(), emitEvent: jest.fn(), enableGlobalOverlayBlocker: jest.fn(), + getUserPermissions: jest.fn(), + getUserPermissionsError: jest.fn(), + getUserPermissionsSucceeded: jest.fn(), global: { autoReload: false, blockApp: false, diff --git a/packages/strapi-admin/admin/src/containers/Admin/tests/reducer.test.js b/packages/strapi-admin/admin/src/containers/Admin/tests/reducer.test.js index 36022ac3c7..cba1568f16 100644 --- a/packages/strapi-admin/admin/src/containers/Admin/tests/reducer.test.js +++ b/packages/strapi-admin/admin/src/containers/Admin/tests/reducer.test.js @@ -1,16 +1,21 @@ -import { fromJS } from 'immutable'; - -import { setAppError } from '../actions'; +import produce from 'immer'; +import { + setAppError, + getUserPermissions, + getUserPermissionsError, + getUserPermissionsSucceeded, +} from '../actions'; import adminReducer from '../reducer'; describe('adminReducer', () => { let state; beforeEach(() => { - state = fromJS({ + state = { appError: false, - pluginsFromMarketplace: [], - }); + isLoading: true, + userPermissions: [], + }; }); it('returns the initial state', () => { @@ -19,9 +24,39 @@ describe('adminReducer', () => { expect(adminReducer(undefined, {})).toEqual(expected); }); - it('should handle the setaAppError action correctly', () => { - const expected = state.set('appError', true); + it('should handle the setAppError action correctly', () => { + const expected = produce(state, draft => { + draft.appError = true; + }); expect(adminReducer(state, setAppError())).toEqual(expected); }); + + it('should handle the getUserPermissions action correctly', () => { + const expected = produce(state, draft => { + draft.isLoading = true; + }); + + expect(adminReducer(state, getUserPermissions())).toEqual(expected); + }); + + it('should handle the getUserPermissionsError action correctly', () => { + const error = 'Error'; + const expected = produce(state, draft => { + draft.isLoading = false; + draft.error = error; + }); + + expect(adminReducer(state, getUserPermissionsError(error))).toEqual(expected); + }); + + it('should handle the getUserPermissionsSucceeded action correctly', () => { + const data = ['permission 1', 'permission 2']; + const expected = produce(state, draft => { + draft.isLoading = false; + draft.userPermissions = data; + }); + + expect(adminReducer(state, getUserPermissionsSucceeded(data))).toEqual(expected); + }); }); diff --git a/packages/strapi-admin/admin/src/containers/Admin/tests/selectors.test.js b/packages/strapi-admin/admin/src/containers/Admin/tests/selectors.test.js deleted file mode 100644 index 238c26bd57..0000000000 --- a/packages/strapi-admin/admin/src/containers/Admin/tests/selectors.test.js +++ /dev/null @@ -1,45 +0,0 @@ -import { fromJS, Map } from 'immutable'; - -import makeSelectAdminDomain, { selectAdminDomain } from '../selectors'; - -describe(' selectors', () => { - describe('selectAdminDomain selector', () => { - it('should select the global state', () => { - const state = fromJS({ - autoReload: false, - appError: false, - currentEnvironment: 'development', - isLoading: true, - layout: Map({}), - showLeftMenu: true, - strapiVersion: '3', - uuid: false, - }); - const mockedState = fromJS({ - admin: state, - }); - - expect(selectAdminDomain()(mockedState)).toEqual(state); - }); - }); - - describe('makeSelectAdminDomain', () => { - it('should select the global state (.toJS())', () => { - const state = fromJS({ - autoReload: false, - appError: false, - currentEnvironment: 'development', - isLoading: true, - layout: Map({}), - showLeftMenu: true, - strapiVersion: '3', - uuid: false, - }); - const mockedState = fromJS({ - admin: state, - }); - - expect(makeSelectAdminDomain()(mockedState)).toEqual(state.toJS()); - }); - }); -}); diff --git a/packages/strapi-admin/admin/src/containers/LeftMenu/index.js b/packages/strapi-admin/admin/src/containers/LeftMenu/index.js index 28123fc99a..5e70f5a2f5 100644 --- a/packages/strapi-admin/admin/src/containers/LeftMenu/index.js +++ b/packages/strapi-admin/admin/src/containers/LeftMenu/index.js @@ -141,7 +141,7 @@ const LeftMenu = forwardRef(({ version, plugins }, ref) => { getLinksPermissions(); // eslint-disable-next-line react-hooks/exhaustive-deps - }, []); + }, [permissions]); return ( diff --git a/packages/strapi-admin/admin/src/containers/LeftMenu/reducer.js b/packages/strapi-admin/admin/src/containers/LeftMenu/reducer.js index 8bb66a823c..90a6b16b0b 100644 --- a/packages/strapi-admin/admin/src/containers/LeftMenu/reducer.js +++ b/packages/strapi-admin/admin/src/containers/LeftMenu/reducer.js @@ -56,7 +56,7 @@ const reducer = (state, action) => break; } case 'TOGGLE_IS_LOADING': { - draftState.isLoading = !state.isLoading; + draftState.isLoading = false; break; } default: diff --git a/packages/strapi-admin/admin/src/hooks/useModels/reducer.js b/packages/strapi-admin/admin/src/hooks/useModels/reducer.js index 1299cbc3cb..258f58e054 100644 --- a/packages/strapi-admin/admin/src/hooks/useModels/reducer.js +++ b/packages/strapi-admin/admin/src/hooks/useModels/reducer.js @@ -14,6 +14,7 @@ const reducer = (state, action) => case 'GET_MODELS': { draftState.collectionTypes = initialState.collectionTypes; draftState.singleTypes = initialState.singleTypes; + draftState.components = initialState.components; draftState.isLoading = true; break; } diff --git a/packages/strapi-admin/admin/src/hooks/useModels/tests/reducer.test.js b/packages/strapi-admin/admin/src/hooks/useModels/tests/reducer.test.js index 1d661ef789..17dffbeca4 100644 --- a/packages/strapi-admin/admin/src/hooks/useModels/tests/reducer.test.js +++ b/packages/strapi-admin/admin/src/hooks/useModels/tests/reducer.test.js @@ -1,6 +1,6 @@ import reducer from '../reducer'; -describe('ADMIN | HOOKS | useContentTypes | reducer', () => { +describe('ADMIN | HOOKS | useModels | reducer', () => { describe('DEFAULT_ACTION', () => { it('should return the initialState', () => { const state = { @@ -11,13 +11,14 @@ describe('ADMIN | HOOKS | useContentTypes | reducer', () => { }); }); - describe('GET_DATA_ERROR', () => { + describe('GET_MODELS_ERROR', () => { it('should set isLoading to false is an error occured', () => { const action = { type: 'GET_MODELS_ERROR', }; const initialState = { collectionTypes: [], + components: [], singleTypes: [ { uid: 'app.homepage', @@ -31,6 +32,7 @@ describe('ADMIN | HOOKS | useContentTypes | reducer', () => { }; const expected = { collectionTypes: [], + components: [], singleTypes: [], isLoading: false, }; @@ -45,12 +47,37 @@ describe('ADMIN | HOOKS | useContentTypes | reducer', () => { type: 'GET_MODELS', }; const initialState = { - collectionTypes: [], - singleTypes: [], - isLoading: true, + collectionTypes: [ + { + uid: 'app.category', + isDisplayed: true, + schema: { + kind: 'collectionType', + }, + }, + { + uid: 'app.category', + isDisplayed: true, + schema: { + kind: 'collectionType', + }, + }, + ], + singleTypes: [ + { + uid: 'app.homepage', + isDisplayed: true, + schema: { + kind: 'singleType', + }, + }, + ], + components: [{}], + isLoading: false, }; const expected = { collectionTypes: [], + components: [], singleTypes: [], isLoading: true, }; @@ -63,7 +90,7 @@ describe('ADMIN | HOOKS | useContentTypes | reducer', () => { it('should return the state with the collectionTypes and singleTypes', () => { const action = { type: 'GET_MODELS_SUCCEDED', - data: [ + contentTypes: [ { uid: 'app.homepage', isDisplayed: true, @@ -86,9 +113,11 @@ describe('ADMIN | HOOKS | useContentTypes | reducer', () => { }, }, ], + components: [], }; const initialState = { collectionTypes: [], + components: [], singleTypes: [], isLoading: true, }; @@ -111,6 +140,7 @@ describe('ADMIN | HOOKS | useContentTypes | reducer', () => { }, }, ], + components: [], isLoading: false, }; diff --git a/packages/strapi-admin/admin/src/utils/fakePermissionsData.js b/packages/strapi-admin/admin/src/utils/fakePermissionsData.js index 02f5c55294..2d70140e73 100644 --- a/packages/strapi-admin/admin/src/utils/fakePermissionsData.js +++ b/packages/strapi-admin/admin/src/utils/fakePermissionsData.js @@ -21,82 +21,82 @@ const data = { }, // Admin webhooks - { - action: 'admin::webhooks.create', - subject: null, - fields: null, - conditions: [], - }, - { - action: 'admin::webhooks.read', - subject: null, - fields: null, - conditions: [], - }, - { - action: 'admin::webhooks.update', - subject: null, - fields: null, - conditions: [], - }, - { - action: 'admin::webhooks.delete', - subject: null, - fields: null, - conditions: [], - }, + // { + // action: 'admin::webhooks.create', + // subject: null, + // fields: null, + // conditions: [], + // }, + // { + // action: 'admin::webhooks.read', + // subject: null, + // fields: null, + // conditions: [], + // }, + // { + // action: 'admin::webhooks.update', + // subject: null, + // fields: null, + // conditions: [], + // }, + // { + // action: 'admin::webhooks.delete', + // subject: null, + // fields: null, + // conditions: [], + // }, // Admin users - { - action: 'admin::users.create', - subject: null, - fields: null, - conditions: [], - }, - { - action: 'admin::users.read', - subject: null, - fields: null, - conditions: [], - }, - { - action: 'admin::users.update', - subject: null, - fields: null, - conditions: [], - }, - { - action: 'admin::users.delete', - subject: null, - fields: null, - conditions: [], - }, + // { + // action: 'admin::users.create', + // subject: null, + // fields: null, + // conditions: [], + // }, + // { + // action: 'admin::users.read', + // subject: null, + // fields: null, + // conditions: [], + // }, + // { + // action: 'admin::users.update', + // subject: null, + // fields: null, + // conditions: [], + // }, + // { + // action: 'admin::users.delete', + // subject: null, + // fields: null, + // conditions: [], + // }, // Admin roles - { - action: 'admin::roles.create', - subject: null, - fields: null, - conditions: [], - }, - { - action: 'admin::roles.read', - subject: null, - fields: null, - conditions: [], - }, - { - action: 'admin::roles.update', - subject: null, - fields: null, - conditions: [], - }, - { - action: 'admin::roles.delete', - subject: null, - fields: null, - conditions: [], - }, + // { + // action: 'admin::roles.create', + // subject: null, + // fields: null, + // conditions: [], + // }, + // { + // action: 'admin::roles.read', + // subject: null, + // fields: null, + // conditions: [], + // }, + // { + // action: 'admin::roles.update', + // subject: null, + // fields: null, + // conditions: [], + // }, + // { + // action: 'admin::roles.delete', + // subject: null, + // fields: null, + // conditions: [], + // }, // Content type builder { @@ -157,12 +157,12 @@ const data = { fields: null, conditions: null, }, - { - action: 'plugins::upload.settings.read', - subject: null, - fields: null, - conditions: null, - }, + // { + // action: 'plugins::upload.settings.read', + // subject: null, + // fields: null, + // conditions: null, + // }, // Users-permissions { @@ -331,6 +331,11 @@ const data = { subject: 'application::address.address', conditions: [], }, + { + action: 'plugins::content-manager.explorer.create', + subject: 'application::vegetable.vegetable', + conditions: [], + }, { action: 'plugins::content-manager.explorer.create', subject: 'application::restaurant.restaurant', diff --git a/packages/strapi-helper-plugin/lib/src/utils/request.js b/packages/strapi-helper-plugin/lib/src/utils/request.js index ceec63aef9..7caaba3689 100644 --- a/packages/strapi-helper-plugin/lib/src/utils/request.js +++ b/packages/strapi-helper-plugin/lib/src/utils/request.js @@ -77,8 +77,7 @@ function serverRestartWatcher(response) { if (res.status >= 400) { throw new Error('not available'); } - // Hide the global OverlayBlocker - strapi.unlockApp(); + resolve(response); }) .catch(() => { @@ -146,9 +145,6 @@ export default function request(...args) { .then(parseJSON) .then(response => { if (shouldWatchServerRestart) { - // Display the global OverlayBlocker - strapi.lockApp(shouldWatchServerRestart); - return serverRestartWatcher(response); } diff --git a/packages/strapi-plugin-content-type-builder/admin/src/containers/DataManagerProvider/index.js b/packages/strapi-plugin-content-type-builder/admin/src/containers/DataManagerProvider/index.js index eb2a4da8da..c6b8a70276 100644 --- a/packages/strapi-plugin-content-type-builder/admin/src/containers/DataManagerProvider/index.js +++ b/packages/strapi-plugin-content-type-builder/admin/src/containers/DataManagerProvider/index.js @@ -33,7 +33,14 @@ import { const DataManagerProvider = ({ allIcons, children }) => { const [reducerState, dispatch] = useReducer(reducer, initialState, init); const [infoModals, toggleInfoModal] = useState({ cancel: false }); - const { autoReload, currentEnvironment, emitEvent, formatMessage, menu } = useGlobalContext(); + const { + autoReload, + currentEnvironment, + emitEvent, + fetchUserPermissions, + formatMessage, + menu, + } = useGlobalContext(); const { components, contentTypes, @@ -214,11 +221,18 @@ const DataManagerProvider = ({ allIcons, children }) => { push({ search: '' }); if (userConfirm) { + strapi.lockApp(); + await request(requestURL, { method: 'DELETE' }, true); + + await updatePermissions(); + // Reload the plugin so the cycle is new again dispatch({ type: 'RELOAD_PLUGIN' }); // Refetch all the data getDataRef.current(); + + strapi.unlockApp(); } } catch (err) { console.error({ err }); @@ -252,15 +266,22 @@ const DataManagerProvider = ({ allIcons, children }) => { return; } + strapi.lockApp(); + await request(requestURL, { method: 'DELETE' }, true); // Reload the plugin so the cycle is new again dispatch({ type: 'RELOAD_PLUGIN' }); + // Refetch the permissions + await updatePermissions(); + // Update the app menu await updateAppMenu(); // Refetch all the data getDataRef.current(); + + strapi.unlockApp(); } } catch (err) { console.error({ err }); @@ -275,13 +296,20 @@ const DataManagerProvider = ({ allIcons, children }) => { // Close the modal push({ search: '' }); + // Lock the app + strapi.lockApp(); + // Update the category await request(requestURL, { method: 'PUT', body }, true); + await updatePermissions(); + // Reload the plugin so the cycle is new again dispatch({ type: 'RELOAD_PLUGIN' }); // Refetch all the data getDataRef.current(); + + strapi.unlockApp(); } catch (err) { console.error({ err }); strapi.notification.error('notification.error'); @@ -394,7 +422,13 @@ const DataManagerProvider = ({ allIcons, children }) => { const baseURL = `/${pluginId}/${endPoint}`; const requestURL = isCreating ? baseURL : `${baseURL}/${currentUid}`; + // Lock the app + strapi.lockApp(); + await request(requestURL, { method, body }, true); + + await updatePermissions(); + // Update the app menu await updateAppMenu(); @@ -416,6 +450,8 @@ const DataManagerProvider = ({ allIcons, children }) => { dispatch({ type: 'RELOAD_PLUGIN' }); // Refetch all the data getDataRef.current(); + + strapi.unlockApp(); } catch (err) { if (!isInContentTypeView) { emitEvent('didNotSaveComponent'); @@ -437,6 +473,10 @@ const DataManagerProvider = ({ allIcons, children }) => { } }; + const updatePermissions = async () => { + await fetchUserPermissions('user2'); + }; + const updateSchema = (data, schemaType, componentUID) => { dispatch({ type: 'UPDATE_SCHEMA',