diff --git a/assets/js/src/form_editor/store/actions.jsx b/assets/js/src/form_editor/store/actions.jsx index cd03aee0d9..e548f7edf3 100644 --- a/assets/js/src/form_editor/store/actions.jsx +++ b/assets/js/src/form_editor/store/actions.jsx @@ -61,11 +61,17 @@ export function switchSidebarTab(id) { }; } -export function toggleSidebarPanel(id, isOpened = undefined) { +/** + * Toggle a panel within the sidebar. Use toggleTo to enforce certain state + * @param {string} id + * @param {string|undefined} toggleTo - possible values 'opened', 'closed' + * @return {{toggleTo: string|undefined, id: string, type: string}} + */ +export function toggleSidebarPanel(id, toggleTo = undefined) { return { type: 'TOGGLE_SIDEBAR_PANEL', id, - isOpened, + toggleTo, }; } diff --git a/assets/js/src/form_editor/store/reducers/toggle_sidebar_panel.jsx b/assets/js/src/form_editor/store/reducers/toggle_sidebar_panel.jsx index 4f201a2ccc..3522ad944d 100644 --- a/assets/js/src/form_editor/store/reducers/toggle_sidebar_panel.jsx +++ b/assets/js/src/form_editor/store/reducers/toggle_sidebar_panel.jsx @@ -1,13 +1,34 @@ import { remove } from 'lodash'; -export default (state, action) => { - const openedPanels = [...state.sidebar.openedPanels]; - const isOpenedCurrent = openedPanels.includes(action.id); - const isOpenedFinal = action.isOpened !== undefined ? action.isOpened : !isOpenedCurrent; - if (isOpenedFinal && !isOpenedCurrent) { - openedPanels.push(action.id); +const getRequiredAction = (openedPanels, panelId, toggleTo) => { + const isPanelOpened = openedPanels.includes(panelId); + let requestedToggleState = toggleTo; + if (requestedToggleState === undefined) { + requestedToggleState = isPanelOpened ? 'closed' : 'opened'; } - if (!isOpenedFinal && isOpenedCurrent) { + if (isPanelOpened && requestedToggleState === 'closed') { + return 'close'; + } + if (!isPanelOpened && requestedToggleState === 'opened') { + return 'open'; + } + return null; +}; + +/** + * @param {object} state + * @param {{toggleTo: string|undefined, id: string, type: string}} action + * @return {object} Modified state object + */ +export default (state, action) => { + if (action.toggleTo !== undefined && !['opened', 'closed'].includes(action.toggleTo)) { + throw new Error(`Unexpected toggleTo value "${action.toggleTo}"`); + } + const openedPanels = [...state.sidebar.openedPanels]; + const requiredAction = getRequiredAction(openedPanels, action.id, action.toggleTo); + if (requiredAction === 'open') { + openedPanels.push(action.id); + } else if (requiredAction === 'close') { remove(openedPanels, (item) => item === action.id); } return {