-
Notifications
You must be signed in to change notification settings - Fork 70
feat(sync-actions): add changeMasterVariant action generation
#304
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
710b3ce
0e605d3
a675b76
e1a5d56
5c6c66e
f552049
7b7ca61
833ee1b
f8a6616
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -61,10 +61,15 @@ export function actionsMapVariants (diff, oldObj, newObj) { | |
| ...newObject, | ||
| action: 'addVariant', | ||
| }), | ||
| [REMOVE_ACTIONS]: objectToRemove => ({ | ||
| action: 'removeVariant', | ||
| id: objectToRemove.id, | ||
| }), | ||
| [REMOVE_ACTIONS]: ({ id }, index) => { | ||
| // The master variant can not be removed | ||
| if (index <= 0) return null | ||
|
|
||
| return { | ||
| action: 'removeVariant', | ||
| id, | ||
| } | ||
| }, | ||
| }) | ||
|
|
||
| return handler(diff, oldObj, newObj) | ||
|
|
@@ -137,29 +142,7 @@ export function actionsMapAttributes ( | |
| sameForAllAttributeNames = [], | ||
| ) { | ||
| let actions = [] | ||
| const { masterVariant, variants } = diff | ||
|
|
||
| if (masterVariant) { | ||
| const skuAction = _buildSkuActions( | ||
| masterVariant, | ||
| oldObj.masterVariant, | ||
| ) | ||
| const keyAction = _buildKeyActions( | ||
| masterVariant, | ||
| oldObj.masterVariant, | ||
| ) | ||
| if (skuAction) actions.push(skuAction) | ||
| if (keyAction) actions.push(keyAction) | ||
|
|
||
| const { attributes } = masterVariant | ||
| const attrActions = _buildVariantAttributesActions( | ||
| attributes, | ||
| oldObj.masterVariant, | ||
| newObj.masterVariant, | ||
| sameForAllAttributeNames, | ||
| ) | ||
| actions = actions.concat(attrActions) | ||
| } | ||
| const { variants } = diff | ||
|
|
||
| if (variants) | ||
| forEach(variants, (variant, key) => { | ||
|
|
@@ -172,6 +155,7 @@ export function actionsMapAttributes ( | |
| if (keyAction) actions.push(keyAction) | ||
|
|
||
| const { attributes } = variant | ||
|
|
||
| const attrActions = _buildVariantAttributesActions( | ||
| attributes, | ||
| oldObj.variants[key], | ||
|
|
@@ -196,16 +180,7 @@ export function actionsMapAttributes ( | |
|
|
||
| export function actionsMapImages (diff, oldObj, newObj) { | ||
| let actions = [] | ||
| const { masterVariant, variants } = diff | ||
|
|
||
| if (masterVariant) { | ||
| const mActions = _buildVariantImagesAction( | ||
| masterVariant.images, | ||
| oldObj.masterVariant, | ||
| newObj.masterVariant, | ||
| ) | ||
| actions = actions.concat(mActions) | ||
| } | ||
| const { variants } = diff | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ...all this duplication of handling changes goes away. |
||
|
|
||
| if (variants) | ||
| forEach(variants, (variant, key) => { | ||
|
|
@@ -225,18 +200,7 @@ export function actionsMapPrices (diff, oldObj, newObj) { | |
| let changePriceActions = [] | ||
| let removePriceActions = [] | ||
|
|
||
| const { masterVariant, variants } = diff | ||
|
|
||
| if (masterVariant) { | ||
| const [ a, c, r ] = _buildVariantPricesAction( | ||
| masterVariant.prices, | ||
| oldObj.masterVariant, | ||
| newObj.masterVariant, | ||
| ) | ||
| addPriceActions = addPriceActions.concat(a) | ||
| changePriceActions = changePriceActions.concat(c) | ||
| removePriceActions = removePriceActions.concat(r) | ||
| } | ||
| const { variants } = diff | ||
|
|
||
| if (variants) | ||
| forEach(variants, (variant, key) => { | ||
|
|
@@ -256,6 +220,30 @@ export function actionsMapPrices (diff, oldObj, newObj) { | |
| .concat(addPriceActions) | ||
| } | ||
|
|
||
| export function generateChangeMasterVariantAction (oldObj, newObj) { | ||
|
||
| const createChangeMasterVariantAction = variantId => ({ | ||
| action: 'changeMasterVariant', | ||
| variantId, | ||
| }) | ||
| const extractMasterVariantId = (fromObj) => { | ||
| const variants = Array.isArray(fromObj.variants) ? fromObj.variants : [] | ||
|
|
||
| return variants[0] ? variants[0].id : undefined | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This feels a bit wonky but eases the code further down. Generally caused by variants not having to be set and hence the |
||
| } | ||
|
|
||
| const newMasterVariantId = extractMasterVariantId(newObj) | ||
| const oldMasterVariantId = extractMasterVariantId(oldObj) | ||
|
|
||
| // Previosuly no master variant existed | ||
| if (!oldMasterVariantId && newMasterVariantId) | ||
|
||
| return createChangeMasterVariantAction(newMasterVariantId) | ||
| // Old and new master master variant differ and a new master variant id exists | ||
| if (newMasterVariantId && oldMasterVariantId !== newMasterVariantId) | ||
| return createChangeMasterVariantAction(newMasterVariantId) | ||
|
|
||
| return null | ||
|
||
| } | ||
|
|
||
|
|
||
| /** | ||
| * HELPER FUNCTIONS | ||
|
|
@@ -542,7 +530,6 @@ function _buildVariantPricesAction (diffedPrices, oldVariant, newVariant) { | |
| } | ||
| } else if (REGEX_UNDERSCORE_NUMBER.test(key)) { | ||
| const index = key.substring(1) | ||
|
|
||
| removePriceActions.push({ | ||
| action: 'removePrice', priceId: oldVariant.prices[index].id, | ||
| }) | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -38,6 +38,10 @@ function createProductMapActions (mapActionGroup) { | |
| allActions.push(mapActionGroup('variants', () => | ||
| productActions.actionsMapVariants(diff, oldObj, newObj))) | ||
|
|
||
| const changeMasterVariantAction = | ||
|
||
| productActions.generateChangeMasterVariantAction(oldObj, newObj) | ||
| if (changeMasterVariantAction) allActions.push(changeMasterVariantAction) | ||
|
|
||
| allActions.push(mapActionGroup('attributes', () => | ||
| productActions.actionsMapAttributes(diff, oldObj, newObj, | ||
| sameForAllAttributeNames || []))) | ||
|
|
@@ -58,10 +62,32 @@ function createProductMapActions (mapActionGroup) { | |
| } | ||
| } | ||
|
|
||
| function moveMasterVariantsIntoVariants (before, now) { | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is the hook we pass in to process data before it hits the differ. |
||
| const move = obj => ({ | ||
| ...obj, | ||
| masterVariant: undefined, | ||
| variants: [ | ||
| obj.masterVariant, | ||
| ...obj.variants || [], | ||
| ], | ||
| }) | ||
| const hasMasterVariant = obj => obj && obj.masterVariant | ||
|
|
||
| return [ | ||
| hasMasterVariant(before) ? move(before) : before, | ||
| hasMasterVariant(now) ? move(now) : now, | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I am not sure how often we will have this scenario but what if the
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is what can not happen in theory. Whenever a project has been created implicitly a master variant will be added. Theoretically we could remove these checks but our test data is sometimes a bit messy. E.g. not having a masterVariant in
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I mean from the user end, I think what you describing is the If we understand each other though 🤔
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hm, so I think there are a couple of invariants in this discussions
If non the the cases hold be should either throw or do nothing which breaks things. By not breaking we can "hope" that the |
||
| ] | ||
| } | ||
|
|
||
| export default (config: Array<ActionGroup>): SyncAction => { | ||
| const mapActionGroup = createMapActionGroup(config) | ||
| const doMapActions = createProductMapActions(mapActionGroup) | ||
| const buildActions = createBuildActions(diffpatcher.diff, doMapActions) | ||
|
|
||
| const buildActions = createBuildActions( | ||
| diffpatcher.diff, | ||
| doMapActions, | ||
| moveMasterVariantsIntoVariants, | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ...third argument of the action builder. |
||
| ) | ||
|
|
||
| return { buildActions } | ||
| } | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,13 +1,23 @@ | ||
| export default function createBuildActions (diff, doMapActions) { | ||
| function applyOnBeforeDiff (before, now, fn) { | ||
| return fn && typeof fn === 'function' ? fn(before, now) : [before, now] | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Eases code on call site. |
||
| } | ||
|
|
||
| export default function createBuildActions ( | ||
| differ, doMapActions, onBeforeDiff, | ||
| ) { | ||
| return function buildActions (now, before, options = {}) { | ||
| if (!now || !before) | ||
| throw new Error('Missing either `newObj` or `oldObj` ' + | ||
| 'in order to build update actions') | ||
|
|
||
| // diff 'em | ||
| const diffed = diff(before, now) | ||
| const [ | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This function feels generally flaky to me. It shuffles the arguments of |
||
| proccedBefore, processedNow, | ||
| ] = applyOnBeforeDiff(before, now, onBeforeDiff) | ||
|
|
||
| const diffed = differ(proccedBefore, processedNow) | ||
|
||
|
|
||
| if (!diffed) return [] | ||
|
|
||
| return doMapActions(diffed, now, before, options) | ||
| return doMapActions(diffed, processedNow, proccedBefore, options) | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -23,26 +23,42 @@ export default function createBuildArrayActions (key, config) { | |
|
|
||
| if (diff[key]) { | ||
| const arrayDelta = diff[key] | ||
|
|
||
| Object.keys(arrayDelta).forEach((index) => { | ||
| if (config[ADD_ACTIONS] && isCreateAction(arrayDelta, index)) | ||
| addActions.push( | ||
| // When adding a new element you don't need the oldObj | ||
| config[ADD_ACTIONS](newObj[key][index]), | ||
| if (config[ADD_ACTIONS] && isCreateAction(arrayDelta, index)) { | ||
| const actionGenerator = config[ADD_ACTIONS] | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Just general simplications in naming things here. The addition is to pass the index to the callback so it has the information. |
||
| // When adding a new element you don't need the oldObj | ||
| const action = actionGenerator( | ||
| newObj[key][index], | ||
| parseInt(index, 10), | ||
| ) | ||
| else if (config[CHANGE_ACTIONS] && isChangeAction(arrayDelta, index)) | ||
| changeActions.push( | ||
| // When changing an existing element you need both old + new | ||
| config[CHANGE_ACTIONS](oldObj[key][index], newObj[key][index]), | ||
|
|
||
| if (action) addActions.push(action) | ||
| } else if ( | ||
| config[CHANGE_ACTIONS] && isChangeAction(arrayDelta, index) | ||
| ) { | ||
| const actionGenerator = config[CHANGE_ACTIONS] | ||
| // When changing an existing element you need both old + new | ||
| const action = actionGenerator( | ||
| oldObj[key][index], | ||
| newObj[key][index], | ||
| parseInt(index, 10), | ||
| ) | ||
| else if ( | ||
|
|
||
| if (action) changeActions.push(action) | ||
| } else if ( | ||
| config[REMOVE_ACTIONS] && | ||
| isRemoveAction(arrayDelta, index) | ||
| ) { | ||
| const realIndex = index.replace('_', '') | ||
| removeActions.push( | ||
| // When removing an existing element you don't need the newObj | ||
| config[REMOVE_ACTIONS](oldObj[key][realIndex]), | ||
| const actionGenerator = config[REMOVE_ACTIONS] | ||
| // When removing an existing element you don't need the newObj | ||
| const action = actionGenerator( | ||
| oldObj[key][realIndex], | ||
| parseInt(realIndex, 10), | ||
| ) | ||
|
|
||
| if (action) removeActions.push(action) | ||
| } | ||
| }) | ||
| } | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can't remove the master variant. This was done before by treating it as in the
masterVariantproperty which would non run through the array detection process.