Skip to content

Commit

Permalink
isolates vars and selectors to dual profiles
Browse files Browse the repository at this point in the history
  • Loading branch information
jhmullen committed Aug 3, 2022
1 parent 2e0d546 commit 7302535
Show file tree
Hide file tree
Showing 4 changed files with 68 additions and 26 deletions.
48 changes: 36 additions & 12 deletions packages/cms/src/components/ProfileRenderer.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,20 @@ import "../css/layout.css";

import "./Profile.css";

const splitComparisonKeys = obj => {
const split = {
profile: {},
comparison: {}
};
Object.keys(obj).forEach(k => {
split
[k.startsWith("compare_") ? "comparison" : "profile"]
[k.replace("compare_", "")] =
obj[k];
});
return split;
};

class ProfileRenderer extends Component {
constructor(props) {
super(props);
Expand Down Expand Up @@ -126,11 +140,11 @@ class ProfileRenderer extends Component {
* This requires re-running materializers, because the user may have changed a variable
* that would affect the "allowed" status of a given section.
*/
onSetVariables(newVariables, forceMats) {
const {profile, selectors, setVarsLoading, formatterFunctions} = this.state;
const {id, variables} = profile;
const {locale, sectionID} = this.props;
const {params} = this.context.router;
onSetVariables(newVariables, forceMats, isComparison) {
const {profile, selectors, setVarsLoading, formatterFunctions, comparison} = this.state;
const {variables} = profile;
const compVars = comparison.variables;
const {locale} = this.props;
// Users should ONLY call setVariables in a callback - never in the main execution, as this
// would cause an infinite loop. However, should they do so anyway, try and prevent the infinite
// loop by checking if the vars are in there already, only updating if they are not yet set.
Expand All @@ -152,8 +166,16 @@ class ProfileRenderer extends Component {
// If forceMats is not true, no materializers required. Using the locally stored _rawProfile and the now-combined
// old and new variables, you have all that you need to make the profile update.
else {
const newProfile = prepareProfile(variables._rawProfile, Object.assign({}, variables, newVariables), formatterFunctions, locale, selectors);
this.setState({profile: {...profile, ...newProfile}});
const split = splitComparisonKeys(selectors);
if (isComparison) {
const newComparison = prepareProfile(compVars._rawProfile, Object.assign({}, compVars, newVariables), formatterFunctions, locale, split.comparison);
this.setState({comparison: {...comparison, ...newComparison}});
}
else {
const newProfile = prepareProfile(variables._rawProfile, Object.assign({}, variables, newVariables), formatterFunctions, locale, split.profile);
this.setState({profile: {...profile, ...newProfile}});
}

}
}
}
Expand All @@ -176,20 +198,21 @@ class ProfileRenderer extends Component {

}

onSelector(name, value) {
onSelector(name, value, isComparison) {

const {comparison, profile, selectors, formatterFunctions} = this.state;
const {locale} = this.props;

selectors[name] = value;
selectors[`${isComparison ? "compare_" : ""}${name}`] = value;
const split = splitComparisonKeys(selectors);

const {variables} = profile;
const newProfile = prepareProfile(variables._rawProfile, variables, formatterFunctions, locale, selectors);
const newProfile = prepareProfile(variables._rawProfile, variables, formatterFunctions, locale, split.profile);
const payload = {selectors, profile: {...profile, ...newProfile}};

if (comparison) {
const compVars = comparison.variables;
const newComp = prepareProfile(compVars._rawProfile, compVars, formatterFunctions, locale, selectors);
const newComp = prepareProfile(compVars._rawProfile, compVars, formatterFunctions, locale, split.comparison);
payload.comparison = {...comparison, ...newComp};
}

Expand Down Expand Up @@ -229,7 +252,8 @@ class ProfileRenderer extends Component {

if (Object.keys(selectors).length) {
const compVars = comparison.variables;
const newComp = prepareProfile(compVars._rawProfile, compVars, formatterFunctions, locale, selectors);
const split = splitComparisonKeys(selectors);
const newComp = prepareProfile(compVars._rawProfile, compVars, formatterFunctions, locale, split.comparison);
comparison = {...comparison, ...newComp};
}

Expand Down
18 changes: 15 additions & 3 deletions packages/cms/src/components/Viz/Viz.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,19 @@ class Viz extends Component {

// Variables come from props in the CMS, and Context in the Front-end.
const variables = this.props.variables || this.context.variables;
const compVariables = this.context.compVariables;
const isComparison = compVariables && compVariables.id === variables.id;
// onSetVariables will either come from ProfileBuilder (CMS) or Profile (Front-end)
// But either way, it is delivered via context. Have a backup no-op just in case.
const onSetVariables = this.context.onSetVariables ? this.context.onSetVariables : d => d;
let onSetVariables = d => d;
if (this.context.onSetVariables) {
if (isComparison) {
onSetVariables = (variables, forceMats) => this.context.onSetVariables(variables, forceMats, true);
}
else {
onSetVariables = this.context.onSetVariables;
}
}
// Window opening is only supported on front-end profiles. If they didn't
// come through context, then this Viz is in the CMS, so just replace it with a no-op.
const onOpenModal = this.context.onOpenModal ? this.context.onOpenModal : d => d;
Expand Down Expand Up @@ -175,7 +185,8 @@ Viz.childContextTypes = {
onOpenModal: PropTypes.func,
print: PropTypes.bool,
updateSource: PropTypes.func,
variables: PropTypes.object
variables: PropTypes.object,
compVariables: PropTypes.object
};

Viz.contextTypes = {
Expand All @@ -186,7 +197,8 @@ Viz.contextTypes = {
onSetVariables: PropTypes.func,
onOpenModal: PropTypes.func,
updateSource: PropTypes.func,
variables: PropTypes.object
variables: PropTypes.object,
compVariables: PropTypes.object
};

Viz.defaultProps = {
Expand Down
7 changes: 4 additions & 3 deletions packages/cms/src/components/sections/Section.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ class Section extends Component {
* the variables back to their original state. This local intermediary function, passed down via context,
* is responsible for keeping track of that, then in turn calling the props version of the function.
*/
onSetVariables(newVariables) {
onSetVariables(newVariables, forceMats, isComparison) {
const initialVariables = this.props.initialVariables || this.context.initialVariables || {};
const changedVariables = {};
Object.keys(newVariables).forEach(key => {
Expand All @@ -125,7 +125,7 @@ class Section extends Component {
changedVariables,
showReset: Object.keys(changedVariables).length > 0
});
if (this.props.onSetVariables) this.props.onSetVariables(newVariables);
if (this.props.onSetVariables) this.props.onSetVariables(newVariables, forceMats, isComparison);
}

/**
Expand All @@ -134,7 +134,8 @@ class Section extends Component {
*/
resetVariables() {
const {changedVariables} = this.state;
if (this.props.onSetVariables) this.props.onSetVariables(changedVariables);
const {comparison} = this.props.contents;
if (this.props.onSetVariables) this.props.onSetVariables(changedVariables, false, comparison);
this.setState({
changedVariables: {},
showReset: false
Expand Down
21 changes: 13 additions & 8 deletions packages/cms/src/components/sections/components/Selector.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,20 +32,24 @@ class Selector extends Component {
}
}

onSelectorWrapper(name, value) {
const {onSelector, variables, compVariables} = this.context;
const isComparison = compVariables && compVariables.id === variables.id;
onSelector(name, value, isComparison);
}

addComparison(comparison) {
const {comparisons} = this.state;
const filteredComparison = comparisons.concat([comparison]);
const {onSelector} = this.context;
const {name} = this.props;
onSelector(name, filteredComparison);
this.onSelectorWrapper(name, filteredComparison);
}

removeComparison(option) {
const {comparisons} = this.state;
const filteredComparison = comparisons.filter(d => d !== option);
const {onSelector} = this.context;
const {name} = this.props;
onSelector(name, filteredComparison);
this.onSelectorWrapper(name, filteredComparison);
}

renderItem(item, {handleClick}) {
Expand All @@ -63,7 +67,7 @@ class Selector extends Component {

render() {
const {activeValue, comparisons} = this.state;
const {onSelector, print, variables} = this.context;
const {print, variables} = this.context;
const {fontSize, id, loading, options, name, selectCutoff, title, type, t} = this.props;
const slug = `${name}-${id}`;
const labels = options.reduce((acc, d) => ({...acc, [d.option]: d.label}), {});
Expand Down Expand Up @@ -120,7 +124,7 @@ class Selector extends Component {
{(print ? options.filter(b => b.option === activeValue) : options).map(b =>
<Button
className="cp-selector-button"
onClick={() => onSelector(name, b.option)}
onClick={() => this.onSelectorWrapper(name, b.option)}
active={b.option === activeValue}
fontSize={fontSize}
key={b.option}
Expand All @@ -136,7 +140,7 @@ class Selector extends Component {
inline
fontSize={fontSize}
id={slug}
onChange={d => onSelector(name, d.target.value)}
onChange={d => this.onSelectorWrapper(name, d.target.value)}
disabled={loading}
value={activeValue}
>
Expand All @@ -153,7 +157,8 @@ class Selector extends Component {
Selector.contextTypes = {
onSelector: PropTypes.func,
print: PropTypes.bool,
variables: PropTypes.object
variables: PropTypes.object,
compVariables: PropTypes.object
};

Selector.defaultProps = {
Expand Down

0 comments on commit 7302535

Please sign in to comment.