- {{#if this.importDisabled}}
- {{svg-jar "warning" class="nudge-top--2 w5 h5 fill-red"}}
- {{else}}
- {{svg-jar "warning" class="nudge-top--2 w5 h5 fill-yellow-d1"}}
- {{/if}}
-
-
The CSV contains errors! {{unless this.importDisabled "Some members will not be imported."}}
- {{#if validationErrors}}
+
+ {{#if this.summary}}
+
+
+
+
{{format-number this.importResponse.imported.count}}
+
{{pluralize this.importResponse.imported.count "Member" without-count=true}} added
+
+
+
{{format-number this.importResponse.invalid.count}}
+
{{pluralize this.importResponse.invalid.count "Error" without-count=true}}
+
+
+
+
+ {{#if this.importResponse.invalid.count}}
+
+
+ {{svg-jar "warning" class="w5 h5 fill-red nudge-top--3 mr3"}}
+
+
{{format-number this.importResponse.invalid.count}} {{pluralize this.importResponse.invalid.count "member" without-count=true}} were skipped due to the following errors:
+ {{#if this.config.enableDeveloperExperiments}}
- {{#each validationErrors as |error|}}
-
- {{{error.message}}}
- {{#if error.context}}
- {{{error.context}}}
- {{/if}}
-
+ {{#each this.importResponse.invalid.errors as |error|}}
+ {{error.message}} ({{format-number error.count}})
{{/each}}
{{/if}}
- {{else}}
-
- {{/if}}
- {{else}}
-
- {{#if this.config.enableDeveloperExperiments}}
- Mapping
-
-
-
- Match the fields in your uploaded file to Ghost members.
- {{else}}
-
-
- {{svg-jar "file-tabular-data" class="w9 h9 mb1 stroke-midgrey"}}
-
{{this.file.name}}
-
-
- {{/if}}
-
-
-
Labels
-
-
Will be applied to all newly imported members
-
-
- {{/if}}
- {{else}}
- {{#if this.failureMessage}}
-
-
{{svg-jar "warning" class="nudge-top--2 w4 h4 fill-red"}}
-
{{this.failureMessage}}
{{/if}}
-
-{{/if}}
+
+ {{/if}}
+
{{#if this.importResponse}}
@@ -148,7 +156,9 @@
{{/unless}}
{{/if}}
- {{else}}
+ {{/if}}
+
+ {{#if this.customizing}}
Start over
diff --git a/ghost/admin/app/components/modal-import-members.js b/ghost/admin/app/components/modal-import-members.js
index 01fc51e7e8..02f79de96f 100644
--- a/ghost/admin/app/components/modal-import-members.js
+++ b/ghost/admin/app/components/modal-import-members.js
@@ -71,13 +71,17 @@ export default ModalComponent.extend({
labelText: 'Select or drag-and-drop a CSV file',
+ // import stages, default is "CSV file selection"
+ validating: false,
+ customizing: false,
+ uploading: false,
+ summary: false,
+
dragClass: null,
file: null,
fileData: null,
mapping: null,
paramName: 'membersfile',
- validating: false,
- uploading: false,
uploadPercentage: 0,
importResponse: null,
failureMessage: null,
@@ -161,6 +165,7 @@ export default ModalComponent.extend({
// TODO: remove "if" below once import validations are production ready
if (this.config.get('enableDeveloperExperiments')) {
this.set('validating', true);
+
papaparse.parse(file, {
header: true,
skipEmptyLines: true,
@@ -175,12 +180,15 @@ export default ModalComponent.extend({
this._importValidationFailed(validationErrors);
} else {
this.set('validating', false);
+ this.set('customizing', true);
}
},
error: (error) => {
this._validationFailed(error);
}
});
+ } else {
+ this.set('customizing', true);
}
}
},
@@ -192,6 +200,11 @@ export default ModalComponent.extend({
this.set('fileData', null);
this.set('mapping', null);
this.set('validationErrors', null);
+
+ this.set('validating', false);
+ this.set('customizing', false);
+ this.set('uploading', false);
+ this.set('summary', false);
},
upload() {
@@ -202,6 +215,7 @@ export default ModalComponent.extend({
continueImport() {
this.set('validating', false);
+ this.set('customizing', true);
},
confirm() {
@@ -280,6 +294,7 @@ export default ModalComponent.extend({
},
_uploadStarted() {
+ this.set('customizing', false);
this.set('uploading', true);
},
@@ -300,6 +315,7 @@ export default ModalComponent.extend({
_uploadFinished() {
this.set('uploading', false);
+ this.set('summary', true);
},
_importValidationFailed(errors) {