diff --git a/client/src/campaigns/List.js b/client/src/campaigns/List.js
index a1094163..bbd724d6 100644
--- a/client/src/campaigns/List.js
+++ b/client/src/campaigns/List.js
@@ -26,6 +26,11 @@ import {
} from "../../../shared/campaigns";
import {checkPermissions} from "../lib/permissions";
import {getCampaignLabels} from "./helpers";
+import {
+ tableDeleteDialogAddDeleteButton,
+ tableDeleteDialogInit,
+ tableDeleteDialogRender
+} from "../lib/modals";
@translate()
@withPageHelpers
@@ -42,6 +47,7 @@ export default class List extends Component {
this.campaignStatusLabels = campaignStatusLabels;
this.state = {};
+ tableDeleteDialogInit(this);
}
@withAsyncErrorHandler
@@ -145,6 +151,8 @@ export default class List extends Component {
});
}
+ tableDeleteDialogAddDeleteButton(actions, this, perms, data[0], data[1]);
+
return actions;
}
}
@@ -152,6 +160,7 @@ export default class List extends Component {
return (
+ {tableDeleteDialogRender(this, `rest/campaigns`, t('Deleting campaign ...'), t('Campaign deleted'))}
{this.state.createPermitted &&
@@ -164,7 +173,7 @@ export default class List extends Component {
{t('Campaigns')}
-
+ this.table = node} withHeader dataUrl="rest/campaigns-table" columns={columns} />
);
}
diff --git a/client/src/campaigns/triggers/List.js b/client/src/campaigns/triggers/List.js
index ef5913bc..ba077a1f 100644
--- a/client/src/campaigns/triggers/List.js
+++ b/client/src/campaigns/triggers/List.js
@@ -15,6 +15,11 @@ import {Table} from '../../lib/table';
import {getTriggerTypes} from './helpers';
import {Icon} from "../../lib/bootstrap-components";
import mailtrainConfig from 'mailtrainConfig';
+import {
+ tableDeleteDialogAddDeleteButton,
+ tableDeleteDialogInit,
+ tableDeleteDialogRender
+} from "../../lib/modals";
@translate()
@withPageHelpers
@@ -29,6 +34,7 @@ export default class List extends Component {
this.eventLabels = eventLabels;
this.state = {};
+ tableDeleteDialogInit(this);
}
static propTypes = {
@@ -59,6 +65,10 @@ export default class List extends Component {
});
}
+ if (perms.includes('manageTriggers')) {
+ tableDeleteDialogAddDeleteButton(actions, this, null, data[0], data[1]);
+ }
+
return actions;
}
}
@@ -66,6 +76,7 @@ export default class List extends Component {
return (
+ {tableDeleteDialogRender(this, `rest/triggers/${this.props.campaign.id}`, t('Deleting trigger ...'), t('Trigger deleted'))}
{mailtrainConfig.globalPermissions.includes('setupAutomation') && this.props.campaign.permissions.includes('manageTriggers') &&
@@ -74,7 +85,7 @@ export default class List extends Component {
{t('Triggers')}
-
+ this.table = node} withHeader dataUrl={`rest/triggers-by-campaign-table/${this.props.campaign.id}`} columns={columns} />
);
}
diff --git a/client/src/lib/files.js b/client/src/lib/files.js
index 3f2a9841..db9623cb 100644
--- a/client/src/lib/files.js
+++ b/client/src/lib/files.js
@@ -10,8 +10,7 @@ import {
import {withErrorHandling} from "./error-handling";
import {Table} from "./table";
import Dropzone from "react-dropzone";
-import {ModalDialog} from "./modals";
-import {Icon} from "./bootstrap-components";
+import {Icon, ModalDialog} from "./bootstrap-components";
import axios from './axios';
import styles from "./styles.scss";
import {withPageHelpers} from "./page";
diff --git a/client/src/lib/modals.js b/client/src/lib/modals.js
index cea106e6..9a226458 100644
--- a/client/src/lib/modals.js
+++ b/client/src/lib/modals.js
@@ -4,44 +4,72 @@ import React, { Component } from 'react';
import axios, { HTTPMethod } from './axios';
import { translate } from 'react-i18next';
import PropTypes from 'prop-types';
-import {ModalDialog} from "./bootstrap-components";
+import {
+ Icon,
+ ModalDialog
+} from "./bootstrap-components";
import {getUrl} from "./urls";
+import {withPageHelpers} from "./page";
+import styles from './styles.scss';
@translate()
-class RestActionModalDialog extends Component {
+@withPageHelpers
+export class RestActionModalDialog extends Component {
static propTypes = {
title: PropTypes.string.isRequired,
message: PropTypes.string.isRequired,
- stateOwner: PropTypes.object.isRequired,
+ stateOwner: PropTypes.object,
visible: PropTypes.bool.isRequired,
actionMethod: PropTypes.func.isRequired,
actionUrl: PropTypes.string.isRequired,
- backUrl: PropTypes.string.isRequired,
- successUrl: PropTypes.string.isRequired,
+ backUrl: PropTypes.string,
+ successUrl: PropTypes.string,
+ onBack: PropTypes.func,
+ onSuccess: PropTypes.func,
+ onPerformingAction: PropTypes.func,
actionInProgressMsg: PropTypes.string.isRequired,
actionDoneMsg: PropTypes.string.isRequired,
onErrorAsync: PropTypes.func
}
- async hideModal() {
- this.props.stateOwner.navigateTo(this.props.backUrl);
+ async hideModal(isBack) {
+ if (this.props.backUrl) {
+ this.props.stateOwner.navigateTo(this.props.backUrl);
+ } else {
+ if (isBack) {
+ this.props.onBack();
+ } else {
+ this.props.onPerformingAction();
+ }
+ }
}
async performAction() {
- const t = this.props.t;
- const owner = this.props.stateOwner;
+ const props = this.props;
+ const t = props.t;
+ const owner = props.stateOwner;
- await this.hideModal();
+ await this.hideModal(false);
try {
- owner.disableForm();
- owner.setFormStatusMessage('info', this.props.actionInProgressMsg);
- await axios.method(this.props.actionMethod, getUrl(this.props.actionUrl));
+ if (!owner) {
+ this.setFlashMessage('info', props.actionInProgressMsg);
+ } else {
+ owner.disableForm();
+ owner.setFormStatusMessage('info', props.actionInProgressMsg);
+ }
- owner.navigateToWithFlashMessage(this.props.successUrl, 'success', this.props.actionDoneMsg);
+ await axios.method(props.actionMethod, getUrl(props.actionUrl));
+
+ if (props.successUrl) {
+ owner.navigateToWithFlashMessage(props.successUrl, 'success', props.actionDoneMsg);
+ } else {
+ props.onSuccess();
+ this.setFlashMessage('success', props.actionDoneMsg);
+ }
} catch (err) {
- if (this.props.onErrorAsync) {
- await this.props.onErrorAsync(err);
+ if (props.onErrorAsync) {
+ await props.onErrorAsync(err);
} else {
throw err;
}
@@ -52,8 +80,8 @@ class RestActionModalDialog extends Component {
const t = this.props.t;
return (
- this.hideModal(true)} buttons={[
+ { label: t('No'), className: 'btn-primary', onClickAsync: () => this.hideModal(true) },
{ label: t('Yes'), className: 'btn-danger', onClickAsync: ::this.performAction }
]}>
{this.props.message}
@@ -63,13 +91,17 @@ class RestActionModalDialog extends Component {
}
@translate()
-class DeleteModalDialog extends Component {
+export class DeleteModalDialog extends Component {
static propTypes = {
- stateOwner: PropTypes.object.isRequired,
+ stateOwner: PropTypes.object,
visible: PropTypes.bool.isRequired,
deleteUrl: PropTypes.string.isRequired,
- backUrl: PropTypes.string.isRequired,
- successUrl: PropTypes.string.isRequired,
+ backUrl: PropTypes.string,
+ successUrl: PropTypes.string,
+ name: PropTypes.string,
+ onBack: PropTypes.func,
+ onSuccess: PropTypes.func,
+ onPerformingAction: PropTypes.func,
deletingMsg: PropTypes.string.isRequired,
deletedMsg: PropTypes.string.isRequired,
onErrorAsync: PropTypes.func
@@ -78,16 +110,20 @@ class DeleteModalDialog extends Component {
render() {
const t = this.props.t;
const owner = this.props.stateOwner;
+ const name = this.props.name !== undefined ? this.props.name : (owner ? owner.getFormValue('name') : '');
return
+ });
+ } else {
+ actions.push({
+ label: ,
+ action: () => {
+ owner.deleteDialogData = {name, id};
+ owner.setState({
+ deleteDialogShown: true
+ });
+ owner.table.refresh();
+ }
+ });
+ }
+ }
+}
+
+export function tableDeleteDialogRender(owner, deleteUrlBase, deletingMsg, deletedMsg) {
+ function hide() {
+ owner.deleteDialogData = {};
+ owner.setState({ deleteDialogShown: false });
+ owner.table.refresh();
+ }
+
+ return (
+ owner.setState({ deleteDialogShown: false })}
+ onSuccess={hide}
+ deletingMsg={deletingMsg}
+ deletedMsg={deletedMsg}
+ />
+ );
}
diff --git a/client/src/lib/styles.scss b/client/src/lib/styles.scss
index 3232f1f7..df9f5f25 100644
--- a/client/src/lib/styles.scss
+++ b/client/src/lib/styles.scss
@@ -131,4 +131,8 @@
.withElementInFullscreen {
height: 0px;
overflow: hidden;
+}
+
+.iconDisabled {
+ color: #888;
}
\ No newline at end of file
diff --git a/client/src/lib/tree.js b/client/src/lib/tree.js
index df1df29c..87f544a1 100644
--- a/client/src/lib/tree.js
+++ b/client/src/lib/tree.js
@@ -16,6 +16,7 @@ import { withPageHelpers } from './page'
import { withErrorHandling, withAsyncErrorHandler } from './error-handling';
import styles from "./styles.scss";
import {getUrl} from "./urls";
+import {Table} from "./table";
const TreeSelectMode = {
NONE: 0,
@@ -23,7 +24,7 @@ const TreeSelectMode = {
MULTI: 2
};
-@translate()
+@translate(null, { withRef: true })
@withPageHelpers
@withErrorHandling
class TreeTable extends Component {
@@ -46,6 +47,13 @@ class TreeTable extends Component {
selectMode: TreeSelectMode.NONE
}
+ refresh() {
+ if (this.tree) {
+ this.tree.reload(this.sanitizeTreeData(this.state.treeData));
+ this.updateSelection();
+ }
+ }
+
@withAsyncErrorHandler
async loadData(dataUrl) {
const response = await axios.get(getUrl(dataUrl));
@@ -323,6 +331,15 @@ class TreeTable extends Component {
}
}
+/*
+ Refreshes the table. This method is provided to allow programmatic refresh from a handler outside the table.
+ The reference to the table can be obtained by ref.
+ */
+TreeTable.prototype.refresh = function() {
+ this.getWrappedInstance().refresh();
+};
+
+
export {
TreeTable,
TreeSelectMode
diff --git a/client/src/lists/List.js b/client/src/lists/List.js
index c951a465..0bad6c5a 100644
--- a/client/src/lists/List.js
+++ b/client/src/lists/List.js
@@ -9,6 +9,11 @@ import axios from '../lib/axios';
import {Link} from "react-router-dom";
import {Icon} from "../lib/bootstrap-components";
import {checkPermissions} from "../lib/permissions";
+import {
+ tableDeleteDialogAddDeleteButton,
+ tableDeleteDialogInit,
+ tableDeleteDialogRender
+} from "../lib/modals";
@translate()
@withPageHelpers
@@ -19,6 +24,7 @@ export default class List extends Component {
super(props);
this.state = {};
+ tableDeleteDialogInit(this);
}
@withAsyncErrorHandler
@@ -115,6 +121,8 @@ export default class List extends Component {
});
}
+ tableDeleteDialogAddDeleteButton(actions, this, perms, data[0], data[1]);
+
return actions;
}
}
@@ -122,6 +130,7 @@ export default class List extends Component {
return (
+ {tableDeleteDialogRender(this, `rest/lists`, t('Deleting list ...'), t('List deleted'))}
{this.state.createPermitted &&
@@ -131,7 +140,7 @@ export default class List extends Component {
{t('Lists')}
-
+ this.table = node} withHeader dataUrl="rest/lists-table" columns={columns} />
);
}
diff --git a/client/src/lists/TriggersList.js b/client/src/lists/TriggersList.js
index f1ca0224..d986902d 100644
--- a/client/src/lists/TriggersList.js
+++ b/client/src/lists/TriggersList.js
@@ -13,6 +13,11 @@ import {Table} from '../lib/table';
import {getTriggerTypes} from '../campaigns/triggers/helpers';
import {Icon} from "../lib/bootstrap-components";
import mailtrainConfig from 'mailtrainConfig';
+import {
+ tableDeleteDialogAddDeleteButton,
+ tableDeleteDialogInit,
+ tableDeleteDialogRender
+} from "../lib/modals";
@translate()
@withPageHelpers
@@ -27,6 +32,7 @@ export default class List extends Component {
this.eventLabels = eventLabels;
this.state = {};
+ tableDeleteDialogInit(this);
}
static propTypes = {
@@ -60,6 +66,10 @@ export default class List extends Component {
});
}
+ if (perms.includes('manageTriggers')) {
+ tableDeleteDialogAddDeleteButton(actions, this, null, campaignId + '/' + data[0], data[1]);
+ }
+
return actions;
}
}
@@ -67,9 +77,10 @@ export default class List extends Component {
return (
+ {tableDeleteDialogRender(this, `rest/triggers`, t('Deleting trigger ...'), t('Trigger deleted'))}
{t('Triggers')}
-
+
this.table = node} withHeader dataUrl={`rest/triggers-by-list-table/${this.props.list.id}`} columns={columns} />
);
}
diff --git a/client/src/lists/fields/List.js b/client/src/lists/fields/List.js
index b3877fdb..c9823861 100644
--- a/client/src/lists/fields/List.js
+++ b/client/src/lists/fields/List.js
@@ -8,6 +8,11 @@ import { withErrorHandling } from '../../lib/error-handling';
import { Table } from '../../lib/table';
import { getFieldTypes } from './helpers';
import {Icon} from "../../lib/bootstrap-components";
+import {
+ tableDeleteDialogAddDeleteButton,
+ tableDeleteDialogInit,
+ tableDeleteDialogRender
+} from "../../lib/modals";
@translate()
@withPageHelpers
@@ -18,6 +23,7 @@ export default class List extends Component {
super(props);
this.state = {};
+ tableDeleteDialogInit(this);
this.fieldTypes = getFieldTypes(props.t);
}
@@ -48,6 +54,8 @@ export default class List extends Component {
label: ,
link: `/lists/${this.props.list.id}/fields/${data[0]}/edit`
});
+
+ tableDeleteDialogAddDeleteButton(actions, this, null, data[0], data[1]);
}
return actions;
@@ -57,6 +65,7 @@ export default class List extends Component {
return (
+ {tableDeleteDialogRender(this, `rest/fields/${this.props.list.id}`, t('Deleting field ...'), t('Field deleted'))}
{this.props.list.permissions.includes('manageFields') &&
@@ -65,7 +74,7 @@ export default class List extends Component {
{t('Fields')}
-
+ this.table = node} withHeader dataUrl={`rest/fields-table/${this.props.list.id}`} columns={columns} />
);
}
diff --git a/client/src/lists/forms/List.js b/client/src/lists/forms/List.js
index 5ee5325b..c46941a3 100644
--- a/client/src/lists/forms/List.js
+++ b/client/src/lists/forms/List.js
@@ -8,6 +8,11 @@ import { Table } from '../../lib/table';
import axios from '../../lib/axios';
import {Icon} from "../../lib/bootstrap-components";
import {checkPermissions} from "../../lib/permissions";
+import {
+ tableDeleteDialogAddDeleteButton,
+ tableDeleteDialogInit,
+ tableDeleteDialogRender
+} from "../../lib/modals";
@translate()
@withPageHelpers
@@ -18,6 +23,7 @@ export default class List extends Component {
super(props);
this.state = {};
+ tableDeleteDialogInit(this);
}
@withAsyncErrorHandler
@@ -64,6 +70,8 @@ export default class List extends Component {
});
}
+ tableDeleteDialogAddDeleteButton(actions, this, perms, data[0], data[1]);
+
return actions;
}
}
@@ -71,6 +79,7 @@ export default class List extends Component {
return (
+ {tableDeleteDialogRender(this, `rest/forms`, t('Deleting form ...'), t('Form deleted'))}
{this.state.createPermitted &&
@@ -79,7 +88,7 @@ export default class List extends Component {
{t('Forms')}
-
+ this.table = node} withHeader dataUrl="rest/forms-table" columns={columns} />
);
}
diff --git a/client/src/lists/imports/CUD.js b/client/src/lists/imports/CUD.js
index 9499321d..4c74d7e4 100644
--- a/client/src/lists/imports/CUD.js
+++ b/client/src/lists/imports/CUD.js
@@ -401,7 +401,7 @@ export default class CUD extends Component {
backUrl={`/lists/${this.props.list.id}/imports/${this.props.entity.id}/edit`}
successUrl={`/lists/${this.props.list.id}/imports`}
deletingMsg={t('Deleting import ...')}
- deletedMsg={t('Field deleted')}/>
+ deletedMsg={t('Import deleted')}/>
}
{isEdit ? t('Edit Import') : t('Create Import')}
diff --git a/client/src/lists/imports/List.js b/client/src/lists/imports/List.js
index 8995ed57..1fab499e 100644
--- a/client/src/lists/imports/List.js
+++ b/client/src/lists/imports/List.js
@@ -17,6 +17,11 @@ import {Icon} from "../../lib/bootstrap-components";
import mailtrainConfig from 'mailtrainConfig';
import moment from "moment";
import {inProgress} from '../../../../shared/imports';
+import {
+ tableDeleteDialogAddDeleteButton,
+ tableDeleteDialogInit,
+ tableDeleteDialogRender
+} from "../../lib/modals";
@translate()
@withPageHelpers
@@ -27,6 +32,7 @@ export default class List extends Component {
super(props);
this.state = {};
+ tableDeleteDialogInit(this);
const {importSourceLabels, importStatusLabels} = getImportLabels(props.t);
this.importSourceLabels = importSourceLabels;
@@ -72,6 +78,10 @@ export default class List extends Component {
link: `/lists/${this.props.list.id}/imports/${data[0]}/status`
});
+ if (this.props.list.permissions.includes('manageImports')) {
+ tableDeleteDialogAddDeleteButton(actions, this, null, data[0], data[1]);
+ }
+
return { refreshTimeout, actions };
}
}
@@ -79,6 +89,7 @@ export default class List extends Component {
return (
+ {tableDeleteDialogRender(this, `rest/imports/${this.props.list.id}`, t('Deleting import ...'), t('Import deleted'))}
{mailtrainConfig.globalPermissions.includes('setupAutomation') && this.props.list.permissions.includes('manageImports') &&
@@ -87,7 +98,7 @@ export default class List extends Component {
{t('Imports')}
-
+ this.table = node} withHeader dataUrl={`rest/imports-table/${this.props.list.id}`} columns={columns} />
);
}
diff --git a/client/src/lists/segments/List.js b/client/src/lists/segments/List.js
index b904591c..912acd0c 100644
--- a/client/src/lists/segments/List.js
+++ b/client/src/lists/segments/List.js
@@ -7,6 +7,11 @@ import {requiresAuthenticatedUser, withPageHelpers, Title, Toolbar, NavButton} f
import { withErrorHandling } from '../../lib/error-handling';
import { Table } from '../../lib/table';
import {Icon} from "../../lib/bootstrap-components";
+import {
+ tableDeleteDialogAddDeleteButton,
+ tableDeleteDialogInit,
+ tableDeleteDialogRender
+} from "../../lib/modals";
@translate()
@withPageHelpers
@@ -17,6 +22,7 @@ export default class List extends Component {
super(props);
this.state = {};
+ tableDeleteDialogInit(this);
}
static propTypes = {
@@ -40,6 +46,8 @@ export default class List extends Component {
label: ,
link: `/lists/${this.props.list.id}/segments/${data[0]}/edit`
});
+
+ tableDeleteDialogAddDeleteButton(actions, this, null, data[0], data[1]);
}
return actions;
@@ -49,6 +57,7 @@ export default class List extends Component {
return (
+ {tableDeleteDialogRender(this, `rest/segments/${this.props.list.id}`, t('Deleting segment ...'), t('Segment deleted'))}
{this.props.list.permissions.includes('manageSegments') &&
@@ -57,7 +66,7 @@ export default class List extends Component {
{t('Segment')}
-
+ this.table = node} withHeader dataUrl={`rest/segments-table/${this.props.list.id}`} columns={columns} />
);
}
diff --git a/client/src/lists/subscriptions/List.js b/client/src/lists/subscriptions/List.js
index fe0faa6d..0042fbed 100644
--- a/client/src/lists/subscriptions/List.js
+++ b/client/src/lists/subscriptions/List.js
@@ -16,6 +16,11 @@ import {Icon, Button} from "../../lib/bootstrap-components";
import axios from '../../lib/axios';
import {getFieldTypes, getSubscriptionStatusLabels} from './helpers';
import {getUrl, getPublicUrl} from "../../lib/urls";
+import {
+ tableDeleteDialogAddDeleteButton,
+ tableDeleteDialogInit,
+ tableDeleteDialogRender
+} from "../../lib/modals";
@translate()
@withForm
@@ -29,6 +34,7 @@ export default class List extends Component {
const t = props.t;
this.state = {};
+ tableDeleteDialogInit(this);
this.subscriptionStatusLabels = getSubscriptionStatusLabels(t);
this.fieldTypes = getFieldTypes(t);
@@ -62,22 +68,16 @@ export default class List extends Component {
this.updateSegmentSelection(nextProps);
}
- @withAsyncErrorHandler
- async deleteSubscription(id) {
- await axios.delete(getUrl(`rest/subscriptions/${this.props.list.id}/${id}`));
- this.blacklistTable.refresh();
- }
-
@withAsyncErrorHandler
async unsubscribeSubscription(id) {
await axios.post(getUrl(`rest/subscriptions-unsubscribe/${this.props.list.id}/${id}`));
- this.blacklistTable.refresh();
+ this.table.refresh();
}
@withAsyncErrorHandler
async blacklistSubscription(email) {
await axios.post(getUrl('rest/blacklist'), { email });
- this.blacklistTable.refresh();
+ this.table.refresh();
}
render() {
@@ -132,10 +132,7 @@ export default class List extends Component {
});
}
- actions.push({
- label: ,
- action: () => this.deleteSubscription(data[0])
- });
+ tableDeleteDialogAddDeleteButton(actions, this, null, data[0], data[2]);
return actions;
}
@@ -157,6 +154,7 @@ export default class List extends Component {
// FIXME - presents segments in a data table as in campaign edit
return (
+ {tableDeleteDialogRender(this, `rest/subscriptions/${this.props.list.id}`, t('Deleting subscription ...'), t('Subscription deleted'))}
@@ -175,7 +173,7 @@ export default class List extends Component {
- this.blacklistTable = node} withHeader dataUrl={dataUrl} columns={columns} />
+ this.table = node} withHeader dataUrl={dataUrl} columns={columns} />
);
}
diff --git a/client/src/namespaces/List.js b/client/src/namespaces/List.js
index 7992128f..e54fc14d 100644
--- a/client/src/namespaces/List.js
+++ b/client/src/namespaces/List.js
@@ -8,6 +8,11 @@ import { withErrorHandling, withAsyncErrorHandler } from '../lib/error-handling'
import axios from '../lib/axios';
import {Icon} from "../lib/bootstrap-components";
import {checkPermissions} from "../lib/permissions";
+import {
+ tableDeleteDialogAddDeleteButton,
+ tableDeleteDialogInit,
+ tableDeleteDialogRender
+} from "../lib/modals";
@translate()
@withErrorHandling
@@ -18,6 +23,7 @@ export default class List extends Component {
super(props);
this.state = {};
+ tableDeleteDialogInit(this);
}
@withAsyncErrorHandler
@@ -44,6 +50,7 @@ export default class List extends Component {
const actions = node => {
const actions = [];
+ console.log(node);
if (node.data.permissions.includes('edit')) {
actions.push({
@@ -59,11 +66,14 @@ export default class List extends Component {
});
}
+ tableDeleteDialogAddDeleteButton(actions, this, node.data.permissions, node.key, node.key);
+
return actions;
};
return (
+ {tableDeleteDialogRender(this, `rest/namespaces`, t('Deleting namespace ...'), t('Namespace deleted'))}
{this.state.createPermitted &&
@@ -72,7 +82,7 @@ export default class List extends Component {
{t('Namespaces')}
-
+ this.table = node} withHeader withDescription dataUrl="rest/namespaces-tree" actions={actions} />
);
}
diff --git a/client/src/reports/List.js b/client/src/reports/List.js
index 29440c73..79242dbf 100644
--- a/client/src/reports/List.js
+++ b/client/src/reports/List.js
@@ -11,6 +11,11 @@ import { ReportState } from '../../../shared/reports';
import {Icon} from "../lib/bootstrap-components";
import {checkPermissions} from "../lib/permissions";
import {getUrl} from "../lib/urls";
+import {
+ tableDeleteDialogAddDeleteButton,
+ tableDeleteDialogInit,
+ tableDeleteDialogRender
+} from "../lib/modals";
@translate()
@withErrorHandling
@@ -21,6 +26,7 @@ export default class List extends Component {
super(props);
this.state = {};
+ tableDeleteDialogInit(this);
}
@withAsyncErrorHandler
@@ -159,6 +165,8 @@ export default class List extends Component {
});
}
+ tableDeleteDialogAddDeleteButton(actions, this, perms, data[0], data[1]);
+
return { refreshTimeout, actions };
}
}
@@ -167,6 +175,7 @@ export default class List extends Component {
return (
+ {tableDeleteDialogRender(this, `rest/reports`, t('Deleting report ...'), t('Report deleted'))}
{this.state.createPermitted &&
@@ -178,7 +187,7 @@ export default class List extends Component {
{t('Reports')}
-
+ this.table = node} withHeader dataUrl="rest/reports-table" columns={columns} />
);
}
diff --git a/client/src/reports/templates/List.js b/client/src/reports/templates/List.js
index 3531f1f9..310289e9 100644
--- a/client/src/reports/templates/List.js
+++ b/client/src/reports/templates/List.js
@@ -10,6 +10,11 @@ import axios from '../../lib/axios';
import moment from 'moment';
import mailtrainConfig from 'mailtrainConfig';
import {checkPermissions} from "../../lib/permissions";
+import {
+ tableDeleteDialogAddDeleteButton,
+ tableDeleteDialogInit,
+ tableDeleteDialogRender
+} from "../../lib/modals";
@translate()
@withPageHelpers
@@ -20,6 +25,7 @@ export default class List extends Component {
super(props);
this.state = {};
+ tableDeleteDialogInit(this);
}
@withAsyncErrorHandler
@@ -68,6 +74,8 @@ export default class List extends Component {
});
}
+ tableDeleteDialogAddDeleteButton(actions, this, perms, data[0], data[1]);
+
return actions;
}
}
@@ -75,6 +83,7 @@ export default class List extends Component {
return (
+ {tableDeleteDialogRender(this, `rest/reports/templates`, t('Deleting report template ...'), t('Report template deleted'))}
{this.state.createPermitted &&
@@ -88,7 +97,7 @@ export default class List extends Component {
{t('Report Templates')}
-
+ this.table = node} withHeader dataUrl="rest/report-templates-table" columns={columns} />
);
}
diff --git a/client/src/send-configurations/List.js b/client/src/send-configurations/List.js
index fbe81091..7c04cf29 100644
--- a/client/src/send-configurations/List.js
+++ b/client/src/send-configurations/List.js
@@ -19,6 +19,11 @@ import axios from '../lib/axios';
import moment from 'moment';
import {getMailerTypes} from './helpers';
import {checkPermissions} from "../lib/permissions";
+import {
+ tableDeleteDialogAddDeleteButton,
+ tableDeleteDialogInit,
+ tableDeleteDialogRender
+} from "../lib/modals";
@translate()
@@ -32,6 +37,7 @@ export default class List extends Component {
this.mailerTypes = getMailerTypes(props.t);
this.state = {};
+ tableDeleteDialogInit(this);
}
@withAsyncErrorHandler
@@ -82,6 +88,8 @@ export default class List extends Component {
});
}
+ tableDeleteDialogAddDeleteButton(actions, this, perms, data[0], data[1]);
+
return actions;
}
}
@@ -89,6 +97,7 @@ export default class List extends Component {
return (
+ {tableDeleteDialogRender(this, `rest/send-configurations`, t('Deleting send configuration ...'), t('Send configuration deleted'))}
{this.state.createPermitted &&
@@ -97,7 +106,7 @@ export default class List extends Component {
{t('Send Configurations')}
-
+ this.table = node} withHeader dataUrl="rest/send-configurations-table" columns={columns} />
);
}
diff --git a/client/src/templates/List.js b/client/src/templates/List.js
index 7738234b..1be3d9c6 100644
--- a/client/src/templates/List.js
+++ b/client/src/templates/List.js
@@ -18,6 +18,11 @@ import {Table} from '../lib/table';
import moment from 'moment';
import {getTemplateTypes} from './helpers';
import {checkPermissions} from "../lib/permissions";
+import {
+ tableDeleteDialogAddDeleteButton,
+ tableDeleteDialogInit,
+ tableDeleteDialogRender
+} from "../lib/modals";
@translate()
@withPageHelpers
@@ -30,6 +35,7 @@ export default class List extends Component {
this.templateTypes = getTemplateTypes(props.t);
this.state = {};
+ tableDeleteDialogInit(this);
}
@withAsyncErrorHandler
@@ -95,6 +101,8 @@ export default class List extends Component {
});
}
+ tableDeleteDialogAddDeleteButton(actions, this, perms, data[0], data[1]);
+
return actions;
}
}
@@ -102,6 +110,7 @@ export default class List extends Component {
return (
+ {tableDeleteDialogRender(this, `rest/templates`, t('Deleting template ...'), t('Template deleted'))}
{this.state.createPermitted &&
@@ -113,7 +122,7 @@ export default class List extends Component {
{t('Templates')}
-
+ this.table = node} withHeader dataUrl="rest/templates-table" columns={columns} />
);
}
diff --git a/client/src/templates/mosaico/List.js b/client/src/templates/mosaico/List.js
index f35f323a..2b6717fa 100644
--- a/client/src/templates/mosaico/List.js
+++ b/client/src/templates/mosaico/List.js
@@ -10,6 +10,11 @@ import axios from '../../lib/axios';
import moment from 'moment';
import { getTemplateTypes } from './helpers';
import {checkPermissions} from "../../lib/permissions";
+import {
+ tableDeleteDialogAddDeleteButton,
+ tableDeleteDialogInit,
+ tableDeleteDialogRender
+} from "../../lib/modals";
@translate()
@@ -23,6 +28,7 @@ export default class List extends Component {
this.templateTypes = getTemplateTypes(props.t);
this.state = {};
+ tableDeleteDialogInit(this);
}
@withAsyncErrorHandler
@@ -86,6 +92,8 @@ export default class List extends Component {
});
}
+ tableDeleteDialogAddDeleteButton(actions, this, perms, data[0], data[1]);
+
return actions;
}
}
@@ -93,6 +101,7 @@ export default class List extends Component {
return (
+ {tableDeleteDialogRender(this, `rest/mosaico-templates`, t('Deleting Mosaico template ...'), t('Mosaico template deleted'))}
{this.state.createPermitted &&
@@ -104,7 +113,7 @@ export default class List extends Component {
{t('Mosaico Templates')}
-
+ this.table = node} withHeader dataUrl="rest/mosaico-templates-table" columns={columns} />
);
}
diff --git a/client/src/users/List.js b/client/src/users/List.js
index ababadf0..565e5334 100644
--- a/client/src/users/List.js
+++ b/client/src/users/List.js
@@ -6,6 +6,11 @@ import {NavButton, requiresAuthenticatedUser, Title, Toolbar, withPageHelpers} f
import {Table} from "../lib/table";
import mailtrainConfig from "mailtrainConfig";
import {Icon} from "../lib/bootstrap-components";
+import {
+ tableDeleteDialogAddDeleteButton,
+ tableDeleteDialogInit,
+ tableDeleteDialogRender
+} from "../lib/modals";
@translate()
@withPageHelpers
@@ -13,6 +18,9 @@ import {Icon} from "../lib/bootstrap-components";
export default class List extends Component {
constructor(props) {
super(props);
+
+ this.state = {};
+ tableDeleteDialogInit(this);
}
render() {
@@ -33,27 +41,35 @@ export default class List extends Component {
columns.push({ data: 4, title: "Role" });
columns.push({
- actions: data => [
- {
+ actions: data => {
+ const actions = [];
+
+ actions.push({
label: ,
link: `/users/${data[0]}/edit`
- },
- {
+ });
+
+ actions.push({
label: ,
link: `/users/${data[0]}/shares`
- }
- ]
+ });
+
+ tableDeleteDialogAddDeleteButton(actions, this, null, data[0], data[1]);
+
+ return actions;
+ }
});
return (
+ {tableDeleteDialogRender(this, `rest/users`, t('Deleting user ...'), t('User deleted'))}
{t('Users')}
-
+
this.table = node} withHeader dataUrl="rest/users-table" columns={columns} />
);
}
diff --git a/models/subscriptions.js b/models/subscriptions.js
index a8dacea2..e5a6e3e5 100644
--- a/models/subscriptions.js
+++ b/models/subscriptions.js
@@ -578,7 +578,7 @@ async function _removeAndGetTx(tx, context, listId, existing) {
throw new interoperableErrors.NotFoundError();
}
- await tx(getSubscriptionTableName(listId)).where('id', id).del();
+ await tx(getSubscriptionTableName(listId)).where('id', existing.id).del();
if (existing.status === SubscriptionStatus.SUBSCRIBED) {
await tx('lists').where('id', listId).decrement('subscribers', 1);