[hub] Realtime Sync Progress

- Show progress from the migration plan
- Show products being synced
- Disallow publishing in sync state
This commit is contained in:
Prateeksha Singh 2018-07-30 09:17:14 +05:30
parent 811cc3f78f
commit efbd2ee3f5
3 changed files with 158 additions and 61 deletions

View File

@ -373,7 +373,7 @@
"bold": 0, "bold": 0,
"collapsible": 0, "collapsible": 0,
"columns": 0, "columns": 0,
"depends_on": "enabled", "depends_on": "",
"fieldname": "publish_section", "fieldname": "publish_section",
"fieldtype": "Section Break", "fieldtype": "Section Break",
"hidden": 0, "hidden": 0,
@ -675,8 +675,8 @@
"issingle": 1, "issingle": 1,
"istable": 0, "istable": 0,
"max_attachments": 0, "max_attachments": 0,
"modified": "2018-07-28 00:48:21.210413", "modified": "2018-07-30 08:01:09.024358",
"modified_by": "cave@aperture.com", "modified_by": "Administrator",
"module": "Hub Node", "module": "Hub Node",
"name": "Hub Settings", "name": "Hub Settings",
"name_case": "", "name_case": "",

View File

@ -825,17 +825,44 @@ erpnext.hub.Profile = class Profile extends SubPage {
erpnext.hub.Publish = class Publish extends SubPage { erpnext.hub.Publish = class Publish extends SubPage {
make_wrapper() { make_wrapper() {
super.make_wrapper(); super.make_wrapper();
this.items_to_publish = [];
this.unpublished_items = [];
this.fetched_items = [];
}
refresh() {
if(!hub.settings.sync_in_progress) { if(!hub.settings.sync_in_progress) {
this.make_publish_header(); this.make_publish_ready_state();
} else { } else {
this.show_publishing_state(); this.make_publish_in_progress_state();
} }
} }
make_publish_header() { make_publish_ready_state() {
const title_html = `<b>${__('Select Products to Publish')}</b>`; this.$wrapper.empty();
this.$wrapper.append(this.get_publishing_header());
const info = `<p class="text-muted">${__("Status decided by the 'Publish in Hub' field in Item.")}</p>`; make_search_bar({
wrapper: this.$wrapper,
on_search: keyword => {
this.search_value = keyword;
this.get_items_and_render();
},
placeholder: __('Search Items')
});
this.setup_publishing_events();
if(hub.settings.last_sync) {
this.show_message(`Last sync was <a href="#marketplace/profile">${hub.settings.last_sync}</a>.
<a href="#marketplace/my-products">See your Published Products</a>.`);
}
this.get_items_and_render();
}
get_publishing_header() {
const title_html = `<b>${__('Select Products to Publish')}</b>`;
const subtitle_html = `<p class="text-muted"> const subtitle_html = `<p class="text-muted">
${__(`Only products with an image, description and category can be published. ${__(`Only products with an image, description and category can be published.
@ -847,10 +874,7 @@ erpnext.hub.Publish = class Publish extends SubPage {
<span class="hidden-xs">${__('Publish')}</span> <span class="hidden-xs">${__('Publish')}</span>
</button>`; </button>`;
const select_all_button = `<button class="btn btn-secondary btn-default btn-xs margin-right select-all">${__('Select All')}</button>`; return $(`
const deselect_all_button = `<button class="btn btn-secondary btn-default btn-xs deselect-all">${__('Deselect All')}</button>`;
const subpage_header = $(`
<div class='subpage-title flex'> <div class='subpage-title flex'>
<div> <div>
${title_html} ${title_html}
@ -859,27 +883,12 @@ erpnext.hub.Publish = class Publish extends SubPage {
${publish_button_html} ${publish_button_html}
</div> </div>
`); `);
this.$wrapper.append(subpage_header);
make_search_bar({
wrapper: this.$wrapper,
on_search: keyword => {
this.search_value = keyword;
this.get_items_and_render();
},
placeholder: __('Search Items')
});
this.setup_events();
} }
setup_events() { setup_publishing_events() {
this.$wrapper.find('.publish-items').on('click', () => { this.$wrapper.find('.publish-items').on('click', () => {
this.publish_selected_items() this.publish_selected_items()
.then(r => { .then(this.refresh.bind(this))
console.log(`${r.message} items will be published`);
});
}); });
this.$wrapper.on('click', '.hub-card', (e) => { this.$wrapper.on('click', '.hub-card', (e) => {
@ -903,33 +912,95 @@ erpnext.hub.Publish = class Publish extends SubPage {
}); });
} }
get_items_and_render() { show_message(message) {
if(hub.settings.sync_in_progress) { const $message = $(`<div class="subpage-message">
this.show_publishing_state(); <p class="text-muted flex">
return; <span>
} ${message}
</span>
<i class="octicon octicon-x text-extra-muted"></i>
</p>
</div>`);
this.$wrapper.find('.hub-card-container').empty(); $message.find('.octicon-x').on('click', () => {
this.get_valid_items() $message.remove();
.then(r => { });
this.render(r.message);
}); this.$wrapper.prepend($message);
} }
refresh() { make_publish_in_progress_state() {
if (hub.settings.sync_in_progress) { this.$wrapper.empty();
this.load_publishing_state();
this.$wrapper.append(this.show_publish_progress());
const subtitle_html = `<p class="text-muted">
${__(`Only products with an image, description and category can be published.
Please update them if an item in your inventory does not appear.`)}
</p>`;
this.$wrapper.append(subtitle_html);
// Show search list with only desctiption, and don't set any events
make_search_bar({
wrapper: this.$wrapper,
on_search: keyword => {
this.search_value = keyword;
this.get_items_and_render();
},
placeholder: __('Search Items')
});
this.get_items_and_render();
}
show_publish_progress() {
const items_to_publish = this.items_to_publish.length
? this.items_to_publish
: JSON.parse(hub.settings.custom_data);
const $publish_progress = $(`<div class="sync-progress">
<p><b>${__(`Syncing ${items_to_publish.length} Products`)}</b></p>
<div class="progress">
<div class="progress-bar" style="width: 12.875%"></div>
</div>
</div>`);
const items_to_publish_container = $(get_item_card_container_html(
items_to_publish, '', get_local_item_card_html));
items_to_publish_container.find('.hub-card').addClass('active');
$publish_progress.append(items_to_publish_container);
return $publish_progress;
}
get_items_and_render(wrapper = this.$wrapper) {
wrapper.find('.results').remove();
const items = this.get_valid_items();
if(!items.then) {
this.render(items, wrapper);
} else { } else {
this.get_items_and_render(); items.then(r => {
this.fetched_items = r.message;
this.render(r.message, wrapper);
});
} }
} }
render(items) { render(items, wrapper) {
const items_container = $(get_item_card_container_html(items, '', get_local_item_card_html)); const items_container = $(get_item_card_container_html(items, '', get_local_item_card_html));
this.$wrapper.append(items_container); items_container.addClass('results');
wrapper.append(items_container);
} }
get_valid_items() { get_valid_items() {
if(this.unpublished_items.length) {
return this.unpublished_items;
}
return frappe.call( return frappe.call(
'erpnext.hub_node.get_valid_items', 'erpnext.hub_node.get_valid_items',
{ {
@ -938,26 +1009,33 @@ erpnext.hub.Publish = class Publish extends SubPage {
); );
} }
show_publishing_state() {
this.$wrapper.html(get_empty_state(
'Publishing items ... You will be notified once published.'
));
}
publish_selected_items() { publish_selected_items() {
const items_to_publish = []; const item_codes_to_publish = [];
this.$wrapper.find('.hub-card.active').map(function () { this.$wrapper.find('.hub-card.active').map(function () {
items_to_publish.push($(this).attr("data-id")); item_codes_to_publish.push($(this).attr("data-id"));
}); });
this.show_publishing_state(); this.unpublished_items = this.fetched_items.filter(item => {
return !item_codes_to_publish.includes(item.item_code);
});
return frappe.call( const items_to_publish = this.fetched_items.filter(item => {
'erpnext.hub_node.publish_selected_items', return item_codes_to_publish.includes(item.item_code);
{ });
items_to_publish: items_to_publish this.items_to_publish = items_to_publish;
}
); return frappe.db.set_value("Hub Settings", "Hub Settings", {
custom_data: JSON.stringify(items_to_publish),
// sync_in_progress: 1
}).then(() => {
hub.settings.sync_in_progress = 1;
})
// .then(frappe.call(
// 'erpnext.hub_node.publish_selected_items',
// {
// items_to_publish: item_codes_to_publish
// }
// ));
} }
} }

View File

@ -31,14 +31,33 @@ body[data-route^="marketplace/"] {
border-color: #59b81c; border-color: #59b81c;
} }
.progress-bar {
background-color: #89da28;
}
.subpage-title.flex { .subpage-title.flex {
align-items: flex-start; align-items: flex-start;
justify-content: space-between; justify-content: space-between;
} }
.subpage-message {
p {
padding: 10px 15px;
margin-top: 0px;
margin-bottom: 15px;
background-color: #f9fbf7;
justify-content: space-between;
}
.octicon-x {
cursor: pointer;
}
}
.hub-card { .hub-card {
border: 1px solid @border-color;
margin-bottom: 25px; margin-bottom: 25px;
position: relative;
border: 1px solid @border-color;
border-radius: 4px; border-radius: 4px;
overflow: hidden; overflow: hidden;
cursor: pointer; cursor: pointer;