From d74806dde3c26fb7449ea7094815e7974904bf9b Mon Sep 17 00:00:00 2001 From: Tomas Bures Date: Sat, 1 Sep 2018 21:29:10 +0200 Subject: [PATCH] Basic import seems to work --- client/src/lists/imports/CUD.js | 50 +- client/src/lists/imports/RunStatus.js | 18 +- client/src/lists/imports/Status.js | 10 +- client/src/lists/imports/helpers.js | 3 +- client/src/lists/subscriptions/List.js | 1 + client/src/lists/subscriptions/helpers.js | 94 ++-- lib/importer.js | 4 +- lib/subscription-mail-helpers.js | 4 +- lib/tools.js | 10 +- models/fields.js | 128 +++-- models/import-runs.js | 24 +- models/shares.js | 5 +- models/subscriptions.js | 157 +++--- routes/api.js | 4 +- routes/rest/editors.js | 519 ------------------ routes/rest/import-runs.js | 4 + services/importer.js | 241 +++++++- .../migrations/20170506102634_v1_to_v2.js | 12 +- shared/imports.js | 3 +- shared/lists.js | 4 +- shared/users.js | 9 + 21 files changed, 555 insertions(+), 749 deletions(-) create mode 100644 shared/users.js diff --git a/client/src/lists/imports/CUD.js b/client/src/lists/imports/CUD.js index e09d9f91..fb014d9c 100644 --- a/client/src/lists/imports/CUD.js +++ b/client/src/lists/imports/CUD.js @@ -175,7 +175,7 @@ export default class CUD extends Component { } else { const mappingType = Number.parseInt(state.getIn(['mapping_type', 'value'])); - if (mappingType === MappingType.BASIC_SUBSCRIBE) { + if (mappingType === MappingType.BASIC_SUBSCRIBE || mappingType === MappingType.BASIC_UNSUBSCRIBE) { if (!state.getIn(['mapping_fields_email_column', 'value'])) { state.setIn(['mapping_fields_email_column', 'error'], t('Email mapping has to be provided')); } @@ -225,24 +225,33 @@ export default class CUD extends Component { for (const field of this.props.fieldsGrouped) { if (field.column) { - mapping.fields[field.column] = { - column: data['mapping_fields_' + field.column + '_column'] - }; + const colMapping = data['mapping_fields_' + field.column + '_column']; + if (colMapping) { + mapping.fields[field.column] = { + column: colMapping + }; + } } else { for (const option of field.settings.options) { const col = field.groupedOptions[option.key].column; - mapping.fields[col] = { - column: data['mapping_fields_' + col + '_column'] - }; + const colMapping = data['mapping_fields_' + col + '_column']; + if (colMapping) { + mapping.fields[col] = { + column: colMapping + }; + } } } } + } + if (data.mapping_type === MappingType.BASIC_SUBSCRIBE || data.mapping_type === MappingType.BASIC_UNSUBSCRIBE) { mapping.fields.email = { column: data.mapping_fields_email_column }; } + data.mapping = mapping; } @@ -317,7 +326,7 @@ export default class CUD extends Component { let mappingSettings = null; const mappingType = Number.parseInt(this.getFormValue('mapping_type')); - if (mappingType === MappingType.BASIC_SUBSCRIBE) { + if (mappingType === MappingType.BASIC_SUBSCRIBE || mappingType === MappingType.BASIC_UNSUBSCRIBE) { const sampleRow = this.getFormValue('sampleRow'); const sourceOpts = []; sourceOpts.push({key: '', label: t('–– Select ––')}); @@ -332,28 +341,33 @@ export default class CUD extends Component { } } + const settingsRows = []; const mappingRows = [ ]; - for (const field of this.props.fieldsGrouped) { - if (field.column) { - mappingRows.push( - - ); - } else { - for (const option of field.settings.options) { - const col = field.groupedOptions[option.key].column; + if (mappingType === MappingType.BASIC_SUBSCRIBE) { + settingsRows.push() + + for (const field of this.props.fieldsGrouped) { + if (field.column) { mappingRows.push( - + ); + } else { + for (const option of field.settings.options) { + const col = field.groupedOptions[option.key].column; + mappingRows.push( + + ); + } } } } mappingSettings = (
- + {settingsRows}
{mappingRows}
diff --git a/client/src/lists/imports/RunStatus.js b/client/src/lists/imports/RunStatus.js index d9ced7fc..67a42a59 100644 --- a/client/src/lists/imports/RunStatus.js +++ b/client/src/lists/imports/RunStatus.js @@ -18,6 +18,7 @@ import axios from "../../lib/axios"; import {getUrl} from "../../lib/urls"; import moment from "moment"; import {runStatusInProgress} from "../../../../shared/imports"; +import {Table} from "../../lib/table"; @translate() @withPageHelpers @@ -52,6 +53,10 @@ export default class Status extends Component { this.setState({ entity: resp.data }); + + if (this.failedTableNode) { + this.failedTableNode.refresh(); + } } async periodicRefreshTask() { @@ -77,7 +82,13 @@ export default class Status extends Component { const entity = this.state.entity; const imprt = this.props.imprt; - return ( + const columns = [ + { data: 1, title: t('Row') }, + { data: 2, title: t('Email') }, + { data: 3, title: t('Reason') } + ]; + + return (
{t('Import Run Status')} @@ -90,6 +101,11 @@ export default class Status extends Component { {entity.new} {entity.failed} {entity.error &&
{entity.error}
} + +
+

{t('Failed Rows')}

+ this.failedTableNode = node} withHeader dataUrl={`rest/import-run-failed-table/${this.props.list.id}/${this.props.imprt.id}/${this.props.entity.id}`} columns={columns} /> + ); } diff --git a/client/src/lists/imports/Status.js b/client/src/lists/imports/Status.js index eb0cba30..8b19becb 100644 --- a/client/src/lists/imports/Status.js +++ b/client/src/lists/imports/Status.js @@ -97,7 +97,10 @@ export default class Status extends Component { } await this.refreshEntity(); - this.runsTableNode.refresh(); + + if (this.runsTableNode) { + this.runsTableNode.refresh(); + } } async stopRunAsync() { @@ -112,7 +115,10 @@ export default class Status extends Component { } await this.refreshEntity(); - this.runsTableNode.refresh(); + + if (this.runsTableNode) { + this.runsTableNode.refresh(); + } } render() { diff --git a/client/src/lists/imports/helpers.js b/client/src/lists/imports/helpers.js index a99ccc62..0745a184 100644 --- a/client/src/lists/imports/helpers.js +++ b/client/src/lists/imports/helpers.js @@ -27,7 +27,8 @@ export function getImportTypes(t) { [RunStatus.SCHEDULED]: t('Starting'), [RunStatus.RUNNING]: t('Running'), [RunStatus.STOPPING]: t('Stopping'), - [RunStatus.FINISHED]: t('Finished') + [RunStatus.FINISHED]: t('Finished'), + [RunStatus.FAILED]: t('Failed') }; const mappingTypeLabels = { diff --git a/client/src/lists/subscriptions/List.js b/client/src/lists/subscriptions/List.js index 0bcd51bf..e166cf75 100644 --- a/client/src/lists/subscriptions/List.js +++ b/client/src/lists/subscriptions/List.js @@ -86,6 +86,7 @@ export default class List extends Component { const segments = this.props.segments; const columns = [ + { data: 1, title: t('CID') }, { data: 2, title: t('Email') }, { data: 3, title: t('Status'), render: (data, display, rowData) => this.subscriptionStatusLabels[data] + (rowData[5] ? ', ' + t('Blacklisted') : '') }, { data: 4, title: t('Created'), render: data => data ? moment(data).fromNow() : '' } diff --git a/client/src/lists/subscriptions/helpers.js b/client/src/lists/subscriptions/helpers.js index 06b22c1b..d43e6f77 100644 --- a/client/src/lists/subscriptions/helpers.js +++ b/client/src/lists/subscriptions/helpers.js @@ -4,7 +4,7 @@ import React from "react"; import {SubscriptionStatus} from "../../../../shared/lists"; import {ACEEditor, CheckBoxGroup, DatePicker, Dropdown, InputField, RadioGroup, TextArea} from "../../lib/form"; import {formatBirthday, formatDate, parseBirthday, parseDate} from "../../../../shared/date"; -import {getFieldKey} from '../../../../shared/lists'; +import {getFieldColumn} from '../../../../shared/lists'; import 'brace/mode/json'; export function getSubscriptionStatusLabels(t) { @@ -24,13 +24,13 @@ export function getFieldTypes(t) { const groupedFieldTypes = {}; const stringFieldType = long => ({ - form: groupedField => long ?