Merge and cleanup of PR #564

The namespace filter in campaigns was dropped (i.e. "Work with campaign's namespace"). Instead, we need a universal solution. For instance a namespace slector somewhere in the top-right corner, which should apply to everything (not just campaigns).

Nevertheless, I kept the ...-by-namespace rest endpoints and related functions in models because they will be useful for implementing the universal namespace selection feature.
This commit is contained in:
Tomas Bures 2019-03-27 00:41:18 +01:00
parent dcb7168322
commit 2fe7f82be3
18 changed files with 1104 additions and 1143 deletions

View file

@ -231,7 +231,7 @@ roles:
name: Global Master
admin: true
description: All permissions
permissions: [rebuildPermissions, createJavascriptWithROAccess, manageUserList, manageBlacklist, manageSettings, setupAutomation]
permissions: [rebuildPermissions, createJavascriptWithROAccess, displayManageUsers, manageBlacklist, manageSettings, setupAutomation]
rootNamespaceRole: master
campaignsAdmin:
name: Campaigns Admin

View file

@ -64,29 +64,30 @@ function hash(entity, content) {
return hasher.hash(filteredEntity);
}
async function listDTAjax(context, params) {
async function _listDTAjax(context, namespaceId, params) {
return await dtHelpers.ajaxListWithPermissions(
context,
[{ entityTypeId: 'campaign', requiredOperations: ['view'] }],
params,
builder => builder.from('campaigns')
.innerJoin('namespaces', 'namespaces.id', 'campaigns.namespace')
.whereNull('campaigns.parent'),
builder => {
builder = builder.from('campaigns')
.innerJoin('namespaces', 'namespaces.id', 'campaigns.namespace')
.whereNull('campaigns.parent');
if (namespaceId) {
builder = builder.where('namespaces.id', namespaceId);
}
return builder;
},
['campaigns.id', 'campaigns.name', 'campaigns.cid', 'campaigns.description', 'campaigns.type', 'campaigns.status', 'campaigns.scheduled', 'campaigns.source', 'campaigns.created', 'namespaces.name']
);
}
async function listDTAjax(context, params) {
return await _listDTAjax(context, undefined, params);
}
async function listByNamespaceDTAjax(context, namespaceId, params) {
return await dtHelpers.ajaxListWithPermissions(
context,
[{ entityTypeId: 'campaign', requiredOperations: ['view'] }],
params,
builder => builder.from('campaigns')
.innerJoin('namespaces', 'namespaces.id', 'campaigns.namespace')
.where('namespaces.id', namespaceId)
.whereNull('campaigns.parent'),
['campaigns.id', 'campaigns.name', 'campaigns.cid', 'campaigns.description', 'campaigns.type', 'campaigns.status', 'campaigns.scheduled', 'campaigns.source', 'campaigns.created', 'namespaces.name']
);
return await _listDTAjax(context, namespaceId, params);
}
async function listChildrenDTAjax(context, campaignId, params) {
@ -556,7 +557,7 @@ async function updateWithConsistencyCheck(context, entity, content) {
} else if (content === Content.WITHOUT_SOURCE_CUSTOM) {
filteredEntity.data.sourceCustom = existing.data.sourceCustom;
await namespaceHelpers.validateMove(context, entity, existing, 'campaign', 'createCampaign', 'delete'); //Doesn't works with filteredEntity
await namespaceHelpers.validateMove(context, filteredEntity, existing, 'campaign', 'createCampaign', 'delete'); // XXX TB - try with entity
} else if (content === Content.ONLY_SOURCE_CUSTOM) {
const data = existing.data;
@ -743,9 +744,9 @@ async function changeStatusByCampaignCidAndSubscriptionIdTx(tx, context, campaig
])
.first();
//if (!message) {
throw new Error('Invalid campaign.')
//}
if (!message) {
throw new Error('Invalid campaign.');
}
await _changeStatusByMessageTx(tx, context, message, subscriptionStatus);
}

View file

@ -26,16 +26,22 @@ function hash(entity) {
}
async function listDTAjax(context, params) {
async function _listDTAjax(context, namespaceId, params) {
const campaignEntityType = entitySettings.getEntityType('campaign');
return await dtHelpers.ajaxListWithPermissions(
context,
[{ entityTypeId: 'list', requiredOperations: ['view'] }],
params,
builder => builder
.from('lists')
.innerJoin('namespaces', 'namespaces.id', 'lists.namespace'),
builder => {
builder = builder
.from('lists')
.innerJoin('namespaces', 'namespaces.id', 'lists.namespace');
if (namespaceId) {
builder = builder.where('lists.namespace', namespaceId);
}
return builder;
},
['lists.id', 'lists.name', 'lists.cid', 'lists.subscribers', 'lists.description', 'namespaces.name',
{
name: 'triggerCount',
@ -53,32 +59,12 @@ async function listDTAjax(context, params) {
);
}
async function listByNamespaceDTAjax(context, namespaceId, params) {
const campaignEntityType = entitySettings.getEntityType('campaign');
async function listDTAjax(context, params) {
return await _listDTAjax(context, undefined, params);
}
return await dtHelpers.ajaxListWithPermissions(
context,
[{ entityTypeId: 'list', requiredOperations: ['view'] }],
params,
builder => builder
.from('lists')
.innerJoin('namespaces', 'namespaces.id', 'lists.namespace')
.where('lists.namespace', namespaceId),
['lists.id', 'lists.name', 'lists.cid', 'lists.subscribers', 'lists.description', 'namespaces.name',
{
name: 'triggerCount',
query: builder =>
builder.from('campaigns')
.innerJoin('campaign_lists', 'campaigns.id', 'campaign_lists.campaign')
.innerJoin('triggers', 'campaigns.id', 'triggers.campaign')
.innerJoin(campaignEntityType.permissionsTable, 'campaigns.id', `${campaignEntityType.permissionsTable}.entity`)
.whereRaw('campaign_lists.list = lists.id')
.where(`${campaignEntityType.permissionsTable}.operation`, 'viewTriggers')
.count()
.as('triggerCount')
}
]
);
async function listByNamespaceDTAjax(context, namespaceId, params) {
return await _listDTAjax(context, namespaceId, params);
}
async function listWithSegmentByCampaignDTAjax(context, campaignId, params) {

View file

@ -22,29 +22,30 @@ function hash(entity) {
return hasher.hash(filterObject(entity, allowedKeys));
}
async function listDTAjax(context, params) {
async function _listDTAjax(context, namespaceId, params) {
return await dtHelpers.ajaxListWithPermissions(
context,
[{ entityTypeId: 'sendConfiguration', requiredOperations: ['viewPublic'] }],
params,
builder => builder
.from('send_configurations')
.innerJoin('namespaces', 'namespaces.id', 'send_configurations.namespace'),
builder => {
builder = builder
.from('send_configurations')
.innerJoin('namespaces', 'namespaces.id', 'send_configurations.namespace');
if (namespaceId) {
builder = builder.where('send_configurations.namespace', namespaceId);
}
return builder;
},
['send_configurations.id', 'send_configurations.name', 'send_configurations.cid', 'send_configurations.description', 'send_configurations.mailer_type', 'send_configurations.created', 'namespaces.name']
);
}
async function listDTAjaxByNamespace(context, namespaceId, params) {
return await dtHelpers.ajaxListWithPermissions(
context,
[{ entityTypeId: 'sendConfiguration', requiredOperations: ['viewPublic'] }],
params,
builder => builder
.from('send_configurations')
.innerJoin('namespaces', 'namespaces.id', 'send_configurations.namespace')
.where('send_configurations.namespace', namespaceId),
['send_configurations.id', 'send_configurations.name', 'send_configurations.cid', 'send_configurations.description', 'send_configurations.mailer_type', 'send_configurations.created', 'namespaces.name']
);
async function listDTAjax(context, params) {
return await _listDTAjax(context, undefined, params);
}
async function listByNamespaceDTAjax(context, namespaceId, params) {
return await _listDTAjax(context, namespaceId, params);
}
async function listWithSendPermissionDTAjax(context, params) {
@ -188,7 +189,7 @@ async function getSystemSendConfiguration() {
module.exports.hash = hash;
module.exports.listDTAjax = listDTAjax;
module.exports.listDTAjaxByNamespace = listDTAjaxByNamespace;
module.exports.listByNamespaceDTAjax = listByNamespaceDTAjax;
module.exports.listWithSendPermissionDTAjax = listWithSendPermissionDTAjax;
module.exports.getByIdTx = getByIdTx;
module.exports.getById = getById;

View file

@ -36,24 +36,28 @@ async function getById(context, id, withPermissions = true) {
});
}
async function listDTAjax(context, params) {
async function _listDTAjax(context, namespaceId, params) {
return await dtHelpers.ajaxListWithPermissions(
context,
[{ entityTypeId: 'template', requiredOperations: ['view'] }],
params,
builder => builder.from('templates').innerJoin('namespaces', 'namespaces.id', 'templates.namespace'),
builder => {
builder = builder.from('templates').innerJoin('namespaces', 'namespaces.id', 'templates.namespace');
if (namespaceId) {
builder = builder.where('namespaces.id', namespaceId);
}
return builder;
},
[ 'templates.id', 'templates.name', 'templates.description', 'templates.type', 'templates.created', 'namespaces.name' ]
);
}
async function listByNamespaceDTAjax(context, params, namespaceId) {
return await dtHelpers.ajaxListWithPermissions(
context,
[{ entityTypeId: 'template', requiredOperations: ['view'] }],
params,
builder => builder.from('templates').innerJoin('namespaces', 'namespaces.id', 'templates.namespace').where('namespaces.id', namespaceId),
[ 'templates.id', 'templates.name', 'templates.description', 'templates.type', 'templates.created', 'namespaces.name' ]
);
async function listDTAjax(context, params) {
return await _listDTAjax(context, undefined, params);
}
async function listByNamespaceDTAjax(context, namespaceId, params) {
return await _listDTAjax(context, namespaceId, params);
}
async function _validateAndPreprocess(tx, entity) {

View file

@ -19,7 +19,7 @@ router.postAsync('/campaigns-others-by-list-table/:campaignId/:listIds', passpor
return res.json(await campaigns.listOthersWhoseListsAreIncludedDTAjax(req.context, castToInteger(req.params.campaignId), req.params.listIds.split(';').map(x => castToInteger(x)), req.body));
});
router.postAsync('/campaigns-namespace/:namespaceId', passport.loggedIn, async (req, res) => {
router.postAsync('/campaigns-by-namespace-table/:namespaceId', passport.loggedIn, async (req, res) => {
return res.json(await campaigns.listByNamespaceDTAjax(req.context, castToInteger(req.params.namespaceId), req.body));
});

View file

@ -11,7 +11,7 @@ router.postAsync('/lists-table', passport.loggedIn, async (req, res) => {
return res.json(await lists.listDTAjax(req.context, req.body));
});
router.postAsync('/users-table-byNamespace/:namespaceId', passport.loggedIn, async (req, res) => {
router.postAsync('/lists-by-namespace-table/:namespaceId', passport.loggedIn, async (req, res) => {
return res.json(await lists.listByNamespaceDTAjax(req.context, castToInteger(req.params.namespaceId), req.body));
});

View file

@ -40,8 +40,8 @@ router.postAsync('/send-configurations-table', passport.loggedIn, async (req, re
return res.json(await sendConfigurations.listDTAjax(req.context, req.body));
});
router.postAsync('/send-configurations-table-byNamespace/:namespaceId', passport.loggedIn, async (req, res) => {
return res.json(await sendConfigurations.listDTAjaxByNamespace(req.context, castToInteger(req.params.namespaceId), req.body));
router.postAsync('/send-configurations-by-namespace-table/:namespaceId', passport.loggedIn, async (req, res) => {
return res.json(await sendConfigurations.listByNamespaceDTAjax(req.context, castToInteger(req.params.namespaceId), req.body));
});
router.postAsync('/send-configurations-with-send-permission-table', passport.loggedIn, async (req, res) => {

View file

@ -35,8 +35,8 @@ router.postAsync('/templates-table', passport.loggedIn, async (req, res) => {
return res.json(await templates.listDTAjax(req.context, req.body));
});
router.postAsync('/templates-table-byNamespace/:namespaceId', passport.loggedIn, async (req, res) => {
return res.json(await templates.listByNamespaceDTAjax(req.context, req.body, castToInteger(req.params.namespaceId)));
router.postAsync('/templates-by-namespace-table/:namespaceId', passport.loggedIn, async (req, res) => {
return res.json(await templates.listByNamespaceDTAjax(req.context, castToInteger(req.params.namespaceId), req.body));
});
router.postAsync('/template-test-send', passport.loggedIn, passport.csrfProtection, async (req, res) => {