[hub] Publishing Dialog, Sync category

- Hub Category selection
- Recycled
diff --git a/erpnext/hub_node/api.py b/erpnext/hub_node/api.py
index 559e22a..86ad031 100644
--- a/erpnext/hub_node/api.py
+++ b/erpnext/hub_node/api.py
@@ -42,11 +42,19 @@
 def publish_selected_items(items_to_publish):
 	items_to_publish = json.loads(items_to_publish)
 	if not len(items_to_publish):
-		return
+		frappe.throw('No items to publish')
 
-	for item_code in items_to_publish:
+	for item in items_to_publish:
+		item_code = item.get('item_code')
 		frappe.db.set_value('Item', item_code, 'publish_in_hub', 1)
 
+		frappe.get_doc({
+			'doctype': 'Hub Tracked Item',
+			'item_code': item_code,
+			'hub_category': item.get('hub_category'),
+			# 'images': item.get('images')
+		}).insert()
+
 	try:
 		hub_settings = frappe.get_doc('Hub Settings')
 		item_sync_preprocess()
diff --git a/erpnext/hub_node/data_migration_mapping/item_to_hub_item/__init__.py b/erpnext/hub_node/data_migration_mapping/item_to_hub_item/__init__.py
index 9445e3a..3f13520 100644
--- a/erpnext/hub_node/data_migration_mapping/item_to_hub_item/__init__.py
+++ b/erpnext/hub_node/data_migration_mapping/item_to_hub_item/__init__.py
@@ -1,19 +1,24 @@
-import io, base64, urllib, os
+import frappe, io, base64, urllib, os
 
 def pre_process(doc):
 
-	file_path = doc.image
-	file_name = os.path.basename(file_path)
+	# file_path = doc.image
+	# file_name = os.path.basename(file_path)
 
-	if file_path.startswith('http'):
-		url = file_path
-		file_path = os.path.join('/tmp', file_name)
-		urllib.urlretrieve(url, file_path)
+	# if file_path.startswith('http'):
+	# 	url = file_path
+	# 	file_path = os.path.join('/tmp', file_name)
+	# 	urllib.urlretrieve(url, file_path)
 
-	with io.open(file_path, 'rb') as f:
-		doc.image = base64.b64encode(f.read())
+	# with io.open(file_path, 'rb') as f:
+	# 	doc.image = base64.b64encode(f.read())
 
-	doc.image_file_name = file_name
+	# doc.image_file_name = file_name
+
+	cached_details = frappe.get_doc('Hub Tracked Item', doc.item_code)
+
+	if cached_details:
+		doc.hub_category = cached_details.hub_category
 
 	return doc
 
diff --git a/erpnext/hub_node/doctype/hub_tracked_item/hub_tracked_item.json b/erpnext/hub_node/doctype/hub_tracked_item/hub_tracked_item.json
index 063c878..7a0bc2a 100644
--- a/erpnext/hub_node/doctype/hub_tracked_item/hub_tracked_item.json
+++ b/erpnext/hub_node/doctype/hub_tracked_item/hub_tracked_item.json
@@ -3,6 +3,7 @@
  "allow_guest_to_view": 0, 
  "allow_import": 0, 
  "allow_rename": 0, 
+ "autoname": "field:item_code", 
  "beta": 0, 
  "creation": "2018-03-18 09:33:50.267762", 
  "custom": 0, 
@@ -14,6 +15,7 @@
  "fields": [
   {
    "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
@@ -41,6 +43,70 @@
    "search_index": 0, 
    "set_only_once": 0, 
    "translatable": 0, 
+   "unique": 1
+  }, 
+  {
+   "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
+   "fieldname": "hub_category", 
+   "fieldtype": "Data", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "label": "Hub Category", 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "remember_last_selected_value": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "translatable": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_bulk_edit": 0, 
+   "allow_in_quick_entry": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
+   "fieldname": "images", 
+   "fieldtype": "Long Text", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "label": "Images", 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "remember_last_selected_value": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "translatable": 0, 
    "unique": 0
   }
  ], 
@@ -49,12 +115,12 @@
  "hide_toolbar": 0, 
  "idx": 0, 
  "image_view": 0, 
- "in_create": 1, 
+ "in_create": 0, 
  "is_submittable": 0, 
  "issingle": 0, 
  "istable": 0, 
  "max_attachments": 0, 
- "modified": "2018-03-18 09:34:01.757713", 
+ "modified": "2018-08-19 19:30:01.449904", 
  "modified_by": "Administrator", 
  "module": "Hub Node", 
  "name": "Hub Tracked Item", 
