[hub] add data-driven notification message
diff --git a/erpnext/public/js/hub/components/EmptyState.vue b/erpnext/public/js/hub/components/EmptyState.vue
index 3e0cb0e..1f36c3c 100644
--- a/erpnext/public/js/hub/components/EmptyState.vue
+++ b/erpnext/public/js/hub/components/EmptyState.vue
@@ -20,4 +20,18 @@
 }
 </script>
 
-<style scoped></style>
+<style lang="less" scoped>
+	@import "../../../../../../frappe/frappe/public/less/variables.less";
+
+	.empty-state {
+		height: 500px;
+		margin: 15px 0px;
+	}
+
+	.empty-state.bordered {
+		border-radius: 4px;
+		border: 1px solid @border-color;
+		border-style: dashed;
+	}
+
+</style>
diff --git a/erpnext/public/js/hub/components/NotificationMessage.vue b/erpnext/public/js/hub/components/NotificationMessage.vue
index c77f15e..c266726 100644
--- a/erpnext/public/js/hub/components/NotificationMessage.vue
+++ b/erpnext/public/js/hub/components/NotificationMessage.vue
@@ -1,8 +1,11 @@
 <template>
-	<div class="subpage-message">
+	<div v-if="message" class="subpage-message">
         <p class="text-muted flex">
             <span v-html="message"></span>
-            <i class="octicon octicon-x text-extra-muted"></i>
+            <i class="octicon octicon-x text-extra-muted"
+                @click="$emit('remove-message')"
+            >
+            </i>
         </p>
     </div>
 </template>
@@ -10,11 +13,26 @@
 <script>
 
 export default {
-	name: ' notification-message',
+	name: 'notification-message',
 	props: {
 		message: String,
-	}
+    }
 }
 </script>
 
-<style scoped></style>
+<style lang="less" scoped>
+    .subpage-message {
+		p {
+			padding: 10px 15px;
+			margin-top: 0px;
+			margin-bottom: 15px;
+			background-color: #f9fbf7;
+			border-radius: 4px;
+			justify-content: space-between;
+		}
+
+		.octicon-x {
+			cursor: pointer;
+		}
+	}
+</style>
diff --git a/erpnext/public/js/hub/components/PublishPage.vue b/erpnext/public/js/hub/components/PublishPage.vue
index 670f010..2eaf295 100644
--- a/erpnext/public/js/hub/components/PublishPage.vue
+++ b/erpnext/public/js/hub/components/PublishPage.vue
@@ -3,6 +3,12 @@
 		class="marketplace-page"
 		:data-page-name="page_name"
 	>
+		<notification-message
+			v-if="last_sync_message"
+			:message="last_sync_message"
+			@remove-message="clear_last_sync_message"
+		></notification-message>
+
 		<div class="flex justify-between align-flex-end">
 			<h5>{{ page_title }}</h5>
 
@@ -41,6 +47,7 @@
 <script>
 import SearchInput from './SearchInput.vue';
 import ItemCardsContainer from './ItemCardsContainer.vue';
+import NotificationMessage from './NotificationMessage.vue';
 
 export default {
 	name: 'publish-page',
@@ -58,12 +65,20 @@
 				Browse and click on products below to publish.`),
 			valid_products_instruction: __(`Only products with an image, description
 				and category can be published. Please update them if an item in your
-				inventory does not appear.`)
+				inventory does not appear.`),
+			last_sync_message: (hub.settings.last_sync_datetime)
+				? __(`Last sync was
+				<a href="#marketplace/profile">
+					${comment_when(hub.settings.last_sync_datetime)}</a>.
+				<a href="#marketplace/my-products">
+					See your Published Products</a>.`)
+				: ''
 		};
 	},
 	components: {
 		SearchInput,
-		ItemCardsContainer
+		ItemCardsContainer,
+		NotificationMessage
 	},
 	computed: {
 		no_selected_items() {
@@ -96,6 +111,10 @@
 			.then((r) => {
 				this.valid_items = r.message;
 			})
+		},
+
+		clear_last_sync_message() {
+			this.last_sync_message = '';
 		}
 	}
 }
