Skip to content

Commit

Permalink
FIX update tab loading to use recent admin module changes
Browse files Browse the repository at this point in the history
The admin module previously used the redux-form store to track the
active Tab within a Tabs component. However this was recently refactored
in the admin module to use a different shard in the redux store, as it
was causing problems (functionality regressions) in form state with the
asset-admin module. So the logic here in Elemental also required updating.
  • Loading branch information
raissanorth authored and robbieaverill committed Oct 19, 2018
1 parent afd80c7 commit 8bae01b
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 37 deletions.
2 changes: 1 addition & 1 deletion client/dist/js/bundle.js

Large diffs are not rendered by default.

75 changes: 40 additions & 35 deletions client/src/components/ElementEditor/Element.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,14 @@

import React, { Component, PropTypes } from 'react';
import { elementType } from 'types/elementType';
import { bindActionCreators, compose } from 'redux';
import { compose } from 'redux';
import { inject } from 'lib/Injector';
import i18n from 'i18n';
import classNames from 'classnames';
import { connect } from 'react-redux';
import { change } from 'redux-form';
import { loadElementFormStateName } from 'state/editor/loadElementFormStateName';
import { loadElementSchemaValue } from 'state/editor/loadElementSchemaValue';

import * as TabsActions from 'state/tabs/TabsActions';

/**
* The Element component used in the context of an ElementEditor shows the summary
Expand Down Expand Up @@ -64,26 +63,25 @@ class Element extends Component {
}

/**
* Dispatcher to Redux-Form state for the Tabs container 'value'
* Dispatcher to Tabs redux store for this element's tabset
*
* @param {string} activeTab Name prop of the active tab
*/
updateFormTab(activeTab) {
const { element, actions } = this.props;
const { tabSetName, onActivateTab } = this.props;
const { initialTab } = this.state;

const formStateName = `element.${loadElementFormStateName(element.ID)}`;

if (!initialTab) {
this.setState({
initialTab: activeTab
});
}

if (activeTab || initialTab) {
actions.reduxForm.change(formStateName, 'Root', activeTab || initialTab);
onActivateTab(tabSetName, activeTab || initialTab);
} else {
const defaultFirstTab = 'Main';
actions.reduxForm.change(formStateName, 'Root', defaultFirstTab);
onActivateTab(tabSetName, defaultFirstTab);
}
}

Expand Down Expand Up @@ -179,7 +177,6 @@ class Element extends Component {
this.getVersionedStateClassName()
);


return (
<div
className={elementClassNames}
Expand Down Expand Up @@ -221,48 +218,56 @@ class Element extends Component {
}

function mapStateToProps(state, ownProps) {
const elementName = loadElementFormStateName(ownProps.element.ID);

// InlineEditForm will neither have been rendered nor wrapped in redux-form
if (!state.form.formState.element || !state.form.formState.element[elementName]) {
return {};
}

const elementId = ownProps.element.ID;
const elementName = loadElementFormStateName(elementId);
const elementFormSchema = loadElementSchemaValue('schemaUrl', elementId);

const stateValue = state.form.formState.element[elementName].values.Root;

// Search out a default value for the active tab if it is not already in the state.
// {@see Tabs.getDefaultActiveKey}
const filterFieldsForTabs = (field) => field.component === 'Tabs';

let defaultValue;
if (
state.form.formSchemas &&
// Find name of the first Tabs component in the form
// Only defined - and needed - once the form is loaded
const tabSet =
state.form &&
state.form.formSchemas[elementFormSchema] &&
state.form.formSchemas[elementFormSchema].schema
) {
defaultValue = state.form.formSchemas[elementFormSchema].schema.fields
.find(filterFieldsForTabs).children[0].name;
}
const activeTab = stateValue || defaultValue;
return { activeTab };
state.form.formSchemas[elementFormSchema].schema &&
state.form.formSchemas[elementFormSchema].schema.fields.find(filterFieldsForTabs);

const tabSetName = tabSet && tabSet.id;
const uniqueFieldId = `element.${elementName}__${tabSetName}`;

// Find name of the active tab in the tab set
// Only defined once an element form is expanded for the first time
const activeTab =
state.tabs &&
state.tabs.fields &&
state.tabs.fields[uniqueFieldId] &&
state.tabs.fields[uniqueFieldId].activeTab
;

return {
tabSetName,
activeTab,
};
}

function mapDispatchToProps(dispatch) {
function mapDispatchToProps(dispatch, ownProps) {
const elementName = loadElementFormStateName(ownProps.element.ID);

return {
actions: {
reduxForm: bindActionCreators({ change }, dispatch),
onActivateTab(tabSetName, activeTabName) {
dispatch(TabsActions.activateTab(`element.${elementName}__${tabSetName}`, activeTabName));
},
};
}


Element.propTypes = {
element: elementType,
link: PropTypes.string.isRequired,
editTabs: PropTypes.arrayOf(PropTypes.object),
// Redux mapped props:
activeTab: PropTypes.string,
tabSetName: PropTypes.string,
onActivateTab: PropTypes.func,
};

Element.defaultProps = {
Expand Down
9 changes: 8 additions & 1 deletion webpack.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,14 @@ const config = [
},
devtool: (ENV !== 'production') ? 'source-map' : '',
resolve: resolveJS(ENV, PATHS),
externals: externalJS(ENV, PATHS),
externals: Object.assign(
{},
externalJS(ENV, PATHS),
{
// @todo remove this once @silverstripe/webpack-config has this updated and published
'state/tabs/TabsActions': 'TabsActions',
}
),
module: moduleJS(ENV, PATHS),
plugins: pluginJS(ENV, PATHS),
},
Expand Down

0 comments on commit 8bae01b

Please sign in to comment.