@@ -63,7 +129,6 @@
  "permissions": [
   {
    "amend": 0, 
-   "apply_user_permissions": 0, 
    "cancel": 0, 
    "create": 1, 
    "delete": 1, 
@@ -89,5 +154,6 @@
  "sort_field": "modified", 
  "sort_order": "DESC", 
  "track_changes": 1, 
- "track_seen": 0
+ "track_seen": 0, 
+ "track_views": 0
 }
\ No newline at end of file
diff --git a/erpnext/public/js/hub/pages/publish.js b/erpnext/public/js/hub/pages/publish.js
index a76f946..035278b 100644
--- a/erpnext/public/js/hub/pages/publish.js
+++ b/erpnext/public/js/hub/pages/publish.js
@@ -3,13 +3,17 @@
 import { get_local_item_card_html } from '../components/item_card';
 import { make_search_bar } from '../components/search_bar';
 
+
 erpnext.hub.Publish = class Publish extends SubPage {
 	make_wrapper() {
 		super.make_wrapper();
-		this.items_to_publish = [];
+		this.items_to_publish = {};
 		this.unpublished_items = [];
 		this.fetched_items = [];
 
+		this.cache = erpnext.hub.cache.items_to_publish;
+		this.cache = [];
+
 		frappe.realtime.on("items-sync", (data) => {
 			this.$wrapper.find('.progress-bar').css('width', data.progress_percent+'%');
 
@@ -58,7 +62,7 @@
 	}
 
 	get_publishing_header() {
-		const title_html = `<b>${__('Select Products to Publish')}</b>`;
+		const title_html = `<h5>${__('Select Products to Publish')}</h5>`;
 
 		const subtitle_html = `<p class="text-muted">
 			${__(`Only products with an image, description and category can be published.
@@ -71,6 +75,9 @@
 		</button>`;
 
 		return $(`
+			<div class="subpage-title flex"><h5>${__('Selected Products')}</h5></div>
+			<div class="row hub-items-container selected-items"></div>
+
 			<div class='subpage-title flex'>
 				<div>
 					${title_html}
@@ -87,27 +94,97 @@
 				.then(this.refresh.bind(this))
 		});
 
+		this.selected_items_container = this.$wrapper.find('.selected-items');
+
+		this.$current_selected_card = null;
+
+		this.make_publishing_dialog();
+
 		this.$wrapper.on('click', '.hub-card', (e) => {
 			const $target = $(e.currentTarget);
-			$target.toggleClass('active');
+			const item_code = $target.attr('data-id');
+			this.show_publishing_dialog_for_item(item_code);
 
-			// Get total items
-			const total_items = this.$wrapper.find('.hub-card.active').length;
+			this.$current_selected_card = $target.parent();
 
-			let button_label;
-			if (total_items > 0) {
-				const more_than_one = total_items > 1;
-				button_label = __('Publish {0} item{1}', [total_items, more_than_one ? 's' : '']);
-			} else {
-				button_label = __('Publish');
-			}
+			this.update_selected_items_count()
 
-			this.$wrapper.find('.publish-items')
-				.text(button_label)
-				.prop('disabled', total_items === 0);
 		});
 	}
 
+	make_publishing_dialog() {
+		this.publishing_dialog = new frappe.ui.Dialog({
+			title: __('Edit Publishing Details'),
+			fields: [
+				{
+					"label": "Item Code",
+					"fieldname": "item_code",
+					"fieldtype": "Data",
+					"read_only": 1
+				},
+				{
+					"label": "Hub Category",
+					"fieldname": "hub_category",
+					"fieldtype": "Autocomplete",
+					"options": ["Agriculture", "Books", "Chemicals", "Clothing",
+						"Electrical", "Electronics", "Energy", "Fashion", "Food and Beverage",
+						"Health", "Home", "Industrial", "Machinery", "Packaging and Printing",
+						"Sports", "Transportation"
+					],
+					"reqd": 1
+				}
+			],
+			primary_action_label: __('Set Details'),
+			primary_action: () => {
+				const values = this.publishing_dialog.get_values(true);
+				this.items_to_publish[values.item_code] = values;
+
+				this.$current_selected_card.appendTo(this.selected_items_container);
+				this.$current_selected_card.find('.hub-card').toggleClass('active');
+
+				this.publishing_dialog.hide();
+			},
+			secondary_action: () => {
+				const values = this.publishing_dialog.get_values(true);
+				this.items_to_publish[values.item_code] = values;
+			}
+		});
+	}
+
+	show_publishing_dialog_for_item(item_code) {
+		let item_data = this.items_to_publish[item_code];
+
+		if(!item_data) { item_data = { item_code }; }
+
+		this.publishing_dialog.clear();
+		this.publishing_dialog.set_values(item_data);
+		this.publishing_dialog.show();
+	}
+
+	update_selected_items_count() {
+		const total_items = this.$wrapper.find('.hub-card.active').length;
+
+		let button_label;
+		if (total_items > 0) {
+			const more_than_one = total_items > 1;
+			button_label = __('Publish {0} item{1}', [total_items, more_than_one ? 's' : '']);
+		} else {
+			button_label = __('Publish');
+		}
+
+		this.$wrapper.find('.publish-items')
+			.text(button_label)
+			.prop('disabled', total_items === 0);
+	}
+
+	add_item_to_publish() {
+		//
+	}
+
+	remove_item_from_publish() {
+		//
+	}
+
 	show_message(message) {
 		const $message = $(`<div class="subpage-message">
 			<p class="text-muted flex">
@@ -211,19 +288,22 @@
 			item_codes_to_publish.push($(this).attr("data-id"));
 		});
 
-		this.unpublished_items = this.fetched_items.filter(item => {
-			return !item_codes_to_publish.includes(item.item_code);
-		});
+		// this.unpublished_items = this.fetched_items.filter(item => {
+		// 	return !item_codes_to_publish.includes(item.item_code);
+		// });
 
-		const items_to_publish = this.fetched_items.filter(item => {
-			return item_codes_to_publish.includes(item.item_code);
-		});
-		this.items_to_publish = items_to_publish;
+		// const items_to_publish = this.fetched_items.filter(item => {
+		// 	return item_codes_to_publish.includes(item.item_code);
+		// });
+
+		// this.items_to_publish = items_to_publish;
+
+		const items_data_to_publish = item_codes_to_publish.map(item_code => this.items_to_publish[item_code])
 
 		return frappe.call(
 			'erpnext.hub_node.api.publish_selected_items',
 			{
-				items_to_publish: item_codes_to_publish
+				items_to_publish: items_data_to_publish
 			}
 		)
 	}