From b058169e1221f23d9e333115554294914e65ef62 Mon Sep 17 00:00:00 2001 From: Tomas Bures Date: Thu, 22 Nov 2018 11:31:16 +0100 Subject: [PATCH] Added confirmations for unsubscribe, blacklist and remove from blacklist --- client/src/blacklist/List.js | 43 ++++-- client/src/campaigns/List.js | 12 +- client/src/campaigns/Status.js | 2 +- client/src/campaigns/triggers/List.js | 12 +- client/src/lib/modals.js | 201 +++++++++++++++---------- client/src/lib/styles.scss | 2 +- client/src/lists/List.js | 12 +- client/src/lists/TriggersList.js | 12 +- client/src/lists/fields/List.js | 12 +- client/src/lists/forms/List.js | 12 +- client/src/lists/imports/List.js | 12 +- client/src/lists/segments/List.js | 12 +- client/src/lists/segments/helpers.js | 2 +- client/src/lists/subscriptions/List.js | 55 +++---- client/src/namespaces/List.js | 12 +- client/src/reports/List.js | 12 +- client/src/reports/templates/List.js | 12 +- client/src/send-configurations/List.js | 12 +- client/src/templates/List.js | 12 +- client/src/templates/mosaico/List.js | 12 +- client/src/users/List.js | 12 +- locales/en/common.json | 22 +-- server/models/blacklist.js | 1 + server/models/lists.js | 8 +- server/models/mosaico-templates.js | 2 - 25 files changed, 290 insertions(+), 228 deletions(-) diff --git a/client/src/blacklist/List.js b/client/src/blacklist/List.js index bc4fc3cc..07061b75 100644 --- a/client/src/blacklist/List.js +++ b/client/src/blacklist/List.js @@ -7,8 +7,13 @@ import {withAsyncErrorHandler, withErrorHandling} from "../lib/error-handling"; import {Table} from "../lib/table"; import {ButtonRow, Form, InputField, withForm, FormSendMethod} from "../lib/form"; import {Button, Icon} from "../lib/bootstrap-components"; -import axios from "../lib/axios"; +import axios, {HTTPMethod} from "../lib/axios"; import {getUrl} from "../lib/urls"; +import { + tableAddRestActionButton, + tableRestActionDialogInit, + tableRestActionDialogRender +} from "../lib/modals"; @withTranslation() @withForm @@ -22,6 +27,7 @@ export default class List extends Component { const t = props.t; this.state = {}; + tableRestActionDialogInit(this); this.initForm({ serverValidation: { @@ -73,7 +79,7 @@ export default class List extends Component { this.enableForm(); this.clearFormStatusMessage(); - this.blacklistTable.refresh(); + this.table.refresh(); } else { this.enableForm(); @@ -85,29 +91,36 @@ export default class List extends Component { this.clearFields(); } - @withAsyncErrorHandler - async deleteBlacklisted(email) { - await axios.delete(getUrl(`rest/blacklist/${email}`)); - this.blacklistTable.refresh(); - } - render() { const t = this.props.t; const columns = [ { data: 0, title: t('email') }, { - actions: data => [ - { - label: , - action: () => this.deleteBlacklisted(data[0]) - } - ] + actions: data => { + const actions = []; + + const email = data[0]; + + tableAddRestActionButton( + actions, this, + { method: HTTPMethod.DELETE, url: `rest/blacklist/${email}`}, + { icon: 'remove', label: t('removeFromBlacklist') }, + t('Confirm Removal From Blacklist'), + t('Are you sure you want to remove {{email}} from the blacklist?', {email}), + t('Removing {{email}} from the blacklist', {email}), + t('{{email}} removed from the blacklist', {email}), + null + ); + + return actions; + } } ]; return (
+ {tableRestActionDialogRender(this)} {t('blacklist')}

{t('addEmailToBlacklist-1')}

@@ -123,7 +136,7 @@ export default class List extends Component {

{t('blacklistedEmails')}

- this.blacklistTable = node} withHeader dataUrl="rest/blacklist-table" columns={columns} /> +
this.table = node} withHeader dataUrl="rest/blacklist-table" columns={columns} /> ); } diff --git a/client/src/campaigns/List.js b/client/src/campaigns/List.js index 2418d7de..31b874b0 100644 --- a/client/src/campaigns/List.js +++ b/client/src/campaigns/List.js @@ -27,9 +27,9 @@ import { import {checkPermissions} from "../lib/permissions"; import {getCampaignLabels} from "./helpers"; import { - tableDeleteDialogAddDeleteButton, - tableDeleteDialogInit, - tableDeleteDialogRender + tableAddDeleteButton, + tableRestActionDialogInit, + tableRestActionDialogRender } from "../lib/modals"; @withTranslation() @@ -47,7 +47,7 @@ export default class List extends Component { this.campaignStatusLabels = campaignStatusLabels; this.state = {}; - tableDeleteDialogInit(this); + tableRestActionDialogInit(this); } @withAsyncErrorHandler @@ -151,7 +151,7 @@ export default class List extends Component { }); } - tableDeleteDialogAddDeleteButton(actions, this, perms, data[0], data[1]); + tableAddDeleteButton(actions, this, perms, `rest/campaigns/${data[0]}`, data[1], t('deletingCampaign'), t('campaignDeleted')); return actions; } @@ -160,7 +160,7 @@ export default class List extends Component { return (
- {tableDeleteDialogRender(this, `rest/campaigns`, t('deletingCampaign'), t('campaignDeleted'))} + {tableRestActionDialogRender(this)} {this.state.createPermitted && diff --git a/client/src/campaigns/Status.js b/client/src/campaigns/Status.js index ab8401b2..ca314ae6 100644 --- a/client/src/campaigns/Status.js +++ b/client/src/campaigns/Status.js @@ -38,7 +38,7 @@ import { } from "../../../shared/campaigns"; import moment from 'moment'; import campaignsStyles from "./styles.scss"; -import {tableDeleteDialogAddDeleteButton} from "../lib/modals"; +import {tableAddDeleteButton} from "../lib/modals"; @withTranslation() diff --git a/client/src/campaigns/triggers/List.js b/client/src/campaigns/triggers/List.js index 91632009..6eaf72a6 100644 --- a/client/src/campaigns/triggers/List.js +++ b/client/src/campaigns/triggers/List.js @@ -16,9 +16,9 @@ import {getTriggerTypes} from './helpers'; import {Icon} from "../../lib/bootstrap-components"; import mailtrainConfig from 'mailtrainConfig'; import { - tableDeleteDialogAddDeleteButton, - tableDeleteDialogInit, - tableDeleteDialogRender + tableAddDeleteButton, + tableRestActionDialogInit, + tableRestActionDialogRender } from "../../lib/modals"; @withTranslation() @@ -34,7 +34,7 @@ export default class List extends Component { this.eventLabels = eventLabels; this.state = {}; - tableDeleteDialogInit(this); + tableRestActionDialogInit(this); } static propTypes = { @@ -66,7 +66,7 @@ export default class List extends Component { } if (this.props.campaign.permissions.includes('manageTriggers')) { - tableDeleteDialogAddDeleteButton(actions, this, null, data[0], data[1]); + tableAddDeleteButton(actions, this, null, `rest/triggers/${this.props.campaign.id}/${data[0]}`, data[1], t('deletingTrigger'), t('triggerDeleted')); } return actions; @@ -76,7 +76,7 @@ export default class List extends Component { return (
- {tableDeleteDialogRender(this, `rest/triggers/${this.props.campaign.id}`, t('deletingTrigger'), t('triggerDeleted'))} + {tableRestActionDialogRender(this)} {mailtrainConfig.globalPermissions.setupAutomation && this.props.campaign.permissions.includes('manageTriggers') && diff --git a/client/src/lib/modals.js b/client/src/lib/modals.js index ab6679d0..744506c6 100644 --- a/client/src/lib/modals.js +++ b/client/src/lib/modals.js @@ -24,6 +24,7 @@ export class RestActionModalDialog extends Component { visible: PropTypes.bool.isRequired, actionMethod: PropTypes.func.isRequired, actionUrl: PropTypes.string.isRequired, + actionData: PropTypes.object, backUrl: PropTypes.string, successUrl: PropTypes.string, @@ -65,7 +66,7 @@ export class RestActionModalDialog extends Component { owner.setFormStatusMessage('info', props.actionInProgressMsg); } - await axios.method(props.actionMethod, getUrl(props.actionUrl)); + await axios.method(props.actionMethod, getUrl(props.actionUrl), props.actionData); if (props.successUrl) { this.navigateToWithFlashMessage(props.successUrl, 'success', props.actionDoneMsg); @@ -96,6 +97,35 @@ export class RestActionModalDialog extends Component { } } +const entityTypeLabels = { + 'namespace': t => t('namespace'), + 'list': t => t('list'), + 'customForm': t => t('customForms'), + 'campaign': t => t('campaign'), + 'template': t => t('template'), + 'sendConfiguration': t => t('sendConfiguration'), + 'report': t => t('report'), + 'reportTemplate': t => t('reportTemplate'), + 'mosaicoTemplate': t => t('mosaicoTemplate') +}; + +function _getDependencyErrorMessage(err, t, name) { + return ( +
+

{t('cannoteDeleteNameDueToTheFollowing', {name})}

+
    + {err.data.dependencies.map(dep => + dep.link ? +
  • {entityTypeLabels[dep.entityTypeId](t)}: {dep.name}
  • + : // if no dep.link is present, it means the user has no permission to view the entity, thus only id without the link is shown +
  • {entityTypeLabels[dep.entityTypeId](t)}: [{dep.id}]
  • + )} + {err.data.andMore &&
  • {t('andMore')}
  • } +
+
+ ); +} + @withTranslation() @withPageHelpers @@ -103,35 +133,14 @@ export class DeleteModalDialog extends Component { constructor(props) { super(props); const t = props.t; - - this.entityTypeLabels = { - 'namespace': t('namespace'), - 'list': t('list'), - 'customForm': t('customForms'), - 'campaign': t('campaign'), - 'template': t('template'), - 'sendConfiguration': t('sendConfiguration'), - 'report': t('report'), - 'reportTemplate': t('reportTemplate'), - 'mosaicoTemplate': t('mosaicoTemplate') - }; } static propTypes = { visible: PropTypes.bool.isRequired, - - stateOwner: PropTypes.object, - name: PropTypes.string, + stateOwner: PropTypes.object.isRequired, deleteUrl: PropTypes.string.isRequired, - backUrl: PropTypes.string, successUrl: PropTypes.string, - - onBack: PropTypes.func, - onPerformingAction: PropTypes.func, - onSuccess: PropTypes.func, - onFail: PropTypes.func, - deletingMsg: PropTypes.string.isRequired, deletedMsg: PropTypes.string.isRequired } @@ -142,32 +151,13 @@ export class DeleteModalDialog extends Component { if (err instanceof interoperableErrors.DependencyPresentError) { const owner = this.props.stateOwner; - const name = this.props.name !== undefined ? this.props.name : (owner ? owner.getFormValue('name') : ''); - this.setFlashMessage('danger', -
-

{t('cannoteDeleteNameDueToTheFollowing', {name})}

-
    - {err.data.dependencies.map(dep => - dep.link ? -
  • {this.entityTypeLabels[dep.entityTypeId]}: {dep.name}
  • - : // if no dep.link is present, it means the user has no permission to view the entity, thus only id without the link is shown -
  • {this.entityTypeLabels[dep.entityTypeId]}: [{dep.id}]
  • - )} - {err.data.andMore &&
  • {t('andMore')}
  • } -
-
- ); + const name = owner.getFormValue('name'); + this.setFlashMessage('danger', _getDependencyErrorMessage(err, t, name)); window.scrollTo(0, 0); // This is to scroll up because the flash message appears on top and it's quite misleading if the delete fails and the message is not in the viewport - if (this.props.onFail) { - this.props.onFail(); - } - - if (owner) { - owner.enableForm(); - owner.clearFormStatusMessage(); - } + owner.enableForm(); + owner.clearFormStatusMessage(); } else { throw err; @@ -177,7 +167,7 @@ export 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') : ''); + const name = owner.getFormValue('name'); return }); @@ -215,10 +222,21 @@ export function tableDeleteDialogAddDeleteButton(actions, owner, perms, id, name actions.push({ label: , action: () => { - owner.deleteDialogData = {name, id}; + owner.tableRestActionDialogData = { + shown: true, + title: t('confirmDeletion'), + message:t('areYouSureYouWantToDeleteName?', {name}), + httpMethod: HTTPMethod.DELETE, + actionUrl: deleteUrl, + actionInProgressMsg: deletingMsg, + actionDoneMsg: deletedMsg, + onErrorAsync: onErrorAsync + }; + owner.setState({ - deleteDialogShown: true + tableRestActionDialogShown: true }); + owner.table.refresh(); } }); @@ -226,24 +244,55 @@ export function tableDeleteDialogAddDeleteButton(actions, owner, perms, id, name } } -export function tableDeleteDialogRender(owner, deleteUrlBase, deletingMsg, deletedMsg) { - function hide() { - owner.deleteDialogData = {}; - owner.setState({ deleteDialogShown: false }); - owner.table.refresh(); - } +export function tableAddRestActionButton(actions, owner, action, button, title, message, actionInProgressMsg, actionDoneMsg, onErrorAsync) { + const t = owner.props.t; + + if (owner.tableRestActionDialogData.shown) { + actions.push({ + label: + }); + } else { + actions.push({ + label: , + action: () => { + owner.tableRestActionDialogData = { + shown: true, + title: title, + message: message, + httpMethod: action.method, + actionUrl: action.url, + actionData: action.data, + actionInProgressMsg: actionInProgressMsg, + actionDoneMsg: actionDoneMsg, + onErrorAsync: onErrorAsync + }; + + owner.setState({ + tableRestActionDialogShown: true + }); + + owner.table.refresh(); + } + }); + } +} + +export function tableRestActionDialogRender(owner) { + const data = owner.tableRestActionDialogData; + + return _hide(owner)} + onPerformingAction={() => _hide(owner, true)} + onSuccess={() => _hide(owner)} + actionInProgressMsg={data.actionInProgressMsg || ''} + actionDoneMsg={data.actionDoneMsg || ''} + onErrorAsync={data.onErrorAsync} + /> - return ( - owner.setState({ deleteDialogShown: false })} - onSuccess={hide} - onFail={hide} - deletingMsg={deletingMsg} - deletedMsg={deletedMsg} - /> - ); } diff --git a/client/src/lib/styles.scss b/client/src/lib/styles.scss index 3424fd5c..5eaa24c6 100644 --- a/client/src/lib/styles.scss +++ b/client/src/lib/styles.scss @@ -140,7 +140,7 @@ } .iconDisabled { - color: #888; + color: #bf3e11; } .dependenciesList { diff --git a/client/src/lists/List.js b/client/src/lists/List.js index f43d918d..29a27464 100644 --- a/client/src/lists/List.js +++ b/client/src/lists/List.js @@ -10,9 +10,9 @@ import {Link} from "react-router-dom"; import {Icon} from "../lib/bootstrap-components"; import {checkPermissions} from "../lib/permissions"; import { - tableDeleteDialogAddDeleteButton, - tableDeleteDialogInit, - tableDeleteDialogRender + tableAddDeleteButton, + tableRestActionDialogInit, + tableRestActionDialogRender } from "../lib/modals"; @withTranslation() @@ -24,7 +24,7 @@ export default class List extends Component { super(props); this.state = {}; - tableDeleteDialogInit(this); + tableRestActionDialogInit(this); } @withAsyncErrorHandler @@ -121,7 +121,7 @@ export default class List extends Component { }); } - tableDeleteDialogAddDeleteButton(actions, this, perms, data[0], data[1]); + tableAddDeleteButton(actions, this, perms, `rest/lists/${data[0]}`, data[1], t('deletingList'), t('listDeleted')); return actions; } @@ -130,7 +130,7 @@ export default class List extends Component { return (
- {tableDeleteDialogRender(this, `rest/lists`, t('deletingList'), t('listDeleted'))} + {tableRestActionDialogRender(this)} {this.state.createPermitted && diff --git a/client/src/lists/TriggersList.js b/client/src/lists/TriggersList.js index 29d02e16..3b1582c7 100644 --- a/client/src/lists/TriggersList.js +++ b/client/src/lists/TriggersList.js @@ -14,9 +14,9 @@ import {getTriggerTypes} from '../campaigns/triggers/helpers'; import {Icon} from "../lib/bootstrap-components"; import mailtrainConfig from 'mailtrainConfig'; import { - tableDeleteDialogAddDeleteButton, - tableDeleteDialogInit, - tableDeleteDialogRender + tableAddDeleteButton, + tableRestActionDialogInit, + tableRestActionDialogRender } from "../lib/modals"; @withTranslation() @@ -32,7 +32,7 @@ export default class List extends Component { this.eventLabels = eventLabels; this.state = {}; - tableDeleteDialogInit(this); + tableRestActionDialogInit(this); } static propTypes = { @@ -67,7 +67,7 @@ export default class List extends Component { } if (perms.includes('manageTriggers')) { - tableDeleteDialogAddDeleteButton(actions, this, null, campaignId + '/' + data[0], data[1]); + tableAddDeleteButton(actions, this, null, `rest/triggers/${campaignId}/${data[0]}`, data[1], t('deletingTrigger'), t('triggerDeleted')); } return actions; @@ -77,7 +77,7 @@ export default class List extends Component { return (
- {tableDeleteDialogRender(this, `rest/triggers`, t('deletingTrigger'), t('triggerDeleted'))} + {tableRestActionDialogRender(this)} {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 f9461b13..53b4a8a3 100644 --- a/client/src/lists/fields/List.js +++ b/client/src/lists/fields/List.js @@ -9,9 +9,9 @@ import { Table } from '../../lib/table'; import { getFieldTypes } from './helpers'; import {Icon} from "../../lib/bootstrap-components"; import { - tableDeleteDialogAddDeleteButton, - tableDeleteDialogInit, - tableDeleteDialogRender + tableAddDeleteButton, + tableRestActionDialogInit, + tableRestActionDialogRender } from "../../lib/modals"; @withTranslation() @@ -23,7 +23,7 @@ export default class List extends Component { super(props); this.state = {}; - tableDeleteDialogInit(this); + tableRestActionDialogInit(this); this.fieldTypes = getFieldTypes(props.t); } @@ -55,7 +55,7 @@ export default class List extends Component { link: `/lists/${this.props.list.id}/fields/${data[0]}/edit` }); - tableDeleteDialogAddDeleteButton(actions, this, null, data[0], data[1]); + tableAddDeleteButton(actions, this, null, `rest/fields/${this.props.list.id}/${data[0]}`, data[1], t('deletingField'), t('fieldDeleted')); } return actions; @@ -65,7 +65,7 @@ export default class List extends Component { return (
- {tableDeleteDialogRender(this, `rest/fields/${this.props.list.id}`, t('deletingField'), t('fieldDeleted'))} + {tableRestActionDialogRender(this)} {this.props.list.permissions.includes('manageFields') && diff --git a/client/src/lists/forms/List.js b/client/src/lists/forms/List.js index a489fca2..f06c16c6 100644 --- a/client/src/lists/forms/List.js +++ b/client/src/lists/forms/List.js @@ -9,9 +9,9 @@ import axios from '../../lib/axios'; import {Icon} from "../../lib/bootstrap-components"; import {checkPermissions} from "../../lib/permissions"; import { - tableDeleteDialogAddDeleteButton, - tableDeleteDialogInit, - tableDeleteDialogRender + tableAddDeleteButton, + tableRestActionDialogInit, + tableRestActionDialogRender } from "../../lib/modals"; @withTranslation() @@ -23,7 +23,7 @@ export default class List extends Component { super(props); this.state = {}; - tableDeleteDialogInit(this); + tableRestActionDialogInit(this); } @withAsyncErrorHandler @@ -70,7 +70,7 @@ export default class List extends Component { }); } - tableDeleteDialogAddDeleteButton(actions, this, perms, data[0], data[1]); + tableAddDeleteButton(actions, this, perms, `rest/forms/${data[0]}`, data[1], t('deletingForm'), t('formDeleted')); return actions; } @@ -79,7 +79,7 @@ export default class List extends Component { return (
- {tableDeleteDialogRender(this, `rest/forms`, t('deletingForm'), t('formDeleted'))} + {tableRestActionDialogRender(this)} {this.state.createPermitted && diff --git a/client/src/lists/imports/List.js b/client/src/lists/imports/List.js index de31323a..506f4ee5 100644 --- a/client/src/lists/imports/List.js +++ b/client/src/lists/imports/List.js @@ -18,9 +18,9 @@ import mailtrainConfig from 'mailtrainConfig'; import moment from "moment"; import {inProgress} from '../../../../shared/imports'; import { - tableDeleteDialogAddDeleteButton, - tableDeleteDialogInit, - tableDeleteDialogRender + tableAddDeleteButton, + tableRestActionDialogInit, + tableRestActionDialogRender } from "../../lib/modals"; @withTranslation() @@ -32,7 +32,7 @@ export default class List extends Component { super(props); this.state = {}; - tableDeleteDialogInit(this); + tableRestActionDialogInit(this); const {importSourceLabels, importStatusLabels} = getImportLabels(props.t); this.importSourceLabels = importSourceLabels; @@ -79,7 +79,7 @@ export default class List extends Component { }); if (this.props.list.permissions.includes('manageImports')) { - tableDeleteDialogAddDeleteButton(actions, this, null, data[0], data[1]); + tableAddDeleteButton(actions, this, null, `rest/imports/${this.props.list.id}/${data[0]}`, data[1], t('deletingImport'), t('importDeleted')); } return { refreshTimeout, actions }; @@ -89,7 +89,7 @@ export default class List extends Component { return (
- {tableDeleteDialogRender(this, `rest/imports/${this.props.list.id}`, t('deletingImport'), t('importDeleted'))} + {tableRestActionDialogRender(this)} {mailtrainConfig.globalPermissions.setupAutomation && this.props.list.permissions.includes('manageImports') && diff --git a/client/src/lists/segments/List.js b/client/src/lists/segments/List.js index 053a673b..aa74d775 100644 --- a/client/src/lists/segments/List.js +++ b/client/src/lists/segments/List.js @@ -8,9 +8,9 @@ import { withErrorHandling } from '../../lib/error-handling'; import { Table } from '../../lib/table'; import {Icon} from "../../lib/bootstrap-components"; import { - tableDeleteDialogAddDeleteButton, - tableDeleteDialogInit, - tableDeleteDialogRender + tableAddDeleteButton, + tableRestActionDialogInit, + tableRestActionDialogRender } from "../../lib/modals"; @withTranslation() @@ -22,7 +22,7 @@ export default class List extends Component { super(props); this.state = {}; - tableDeleteDialogInit(this); + tableRestActionDialogInit(this); } static propTypes = { @@ -47,7 +47,7 @@ export default class List extends Component { link: `/lists/${this.props.list.id}/segments/${data[0]}/edit` }); - tableDeleteDialogAddDeleteButton(actions, this, null, data[0], data[1]); + tableAddDeleteButton(actions, this, null, `rest/segments/${this.props.list.id}/${data[0]}`, data[1], t('deletingSegment'), t('segmentDeleted')); } return actions; @@ -57,7 +57,7 @@ export default class List extends Component { return (
- {tableDeleteDialogRender(this, `rest/segments/${this.props.list.id}`, t('deletingSegment'), t('segmentDeleted'))} + {tableRestActionDialogRender(this)} {this.props.list.permissions.includes('manageSegments') && diff --git a/client/src/lists/segments/helpers.js b/client/src/lists/segments/helpers.js index 4897efc4..de19d765 100644 --- a/client/src/lists/segments/helpers.js +++ b/client/src/lists/segments/helpers.js @@ -129,7 +129,7 @@ export function getRuleHelpers(t, fields) { }, eqTodayPlusDays: { dropdownLabel: t('onXthDayBeforeafterCurrentDate'), - treeLabel: rule => getRelativeDateTreeLabel(rule, 'is', [tMark('dateInColumnColNameIsTheCurrentDate'), tMark('dateInColumnColNameIsValuethDayAfterThe'), tMark('dateInColumnColNameIsValuethDayBeforeThe')]), + treeLabel: rule => getRelativeDateTreeLabel(rule, [tMark('dateInColumnColNameIsTheCurrentDate'), tMark('dateInColumnColNameIsValuethDayAfterThe'), tMark('dateInColumnColNameIsValuethDayBeforeThe')]), }, ltTodayPlusDays: { dropdownLabel: t('beforeXthDayBeforeafterCurrentDate'), diff --git a/client/src/lists/subscriptions/List.js b/client/src/lists/subscriptions/List.js index 4de19058..7470d2aa 100644 --- a/client/src/lists/subscriptions/List.js +++ b/client/src/lists/subscriptions/List.js @@ -13,15 +13,16 @@ import { withForm } from '../../lib/form'; import {Icon, Button} from "../../lib/bootstrap-components"; -import axios, {HTTPMethod} from '../../lib/axios'; +import {HTTPMethod} from '../../lib/axios'; import {getFieldTypes, getSubscriptionStatusLabels} from './helpers'; import {getUrl, getPublicUrl} from "../../lib/urls"; import { DeleteModalDialog, RestActionModalDialog, - tableDeleteDialogAddDeleteButton, - tableDeleteDialogInit, - tableDeleteDialogRender + tableAddDeleteButton, + tableRestActionDialogInit, + tableRestActionDialogRender, + tableAddRestActionButton } from "../../lib/modals"; import listStyles from "../styles.scss"; import styles from '../../lib/styles.scss'; @@ -38,7 +39,7 @@ export default class List extends Component { const t = props.t; this.state = {}; - tableDeleteDialogInit(this); + tableRestActionDialogInit(this); this.subscriptionStatusLabels = getSubscriptionStatusLabels(t); this.fieldTypes = getFieldTypes(t); @@ -72,18 +73,6 @@ export default class List extends Component { this.updateSegmentSelection(nextProps); } - @withAsyncErrorHandler - async unsubscribeSubscription(id) { - await axios.post(getUrl(`rest/subscriptions-unsubscribe/${this.props.list.id}/${id}`)); - this.table.refresh(); - } - - @withAsyncErrorHandler - async blacklistSubscription(email) { - await axios.post(getUrl('rest/blacklist'), { email }); - this.table.refresh(); - } - render() { const t = this.props.t; const list = this.props.list; @@ -126,20 +115,32 @@ export default class List extends Component { }); if (email && status === SubscriptionStatus.SUBSCRIBED) { - actions.push({ - label: , - action: () => this.unsubscribeSubscription(id) - }); + tableAddRestActionButton( + actions, this, + { method: HTTPMethod.POST, url: `rest/subscriptions-unsubscribe/${this.props.list.id}/${id}`}, + { icon: 'off', label: t('unsubscribe') }, + t('Confirm Unsubscription'), + t('Are you sure you want to unsubscribe {{email}}?', {email}), + t('Unsubscribing {{email}}', {email}), + t('{{email}} unsubscribed', {email}), + null + ); } if (email && !data[5]) { - actions.push({ - label: , - action: () => this.blacklistSubscription(email) - }); + tableAddRestActionButton( + actions, this, + { method: HTTPMethod.POST, url: `rest/blacklist`, data: {email} }, + { icon: 'ban-circle', label: t('blacklist') }, + t('Confirm Email Blacklisting'), + t('Are you sure you want to blacklist {{email}}?', {email}), + t('Blacklisting {{email}}', {email}), + t('{{email}} blacklisted', {email}), + null + ); } - tableDeleteDialogAddDeleteButton(actions, this, null, id, email); + tableAddDeleteButton(actions, this, null, `rest/subscriptions/${this.props.list.id}/${id}`, email, t('deletingSubscription'), t('subscriptionDeleted')); return actions; } @@ -161,7 +162,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('deletingSubscription'), t('subscriptionDeleted'))} + {tableRestActionDialogRender(this)}