diff --git a/erpnext/public/js/hub/components/notification_message.js b/erpnext/public/js/hub/components/notification_message.js
deleted file mode 100644
index 890c298..0000000
--- a/erpnext/public/js/hub/components/notification_message.js
+++ /dev/null
@@ -1,20 +0,0 @@
-const NotificationMessage = (message) => {
-    const $message = $(`<div class="subpage-message">
-        <p class="text-muted flex">
-            <span>
-                ${message}
-            </span>
-            <i class="octicon octicon-x text-extra-muted"></i>
-        </p>
-    </div>`);
-
-    $message.find('.octicon-x').on('click', () => {
-        $message.remove();
-    });
-
-    return $message;
-}
-
-export {
-    NotificationMessage
-}
diff --git a/erpnext/public/js/hub/pages/publish.js b/erpnext/public/js/hub/pages/publish.js
index 78ca58d..725fdc8 100644
--- a/erpnext/public/js/hub/pages/publish.js
+++ b/erpnext/public/js/hub/pages/publish.js
@@ -66,12 +66,12 @@
 		this.get_items_and_render();
 	}
 
-	show_last_sync_message() {
-		if(hub.settings.last_sync_datetime) {
-			this.show_message(`Last sync was <a href="#marketplace/profile">${comment_when(hub.settings.last_sync_datetime)}</a>.
-				<a href="#marketplace/my-products">See your Published Products</a>.`);
-		}
-	}
+	// show_last_sync_message() {
+	// 	if(hub.settings.last_sync_datetime) {
+	// 		this.show_message(`Last sync was <a href="#marketplace/profile">${comment_when(hub.settings.last_sync_datetime)}</a>.
+	// 			<a href="#marketplace/my-products">See your Published Products</a>.`);
+	// 	}
+	// }
 
 	setup_publishing_events() {
 		this.$wrapper.find('.publish-items').on('click', () => {
diff --git a/erpnext/public/js/hub/pages/subpage.js b/erpnext/public/js/hub/pages/subpage.js
index cded179..07ea11e 100644
--- a/erpnext/public/js/hub/pages/subpage.js
+++ b/erpnext/public/js/hub/pages/subpage.js
@@ -1,5 +1,3 @@
-import { NotificationMessage } from '../components/notification_message';
-
 export default class SubPage {
 	constructor(parent, options) {
 		this.$parent = $(parent);
@@ -84,8 +82,4 @@
 	hide() {
 		this.$wrapper.hide();
 	}
-
-	show_message(message) {
-		this.$wrapper.prepend(NotificationMessage(message));
-	}
 }
diff --git a/erpnext/public/less/hub.less b/erpnext/public/less/hub.less
index 71e9534..5fac085 100644
--- a/erpnext/public/less/hub.less
+++ b/erpnext/public/less/hub.less
@@ -44,21 +44,6 @@
 		justify-content: space-between;
 	}
 
-	.subpage-message {
-		p {
-			padding: 10px 15px;
-			margin-top: 0px;
-			margin-bottom: 15px;
-			background-color: #f9fbf7;
-			border-radius: 4px;
-			justify-content: space-between;
-		}
-
-		.octicon-x {
-			cursor: pointer;
-		}
-	}
-
 	.hub-card {
 		margin-bottom: 25px;
 		position: relative;
@@ -211,17 +196,6 @@
 		padding: 15px 25px;
 	}
 
-	.empty-state {
-		height: 500px;
-		margin: 15px 0px;
-	}
-
-	.empty-state.bordered {
-		border-radius: 4px;
-		border: 1px solid @border-color;
-		border-style: dashed;
-	}
-
 	.publish-area.filled {
 		.empty-items-container {
 			display: none;