Add column selection to data table
[MAILPOET-1809]
This commit is contained in:
@@ -158,269 +158,6 @@ jQuery(document).ready(() => {
|
|||||||
? data
|
? data
|
||||||
: new Handlebars.SafeString(Handlebars.Utils.escapeExpression(data))));
|
: new Handlebars.SafeString(Handlebars.Utils.escapeExpression(data))));
|
||||||
|
|
||||||
// start array index from 1
|
|
||||||
Handlebars.registerHelper('calculate_index', (rawIndex) => {
|
|
||||||
const index = parseInt(rawIndex, 10);
|
|
||||||
// display filler data (e.g., ellipsis) if we've reached the maximum number of rows and
|
|
||||||
// subscribers count is greater than the maximum number of rows we're displaying
|
|
||||||
if (index === maxRowsToShow && subscribers.subscribersCount > (maxRowsToShow + 1)) {
|
|
||||||
fillerPosition = index;
|
|
||||||
return filler;
|
|
||||||
}
|
|
||||||
if (index === (subscribers.subscribers.length - 1)) {
|
|
||||||
// if we're on the last line, show the total count of subscribers data
|
|
||||||
return subscribers.subscribersCount.toLocaleString();
|
|
||||||
}
|
|
||||||
return index + 1;
|
|
||||||
});
|
|
||||||
|
|
||||||
// reduce subscribers object if the total length is greater than the
|
|
||||||
// maximum number of defined rows
|
|
||||||
if (subscribers.subscribersCount > (maxRowsToShow + 1)) {
|
|
||||||
subscribers.subscribers.splice(
|
|
||||||
maxRowsToShow, subscribers.subscribersCount - (maxRowsToShow + 1),
|
|
||||||
fillerArray
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// filter subscribers' data to detect dates, emails, etc.
|
|
||||||
function filterSubscribers() {
|
|
||||||
const subscribersClone = jQuery.extend(true, {}, subscribers);
|
|
||||||
let preventNextStep = false;
|
|
||||||
jQuery(
|
|
||||||
'[data-id="notice_invalidEmail"], [data-id="notice_invalidDate"]'
|
|
||||||
)
|
|
||||||
.remove();
|
|
||||||
const displayedColumns = jQuery.map(
|
|
||||||
jQuery('.mailpoet_subscribers_column_data_match'), (element, elementIndex) => {
|
|
||||||
const columnId = jQuery(element).data('column-id');
|
|
||||||
const validationRule = jQuery(element).data('validation-rule');
|
|
||||||
jQuery(element).val(columnId).trigger('change');
|
|
||||||
return {
|
|
||||||
id: columnId,
|
|
||||||
index: elementIndex,
|
|
||||||
validationRule,
|
|
||||||
element,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
);
|
|
||||||
// iterate through the object of mailpoet columns
|
|
||||||
jQuery.map(window.mailpoetColumns, (column) => {
|
|
||||||
let firstRowData;
|
|
||||||
let validationRule;
|
|
||||||
let testedFormat;
|
|
||||||
let allowedDateFormats;
|
|
||||||
// check if the column id matches the selected id of one of the
|
|
||||||
// subscriber's data columns
|
|
||||||
const matchedColumn = _.find(
|
|
||||||
displayedColumns,
|
|
||||||
data => data.id === column.id
|
|
||||||
);
|
|
||||||
// EMAIL filter: if the first value in the column doesn't have a valid
|
|
||||||
// email, hide the next button
|
|
||||||
if (column.id === 'email') {
|
|
||||||
if (!window.mailpoet_email_regex.test(
|
|
||||||
subscribersClone.subscribers[0][matchedColumn.index]
|
|
||||||
)
|
|
||||||
) {
|
|
||||||
preventNextStep = true;
|
|
||||||
if (!jQuery('[data-id="notice_invalidEmail"]').length) {
|
|
||||||
MailPoet.Notice.error(MailPoet.I18n.t('columnContainsInvalidElement'), {
|
|
||||||
static: true,
|
|
||||||
scroll: true,
|
|
||||||
hideClose: true,
|
|
||||||
id: 'invalidEmail',
|
|
||||||
});
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
MailPoet.Notice.hide('invalidEmail');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// DATE filter: if column type is date, check if we can recognize it
|
|
||||||
if (column.type === 'date' && matchedColumn) {
|
|
||||||
allowedDateFormats = [
|
|
||||||
Moment.ISO_8601,
|
|
||||||
'YYYY/MM/DD',
|
|
||||||
'MM/DD/YYYY',
|
|
||||||
'DD/MM/YYYY',
|
|
||||||
'YYYY/MM/DD',
|
|
||||||
'YYYY/DD/MM',
|
|
||||||
'MM/YYYY',
|
|
||||||
'YYYY/MM',
|
|
||||||
'YYYY',
|
|
||||||
];
|
|
||||||
firstRowData = subscribersClone.subscribers[0][matchedColumn.index];
|
|
||||||
validationRule = false;
|
|
||||||
// check if date exists
|
|
||||||
if (firstRowData.trim() === '') {
|
|
||||||
subscribersClone.subscribers[0][matchedColumn.index] = `<span class="mailpoet_data_match mailpoet_import_error" title="${MailPoet.I18n.t('noDateFieldMatch')}">${MailPoet.I18n.t('emptyFirstRowDate')}</span> `;
|
|
||||||
preventNextStep = true;
|
|
||||||
} else {
|
|
||||||
Object.keys(allowedDateFormats).forEach((format) => {
|
|
||||||
testedFormat = allowedDateFormats[format];
|
|
||||||
if (Moment(firstRowData, testedFormat, true).isValid()) {
|
|
||||||
validationRule = (typeof (testedFormat) === 'function')
|
|
||||||
? 'datetime'
|
|
||||||
: testedFormat;
|
|
||||||
// set validation on the column element
|
|
||||||
jQuery(matchedColumn.element).data('validation-rule', validationRule);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (validationRule === 'datetime') {
|
|
||||||
validationRule = Moment.ISO_8601;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
jQuery.map(subscribersClone.subscribers, (dataSubscribers, index) => {
|
|
||||||
const data = dataSubscribers;
|
|
||||||
const rowData = data[matchedColumn.index];
|
|
||||||
const date = Moment(rowData, testedFormat, true);
|
|
||||||
if (index === fillerPosition || rowData.trim() === '') return;
|
|
||||||
// validate date
|
|
||||||
if (date.isValid()) {
|
|
||||||
data[matchedColumn.index] = new Handlebars.SafeString(
|
|
||||||
`${Handlebars.Utils.escapeExpression(data[matchedColumn.index])}<span class="mailpoet_data_match" title="${MailPoet.I18n.t('verifyDateMatch')}">${MailPoet.Date.format(date)}</span> `
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
data[matchedColumn.index] = new Handlebars.SafeString(
|
|
||||||
`${Handlebars.Utils.escapeExpression(data[matchedColumn.index])}<span class="mailpoet_data_match mailpoet_import_error" title="${MailPoet.I18n.t('noDateFieldMatch')}">${new Handlebars.SafeString(MailPoet.I18n.t('dateMatchError'))}</span> `
|
|
||||||
);
|
|
||||||
preventNextStep = true;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
if (preventNextStep && !jQuery('.mailpoet_invalidDate').length) {
|
|
||||||
MailPoet.Notice.error(MailPoet.I18n.t('columnContainsInvalidDate'), {
|
|
||||||
static: true,
|
|
||||||
scroll: true,
|
|
||||||
hideClose: true,
|
|
||||||
id: 'invalidDate',
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
// refresh table with susbcribers' data
|
|
||||||
jQuery('#subscribers_data > table > tbody')
|
|
||||||
.html(subscribersDataTemplatePartial(subscribersClone));
|
|
||||||
|
|
||||||
if (preventNextStep) {
|
|
||||||
toggleNextStepButton('off');
|
|
||||||
} else if (!jQuery('.mailpoet_notice.error:visible').length
|
|
||||||
&& segmentSelectElement.val()) {
|
|
||||||
toggleNextStepButton('on');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// render template
|
|
||||||
jQuery('#subscribers_data > table').html(subscribersDataTemplate(subscribers));
|
|
||||||
|
|
||||||
// filter displayed data
|
|
||||||
jQuery('select.mailpoet_subscribers_column_data_match')
|
|
||||||
.select2({
|
|
||||||
data: window.mailpoetColumnsSelect2,
|
|
||||||
width: '15em',
|
|
||||||
templateResult(item) {
|
|
||||||
return item.name;
|
|
||||||
},
|
|
||||||
templateSelection(item) {
|
|
||||||
return item.name;
|
|
||||||
},
|
|
||||||
})
|
|
||||||
.on('select2:selecting', (selectEvent) => {
|
|
||||||
const selectElement = selectEvent.currentTarget;
|
|
||||||
const selectedOptionId = selectEvent.params.args.data.id;
|
|
||||||
// CREATE CUSTOM FIELD
|
|
||||||
if (selectedOptionId === 'create') {
|
|
||||||
selectEvent.preventDefault();
|
|
||||||
jQuery(selectElement).select2('close');
|
|
||||||
MailPoet.Modal.popup({
|
|
||||||
title: MailPoet.I18n.t('addNewField'),
|
|
||||||
template: jQuery('#form_template_field_form').html(),
|
|
||||||
});
|
|
||||||
jQuery('#form_field_new').parsley().on('form:submit', () => {
|
|
||||||
// get data
|
|
||||||
const data = jQuery('#form_field_new').mailpoetSerializeObject();
|
|
||||||
|
|
||||||
// save custom field
|
|
||||||
MailPoet.Ajax.post({
|
|
||||||
api_version: window.mailpoet_api_version,
|
|
||||||
endpoint: 'customFields',
|
|
||||||
action: 'save',
|
|
||||||
data,
|
|
||||||
}).done((response) => {
|
|
||||||
const newColumnData = {
|
|
||||||
id: response.data.id,
|
|
||||||
name: response.data.name,
|
|
||||||
type: response.data.type,
|
|
||||||
params: response.data.params,
|
|
||||||
custom: true,
|
|
||||||
};
|
|
||||||
// if this is the first custom column, create an "optgroup"
|
|
||||||
if (window.mailpoetColumnsSelect2.length === 2) {
|
|
||||||
window.mailpoetColumnsSelect2.push({
|
|
||||||
name: MailPoet.I18n.t('userColumns'),
|
|
||||||
children: [],
|
|
||||||
});
|
|
||||||
}
|
|
||||||
window.mailpoetColumnsSelect2[2].children.push(newColumnData);
|
|
||||||
window.mailpoetColumns.push(newColumnData);
|
|
||||||
jQuery('select.mailpoet_subscribers_column_data_match')
|
|
||||||
.each(() => {
|
|
||||||
jQuery(selectElement)
|
|
||||||
.html('')
|
|
||||||
.select2('destroy')
|
|
||||||
.select2({
|
|
||||||
data: window.mailpoetColumnsSelect2,
|
|
||||||
width: '15em',
|
|
||||||
templateResult(item) {
|
|
||||||
return item.name;
|
|
||||||
},
|
|
||||||
templateSelection(item) {
|
|
||||||
return item.name;
|
|
||||||
},
|
|
||||||
});
|
|
||||||
});
|
|
||||||
jQuery(selectElement).data('column-id', newColumnData.id);
|
|
||||||
jQuery(selectElement).data('validation-rule', false);
|
|
||||||
filterSubscribers();
|
|
||||||
// close popup
|
|
||||||
MailPoet.Modal.close();
|
|
||||||
}).fail((response) => {
|
|
||||||
if (response.errors.length > 0) {
|
|
||||||
MailPoet.Notice.error(
|
|
||||||
response.errors.map(error => error.message),
|
|
||||||
{ positionAfter: '#field_name' }
|
|
||||||
);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return false;
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
// CHANGE COLUMN
|
|
||||||
// check for duplicate values in all select options
|
|
||||||
jQuery('select.mailpoet_subscribers_column_data_match')
|
|
||||||
.each(() => {
|
|
||||||
const element = selectElement;
|
|
||||||
const elementId = jQuery(element).val();
|
|
||||||
// if another column has the same value and it's not an 'ignore',
|
|
||||||
// prompt user
|
|
||||||
if (elementId === selectedOptionId
|
|
||||||
&& elementId !== 'ignore') {
|
|
||||||
if (confirm(`${MailPoet.I18n.t('selectedValueAlreadyMatched')} ${MailPoet.I18n.t('confirmCorrespondingColumn')}`)) { // eslint-disable-line
|
|
||||||
jQuery(element).data('column-id', 'ignore');
|
|
||||||
} else {
|
|
||||||
selectEvent.preventDefault();
|
|
||||||
jQuery(selectElement).select2('close');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.on('select2:select', (selectEvent) => {
|
|
||||||
const selectElement = selectEvent.currentTarget;
|
|
||||||
const selectedOptionId = selectEvent.params.data.id;
|
|
||||||
jQuery(selectElement).data('column-id', selectedOptionId);
|
|
||||||
filterSubscribers();
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
nextStepButton.off().on('click', (event) => {
|
nextStepButton.off().on('click', (event) => {
|
||||||
|
@@ -4,6 +4,7 @@ import { withRouter } from 'react-router-dom';
|
|||||||
import PreviousNextStepButtons from './previous_next_step_buttons.jsx';
|
import PreviousNextStepButtons from './previous_next_step_buttons.jsx';
|
||||||
import Warnings from './step_data_manipulation/warnings.jsx';
|
import Warnings from './step_data_manipulation/warnings.jsx';
|
||||||
import MatchTable from './step_data_manipulation/match_table.jsx';
|
import MatchTable from './step_data_manipulation/match_table.jsx';
|
||||||
|
import SelectSegment from './step_data_manipulation/select_segment.jsx';
|
||||||
|
|
||||||
function getPreviousStepLink(importData, subscribersLimitForValidation) {
|
function getPreviousStepLink(importData, subscribersLimitForValidation) {
|
||||||
if (importData === undefined) {
|
if (importData === undefined) {
|
||||||
@@ -46,6 +47,7 @@ function StepDataManipulation({
|
|||||||
subscribers={stepMethodSelectionData.subscribers}
|
subscribers={stepMethodSelectionData.subscribers}
|
||||||
header={stepMethodSelectionData.header}
|
header={stepMethodSelectionData.header}
|
||||||
/>
|
/>
|
||||||
|
<SelectSegment />
|
||||||
</div>
|
</div>
|
||||||
<PreviousNextStepButtons
|
<PreviousNextStepButtons
|
||||||
canGoNext={false}
|
canGoNext={false}
|
||||||
|
@@ -0,0 +1,120 @@
|
|||||||
|
import jQuery from 'jquery';
|
||||||
|
import MailPoet from 'mailpoet';
|
||||||
|
|
||||||
|
export default (selectColumnType) => {
|
||||||
|
jQuery('select.mailpoet_subscribers_column_data_match')
|
||||||
|
.select2({
|
||||||
|
data: window.mailpoetColumnsSelect2,
|
||||||
|
width: '15em',
|
||||||
|
templateResult(item) {
|
||||||
|
return item.name;
|
||||||
|
},
|
||||||
|
templateSelection(item) {
|
||||||
|
return item.name;
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.on('select2:selecting', (selectEvent) => {
|
||||||
|
const selectElement = selectEvent.currentTarget;
|
||||||
|
const selectedOptionId = selectEvent.params.args.data.id;
|
||||||
|
// CREATE CUSTOM FIELD
|
||||||
|
if (selectedOptionId === 'create') {
|
||||||
|
selectEvent.preventDefault();
|
||||||
|
jQuery(selectElement).select2('close');
|
||||||
|
MailPoet.Modal.popup({
|
||||||
|
title: MailPoet.I18n.t('addNewField'),
|
||||||
|
template: jQuery('#form_template_field_form').html(),
|
||||||
|
});
|
||||||
|
jQuery('#form_field_new').parsley().on('form:submit', () => {
|
||||||
|
// get data
|
||||||
|
const data = jQuery('#form_field_new').mailpoetSerializeObject();
|
||||||
|
|
||||||
|
// save custom field
|
||||||
|
MailPoet.Ajax.post({
|
||||||
|
api_version: window.mailpoet_api_version,
|
||||||
|
endpoint: 'customFields',
|
||||||
|
action: 'save',
|
||||||
|
data,
|
||||||
|
}).done((response) => {
|
||||||
|
const newColumnData = {
|
||||||
|
id: response.data.id,
|
||||||
|
name: response.data.name,
|
||||||
|
type: response.data.type,
|
||||||
|
params: response.data.params,
|
||||||
|
custom: true,
|
||||||
|
};
|
||||||
|
// if this is the first custom column, create an "optgroup"
|
||||||
|
if (window.mailpoetColumnsSelect2.length === 2) {
|
||||||
|
window.mailpoetColumnsSelect2.push({
|
||||||
|
name: MailPoet.I18n.t('userColumns'),
|
||||||
|
children: [],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
window.mailpoetColumnsSelect2[2].children.push(newColumnData);
|
||||||
|
window.mailpoetColumns.push(newColumnData);
|
||||||
|
jQuery('select.mailpoet_subscribers_column_data_match')
|
||||||
|
.each(() => {
|
||||||
|
jQuery(selectElement)
|
||||||
|
.html('')
|
||||||
|
.select2('destroy')
|
||||||
|
.select2({
|
||||||
|
data: window.mailpoetColumnsSelect2,
|
||||||
|
width: '15em',
|
||||||
|
templateResult(item) {
|
||||||
|
return item.name;
|
||||||
|
},
|
||||||
|
templateSelection(item) {
|
||||||
|
return item.name;
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
jQuery(selectElement).data('column-id', newColumnData.id);
|
||||||
|
jQuery(selectElement).data('validation-rule', false);
|
||||||
|
const columnIndex = jQuery(selectElement).data('column-index');
|
||||||
|
selectColumnType(newColumnData.id, columnIndex);
|
||||||
|
// close popup
|
||||||
|
MailPoet.Modal.close();
|
||||||
|
}).fail((response) => {
|
||||||
|
if (response.errors.length > 0) {
|
||||||
|
MailPoet.Notice.error(
|
||||||
|
response.errors.map(error => error.message),
|
||||||
|
{ positionAfter: '#field_name' }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
// CHANGE COLUMN
|
||||||
|
// check for duplicate values in all select options
|
||||||
|
jQuery('select.mailpoet_subscribers_column_data_match')
|
||||||
|
.each(() => {
|
||||||
|
const element = selectElement;
|
||||||
|
const elementId = jQuery(element).val();
|
||||||
|
// if another column has the same value and it's not an 'ignore',
|
||||||
|
// prompt user
|
||||||
|
if (elementId === selectedOptionId
|
||||||
|
&& elementId !== 'ignore') {
|
||||||
|
if (confirm(`${MailPoet.I18n.t('selectedValueAlreadyMatched')} ${MailPoet.I18n.t('confirmCorrespondingColumn')}`)) { // eslint-disable-line
|
||||||
|
jQuery(element).data('column-id', 'ignore');
|
||||||
|
} else {
|
||||||
|
selectEvent.preventDefault();
|
||||||
|
jQuery(selectElement).select2('close');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.on('select2:select', (selectEvent) => {
|
||||||
|
const selectElement = selectEvent.currentTarget;
|
||||||
|
const selectedOptionId = selectEvent.params.data.id;
|
||||||
|
jQuery(selectElement).data('column-id', selectedOptionId);
|
||||||
|
const columnIndex = jQuery(selectElement).data('column-index');
|
||||||
|
selectColumnType(selectedOptionId, columnIndex);
|
||||||
|
});
|
||||||
|
jQuery.map(
|
||||||
|
jQuery('.mailpoet_subscribers_column_data_match'), (element) => {
|
||||||
|
const columnId = jQuery(element).data('column-id');
|
||||||
|
jQuery(element).val(columnId).trigger('change');
|
||||||
|
}
|
||||||
|
);
|
||||||
|
};
|
||||||
|
@@ -1,106 +1,120 @@
|
|||||||
import React from 'react';
|
import React, { useLayoutEffect } from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import MailPoet from 'mailpoet';
|
import MailPoet from 'mailpoet';
|
||||||
|
import _ from 'underscore';
|
||||||
|
|
||||||
|
import generateColumnSelection from './generate_column_selection.jsx';
|
||||||
import matchColumns from './match_columns.jsx';
|
import matchColumns from './match_columns.jsx';
|
||||||
|
|
||||||
const MAX_SUBSCRIBERS_SHOWN = 10;
|
const MAX_SUBSCRIBERS_SHOWN = 10;
|
||||||
|
|
||||||
function ColumnDataMatch({ columnTypes }) {
|
|
||||||
return (
|
|
||||||
<tr>
|
|
||||||
<th>{MailPoet.I18n.t('matchData')}</th>
|
|
||||||
{/* eslint-disable-next-line react/no-array-index-key */}
|
|
||||||
{columnTypes.map((columnType, i) => <th key={columnType.column_id + i}>{columnType.column_id}</th>)}
|
|
||||||
</tr>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
ColumnDataMatch.propTypes = {
|
|
||||||
columnTypes: PropTypes.arrayOf(PropTypes.shape({ column_id: PropTypes.string })).isRequired,
|
|
||||||
};
|
|
||||||
|
|
||||||
function Header({ header }) {
|
|
||||||
return (
|
|
||||||
<tr className="mailpoet_header">
|
|
||||||
<td />
|
|
||||||
{header.map(headerName => <td key={headerName}>{headerName}</td>)}
|
|
||||||
</tr>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Header.propTypes = {
|
|
||||||
header: PropTypes.arrayOf(PropTypes.string).isRequired,
|
|
||||||
};
|
|
||||||
|
|
||||||
function Subscriber({ subscriber, index }) {
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<td>{index}</td>
|
|
||||||
{/* eslint-disable-next-line react/no-array-index-key */}
|
|
||||||
{subscriber.map((field, i) => <td key={field + index + i}>{field}</td>)}
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Subscriber.propTypes = {
|
|
||||||
subscriber: PropTypes.arrayOf(PropTypes.string).isRequired,
|
|
||||||
index: PropTypes.node.isRequired,
|
|
||||||
};
|
|
||||||
|
|
||||||
function Subscribers({ subscribers, subscribersCount }) {
|
|
||||||
const filler = '. . .';
|
|
||||||
const fillerArray = Array(subscribers[0].length).fill(filler);
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
{
|
|
||||||
subscribers
|
|
||||||
.slice(0, MAX_SUBSCRIBERS_SHOWN)
|
|
||||||
.map((subscriber, i) => (
|
|
||||||
<tr key={subscriber[0]}>
|
|
||||||
<Subscriber subscriber={subscriber} index={i + 1} />
|
|
||||||
</tr>
|
|
||||||
))
|
|
||||||
}
|
|
||||||
{
|
|
||||||
subscribersCount > MAX_SUBSCRIBERS_SHOWN + 1
|
|
||||||
? <tr key="filler"><Subscriber subscriber={fillerArray} index={filler} /></tr>
|
|
||||||
: null
|
|
||||||
}
|
|
||||||
{
|
|
||||||
subscribersCount > MAX_SUBSCRIBERS_SHOWN
|
|
||||||
? (
|
|
||||||
<tr key={subscribers[subscribersCount - 1][0]}>
|
|
||||||
<Subscriber subscriber={subscribers[subscribersCount - 1]} index={subscribersCount} />
|
|
||||||
</tr>
|
|
||||||
)
|
|
||||||
: null
|
|
||||||
}
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Subscribers.propTypes = {
|
|
||||||
subscribersCount: PropTypes.number.isRequired,
|
|
||||||
subscribers: PropTypes.arrayOf(PropTypes.arrayOf(PropTypes.string)).isRequired,
|
|
||||||
};
|
|
||||||
|
|
||||||
function MatchTable({
|
function MatchTable({
|
||||||
subscribersCount,
|
subscribersCount,
|
||||||
subscribers,
|
subscribers,
|
||||||
header,
|
header,
|
||||||
}) {
|
}) {
|
||||||
const matchedColumnTypes = matchColumns(subscribers, header);
|
let selectedColumns = [];
|
||||||
|
|
||||||
|
useLayoutEffect(() => {
|
||||||
|
generateColumnSelection((selectedOptionId, columnIndex) => {
|
||||||
|
selectedColumns[columnIndex] = selectedOptionId;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
function ColumnDataMatch() {
|
||||||
|
const matchedColumnTypes = matchColumns(subscribers, header);
|
||||||
|
selectedColumns = _.pluck(matchedColumnTypes, 'column_id');
|
||||||
|
return (
|
||||||
|
<tr>
|
||||||
|
<th>{MailPoet.I18n.t('matchData')}</th>
|
||||||
|
{
|
||||||
|
matchedColumnTypes.map((columnType, i) => {
|
||||||
|
return (
|
||||||
|
// eslint-disable-next-line react/no-array-index-key
|
||||||
|
<th key={columnType.column_id + i}>
|
||||||
|
<select
|
||||||
|
className="mailpoet_subscribers_column_data_match"
|
||||||
|
data-column-id={columnType.column_id}
|
||||||
|
data-validation-rule="false"
|
||||||
|
data-column-index={i}
|
||||||
|
id={`column_${i}`}
|
||||||
|
/>
|
||||||
|
</th>
|
||||||
|
);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
</tr>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function Header() {
|
||||||
|
return (
|
||||||
|
<tr className="mailpoet_header">
|
||||||
|
<td />
|
||||||
|
{header.map(headerName => <td key={headerName}>{headerName}</td>)}
|
||||||
|
</tr>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function Subscriber({ subscriber, index }) {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<td>{index}</td>
|
||||||
|
{/* eslint-disable-next-line react/no-array-index-key */}
|
||||||
|
{subscriber.map((field, i) => <td key={field + index + i}>{field}</td>)}
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Subscriber.propTypes = {
|
||||||
|
subscriber: PropTypes.arrayOf(PropTypes.string).isRequired,
|
||||||
|
index: PropTypes.node.isRequired,
|
||||||
|
};
|
||||||
|
|
||||||
|
function Subscribers() {
|
||||||
|
const filler = '. . .';
|
||||||
|
const fillerArray = Array(subscribers[0].length).fill(filler);
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
{
|
||||||
|
subscribers
|
||||||
|
.slice(0, MAX_SUBSCRIBERS_SHOWN)
|
||||||
|
.map((subscriber, i) => (
|
||||||
|
<tr key={subscriber[0]}>
|
||||||
|
<Subscriber subscriber={subscriber} index={i + 1} />
|
||||||
|
</tr>
|
||||||
|
))
|
||||||
|
}
|
||||||
|
{
|
||||||
|
subscribersCount > MAX_SUBSCRIBERS_SHOWN + 1
|
||||||
|
? <tr key="filler"><Subscriber subscriber={fillerArray} index={filler} /></tr>
|
||||||
|
: null
|
||||||
|
}
|
||||||
|
{
|
||||||
|
subscribersCount > MAX_SUBSCRIBERS_SHOWN
|
||||||
|
? (
|
||||||
|
<tr key={subscribers[subscribersCount - 1][0]}>
|
||||||
|
<Subscriber
|
||||||
|
subscriber={subscribers[subscribersCount - 1]}
|
||||||
|
index={subscribersCount}
|
||||||
|
/>
|
||||||
|
</tr>
|
||||||
|
)
|
||||||
|
: null
|
||||||
|
}
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="subscribers_data">
|
<div className="subscribers_data">
|
||||||
<table className="mailpoet_subscribers widefat fixed">
|
<table className="mailpoet_subscribers widefat fixed">
|
||||||
<thead>
|
<thead>
|
||||||
<ColumnDataMatch columnTypes={matchedColumnTypes} />
|
<ColumnDataMatch />
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
<Header header={header} />
|
<Header />
|
||||||
<Subscribers subscribers={subscribers} subscribersCount={subscribersCount} />
|
<Subscribers />
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
Reference in New Issue
Block a user