diff --git a/client/src/campaigns/CUD.js b/client/src/campaigns/CUD.js index 16978459..945965a9 100644 --- a/client/src/campaigns/CUD.js +++ b/client/src/campaigns/CUD.js @@ -82,7 +82,7 @@ export default class CUD extends Component { ]; this.sourceOptions = []; - for (const key in sourceLabelsOrder) { + for (const key of sourceLabelsOrder) { this.sourceOptions.push({key, label: this.sourceLabels[key]}); } diff --git a/client/src/templates/CUD.js b/client/src/templates/CUD.js index b253f129..c89166de 100644 --- a/client/src/templates/CUD.js +++ b/client/src/templates/CUD.js @@ -98,9 +98,13 @@ export default class CUD extends Component { } submitFormValuesMutator(data) { - this.templateTypes[data.type].beforeSave(data); + if (data.fromExistingEntity) { + return filterData(data, ['name', 'description', 'namespace', 'fromExistingEntity', 'existingEntity']); - return filterData(data, ['name', 'description', 'type', 'tag_language', 'data', 'html', 'text', 'namespace', 'fromExistingEntity', 'existingEntity']); + } else { + this.templateTypes[data.type].beforeSave(data); + return filterData(data, ['name', 'description', 'type', 'tag_language', 'data', 'html', 'text', 'namespace', 'fromExistingEntity']); + } } async getPreSubmitFormValuesUpdater() { @@ -151,27 +155,28 @@ export default class CUD extends Component { state.setIn(['name', 'error'], t('nameMustNotBeEmpty')); } - const typeKey = state.getIn(['type', 'value']); - if (!typeKey && !state.getIn(['fromExistingEntity', 'value'])) { - state.setIn(['type', 'error'], t('typeMustBeSelected')); - }else{ - state.setIn(['type', 'error'], null); - } - - if (!state.getIn(['tag_language', 'value'])) { - state.setIn(['tag_language', 'error'], t('Tag language must be selected')); - } - - if (state.getIn(['fromExistingEntity', 'value']) && !state.getIn(['existingEntity', 'value'])) { - state.setIn(['existingEntity', 'error'], t('sourceTemplateMustNotBeEmpty')); - } else { - state.setIn(['existingEntity', 'error'], null); - } - validateNamespace(t, state); - if (typeKey && !state.getIn(['fromExistingEntity', 'value'])) { - this.templateTypes[typeKey].validate(state); + const fromExistingEntity = state.getIn(['fromExistingEntity', 'value']); + + if (fromExistingEntity) { + if (!state.getIn(['existingEntity', 'value'])) { + state.setIn(['existingEntity', 'error'], t('sourceTemplateMustNotBeEmpty')); + } + + } else { + const typeKey = state.getIn(['type', 'value']); + if (!typeKey) { + state.setIn(['type', 'error'], t('typeMustBeSelected')); + } + + if (!state.getIn(['tag_language', 'value'])) { + state.setIn(['tag_language', 'error'], t('Tag language must be selected')); + } + + if (typeKey) { + this.templateTypes[typeKey].validate(state); + } } } diff --git a/server/lib/campaign-content.js b/server/lib/campaign-content.js index 1f6901d8..965b6bfb 100644 --- a/server/lib/campaign-content.js +++ b/server/lib/campaign-content.js @@ -1,6 +1,6 @@ 'use strict'; -function convertFileURLs(sourceCustom, fromEntityType, fromEntityId, toEntityType, toEntityId, campaign) { +function convertFileURLs(sourceCustom, fromEntityType, fromEntityId, toEntityType, toEntityId) { function convertText(text) { if (text) { @@ -22,7 +22,7 @@ function convertFileURLs(sourceCustom, fromEntityType, fromEntityId, toEntityTyp sourceCustom.html = convertText(sourceCustom.html); sourceCustom.text = convertText(sourceCustom.text); - if ((sourceCustom.type === 'mosaico' || sourceCustom.type === 'mosaicoWithFsTemplate') && campaign){ + if (sourceCustom.type === 'mosaico' || sourceCustom.type === 'mosaicoWithFsTemplate') { sourceCustom.data.model = convertText(sourceCustom.data.model); sourceCustom.data.model = convertText(sourceCustom.data.model); sourceCustom.data.metadata = convertText(sourceCustom.data.metadata); diff --git a/server/models/campaigns.js b/server/models/campaigns.js index a8f6e8f3..7c8c5bfa 100644 --- a/server/models/campaigns.js +++ b/server/models/campaigns.js @@ -529,7 +529,7 @@ async function _createTx(tx, context, entity, content) { if (copyFilesFrom) { await files.copyAllTx(tx, context, copyFilesFrom.entityType, 'file', copyFilesFrom.entityId, 'campaign', 'file', id); - convertFileURLs(data.sourceCustom, copyFilesFrom.entityType, copyFilesFrom.entityId, 'campaign', id, true); + convertFileURLs(data.sourceCustom, copyFilesFrom.entityType, copyFilesFrom.entityId, 'campaign', id); await tx('campaigns') .update({ data: JSON.stringify(data) diff --git a/server/models/templates.js b/server/models/templates.js index 0f311f77..209e1635 100644 --- a/server/models/templates.js +++ b/server/models/templates.js @@ -67,8 +67,6 @@ async function _validateAndPreprocess(tx, entity) { enforce(allTagLanguages.includes(entity.tag_language), `Invalid tag language '${entity.tag_language}'`); // We don't check contents of the "data" because it is processed solely on the client. The client generates the HTML code we use when sending out campaigns. - - entity.data = JSON.stringify(entity.data); } async function create(context, entity) { @@ -77,7 +75,7 @@ async function create(context, entity) { if (entity.fromExistingEntity) { const existing = await getByIdTx(tx, context, entity.existingEntity, false); - + entity.type = existing.type; entity.tag_language = existing.tag_language; entity.data = existing.data; @@ -87,15 +85,28 @@ async function create(context, entity) { await _validateAndPreprocess(tx, entity); - const ids = await tx('templates').insert(filterObject(entity, allowedKeys)); + const filteredEntityWithUnstringifiedData = filterObject(entity, allowedKeys); + const filteredEntity = { + ...filteredEntityWithUnstringifiedData, + data: JSON.stringify(filteredEntityWithUnstringifiedData.data) + }; + + const ids = await tx('templates').insert(filteredEntity); const id = ids[0]; await shares.rebuildPermissionsTx(tx, { entityTypeId: 'template', entityId: id }); if (entity.fromExistingEntity) { await files.copyAllTx(tx, context, 'template', 'file', entity.existingEntity, 'template', 'file', id); - convertFileURLs(entity, 'template', entity.existingEntity, 'template', id, false); - await tx('templates').update(filterObject(entity, allowedKeys)).where('id', id); + + convertFileURLs(filteredEntityWithUnstringifiedData, 'template', entity.existingEntity, 'template', id); + + const filteredEntity = { + ...filteredEntityWithUnstringifiedData, + data: JSON.stringify(filteredEntityWithUnstringifiedData.data) + }; + + await tx('templates').update(filteredEntity).where('id', id); } return id; @@ -119,10 +130,13 @@ async function updateWithConsistencyCheck(context, entity) { } await _validateAndPreprocess(tx, entity); + entity.data = JSON.stringify(entity.data); await namespaceHelpers.validateMove(context, entity, existing, 'template', 'createTemplate', 'delete'); - await tx('templates').where('id', entity.id).update(filterObject(entity, allowedKeys)); + const filteredEntity = filterObject(entity, allowedKeys); + + await tx('templates').where('id', entity.id).update(filteredEntity); await shares.rebuildPermissionsTx(tx, { entityTypeId: 'template', entityId: entity.id }); });