Added csv import/export for members

no issue

- Adds action view with import/export csv options
This commit is contained in:
Rish 2019-10-04 15:03:10 +05:30
parent b01bb02534
commit 6cd12401c1
9 changed files with 169 additions and 2 deletions

View File

@ -0,0 +1,43 @@
import ModalComponent from 'ghost-admin/components/modal-base';
import ghostPaths from 'ghost-admin/utils/ghost-paths';
import {computed} from '@ember/object';
export default ModalComponent.extend({
labelText: 'Select or drag-and-drop a CSV File',
response: null,
closeDisabled: false,
// Allowed actions
confirm: () => {},
uploadUrl: computed(function () {
return `${ghostPaths().apiRoot}/members/csv/`;
}),
actions: {
uploadStarted() {
this.set('closeDisabled', true);
},
uploadFinished() {
this.set('closeDisabled', false);
},
uploadSuccess(response) {
this.set('response', response.meta.stats);
// invoke the passed in confirm action
this.confirm();
},
confirm() {
// noop - we don't want the enter key doing anything
},
closeModal() {
if (!this.closeDisabled) {
this._super(...arguments);
}
}
}
});

View File

@ -1,4 +1,5 @@
import Controller from '@ember/controller';
import ghostPaths from 'ghost-admin/utils/ghost-paths';
import moment from 'moment';
import {computed} from '@ember/object';
import {inject as service} from '@ember/service';
@ -32,6 +33,22 @@ export default Controller.extend({
return filtered;
}),
actions: {
exportData() {
let exportUrl = ghostPaths().url.api('members/csv');
let downloadURL = `${exportUrl}`;
let iframe = document.getElementById('iframeDownload');
if (!iframe) {
iframe = document.createElement('iframe');
iframe.id = 'iframeDownload';
iframe.style.display = 'none';
document.body.append(iframe);
}
iframe.setAttribute('src', downloadURL);
}
},
fetchMembers: task(function* () {
let newFetchDate = new Date();

View File

@ -0,0 +1,19 @@
import Controller from '@ember/controller';
import {inject as controller} from '@ember/controller';
import {inject as service} from '@ember/service';
/* eslint-disable ghost/ember/alias-model-in-controller */
export default Controller.extend({
members: controller(),
router: service(),
actions: {
fetchNewMembers() {
this.members.fetchMembers.perform();
},
close() {
this.router.transitionTo('members');
}
}
});

View File

@ -58,7 +58,9 @@ Router.map(function () {
this.route('settings.integrations.unsplash', {path: '/settings/integrations/unsplash'});
this.route('settings.integrations.zapier', {path: '/settings/integrations/zapier'});
this.route('members');
this.route('members', function () {
this.route('import');
});
this.route('member', {path: '/members/:member_id'});
this.route('subscribers', function () {

View File

@ -0,0 +1,4 @@
import Route from '@ember/routing/route';
export default Route.extend({
});

View File

@ -27,4 +27,12 @@ p.gh-members-list-email {
textarea.gh-member-details-textarea {
max-width: 100%;
height: 123px;
}
/* Import modal
/* ---------------------------------------------------------- */
.members-import-results {
margin: 0;
width: auto;
}

View File

@ -0,0 +1,47 @@
<header class="modal-header" data-test-modal="import-members">
<h1>
{{#if response}}
Import Successful
{{else}}
Import Members
{{/if}}
</h1>
</header>
<a class="close" href="" title="Close" {{action "closeModal"}}>{{svg-jar "close"}}<span class="hidden">Close</span></a>
<div class="modal-body">
{{#if response}}
<table class="members-import-results">
<tr>
<td>Imported:</td>
<td align="left" data-test-text="import-members-imported">{{response.imported}}</td>
</tr>
{{#if response.duplicates}}
<tr>
<td>Duplicates:</td>
<td align="left" data-test-text="import-members-duplicates">{{response.duplicates}}</td>
</tr>
{{/if}}
{{#if response.invalid}}
<tr>
<td>Invalid:</td>
<td align="left" data-test-text="import-members-invalid">{{response.invalid}}</td>
</tr>
{{/if}}
</table>
{{else}}
{{gh-file-uploader
url=uploadUrl
paramName="membersfile"
labelText="Select or drag-and-drop a CSV file."
uploadStarted=(action "uploadStarted")
uploadFinished=(action "uploadFinished")
uploadSuccess=(action "uploadSuccess")}}
{{/if}}
</div>
<div class="modal-footer">
<button {{action "closeModal"}} disabled={{closeDisabled}} class="gh-btn" data-test-button="close-import-members">
<span>{{#if response}}Close{{else}}Cancel{{/if}}</span>
</button>
</div>

View File

@ -6,6 +6,28 @@
{{svg-jar "search" class="absolute top-2 left-2 w4 h4 fill-midlightgrey-l2"}}
<GhTextInput placeholder="Search members..." @value={{this.searchText}} @input={{action (mut this.searchText) value="target.value"}} class="gh-members-list-searchfield" />
</div>
<section class="view-actions">
<span class="dropdown">
{{#gh-dropdown-button dropdownName="members-actions-menu" classNames="gh-btn gh-btn-white gh-btn-icon only-has-icon user-actions-cog" title="Members Actions" data-test-user-actions=true}}
<span>
{{svg-jar "settings"}}
<span class="hidden">Members Actions</span>
</span>
{{/gh-dropdown-button}}
{{#gh-dropdown name="members-actions-menu" tagName="ul" classNames="user-actions-menu dropdown-menu dropdown-triangle-top-right"}}
<li>
{{#link-to "members.import" class="mr2" data-test-link="import-csv"}}
<span>Import CSV </span>
{{/link-to}}
</li>
<li>
<a href="#" {{action 'exportData'}} class="mr2">
<span>Export CSV </span>
</a>
</li>
{{/gh-dropdown}}
</span>
</section>
</section>
</GhCanvasHeader>
<section class="view-container">
@ -64,4 +86,5 @@
</ol>
</section>
</section>
</section>
</section>
{{outlet}}

View File

@ -0,0 +1,4 @@
{{gh-fullscreen-modal "import-members"
close=(action "close")
confirm=(action "fetchNewMembers")
modifier="action wide"}}