[hub][vue] add empty state and dynamic publish button
This commit is contained in:
parent
d7d2bb261b
commit
b696b2965d
23
erpnext/public/js/hub/components/EmptyState.vue
Normal file
23
erpnext/public/js/hub/components/EmptyState.vue
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
<template>
|
||||||
|
<div class="empty-state flex align-center flex-column justify-center"
|
||||||
|
:class="{ bordered: bordered }"
|
||||||
|
:style="{ height: height + 'px' }"
|
||||||
|
>
|
||||||
|
<p class="text-muted">{{ message }}</p>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'empty-state',
|
||||||
|
props: {
|
||||||
|
message: String,
|
||||||
|
bordered: Boolean,
|
||||||
|
height: Number,
|
||||||
|
// action: Function
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped></style>
|
@ -1,5 +1,12 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
|
<empty-state
|
||||||
|
v-if="items.length === 0"
|
||||||
|
:message="empty_state_message"
|
||||||
|
:bordered="true"
|
||||||
|
:height="80"
|
||||||
|
>
|
||||||
|
</empty-state>
|
||||||
<item-card
|
<item-card
|
||||||
v-for="item in items"
|
v-for="item in items"
|
||||||
:key="item[item_id]"
|
:key="item[item_id]"
|
||||||
@ -12,12 +19,21 @@
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
import ItemCard from './ItemCard.vue';
|
import ItemCard from './ItemCard.vue';
|
||||||
|
import EmptyState from './EmptyState.vue';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'item-cards-container',
|
name: 'item-cards-container',
|
||||||
props: ['items', 'is_local'],
|
props: {
|
||||||
|
'items': Array,
|
||||||
|
'is_local': Boolean,
|
||||||
|
|
||||||
|
'empty_state_message': String,
|
||||||
|
'empty_state_height': Number,
|
||||||
|
'empty_state_bordered': Boolean
|
||||||
|
},
|
||||||
components: {
|
components: {
|
||||||
ItemCard
|
ItemCard,
|
||||||
|
EmptyState
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
item_id() {
|
item_id() {
|
||||||
|
20
erpnext/public/js/hub/components/NotificationMessage.vue
Normal file
20
erpnext/public/js/hub/components/NotificationMessage.vue
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
<template>
|
||||||
|
<div class="subpage-message">
|
||||||
|
<p class="text-muted flex">
|
||||||
|
<span v-html="message"></span>
|
||||||
|
<i class="octicon octicon-x text-extra-muted"></i>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: ' notification-message',
|
||||||
|
props: {
|
||||||
|
message: String,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped></style>
|
@ -3,15 +3,36 @@
|
|||||||
class="marketplace-page"
|
class="marketplace-page"
|
||||||
:data-page-name="page_name"
|
:data-page-name="page_name"
|
||||||
>
|
>
|
||||||
|
<div class="flex justify-between align-flex-end">
|
||||||
|
<h5>{{ page_title }}</h5>
|
||||||
|
|
||||||
|
<button class="btn btn-primary btn-sm publish-items"
|
||||||
|
:disabled="no_selected_items">
|
||||||
|
<span>{{ publish_button_text }}</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<item-cards-container
|
||||||
|
:items="selected_items"
|
||||||
|
:is_local="true"
|
||||||
|
:empty_state_message="empty_state_message"
|
||||||
|
:empty_state_bordered="true"
|
||||||
|
:empty_state_height="80"
|
||||||
|
>
|
||||||
|
</item-cards-container>
|
||||||
|
|
||||||
|
<p class="text-muted">{{ valid_products_instruction }}</p>
|
||||||
|
|
||||||
<search-input
|
<search-input
|
||||||
placeholder="Search Items ..."
|
:placeholder="search_placeholder"
|
||||||
:on_search="get_valid_items"
|
:on_search="get_valid_items"
|
||||||
v-model="search_value"
|
v-model="search_value"
|
||||||
>
|
>
|
||||||
</search-input>
|
</search-input>
|
||||||
|
|
||||||
<item-cards-container
|
<item-cards-container
|
||||||
:items="valid_items"
|
:items="valid_items"
|
||||||
:is_local="1"
|
:is_local="true"
|
||||||
>
|
>
|
||||||
</item-cards-container>
|
</item-cards-container>
|
||||||
</div>
|
</div>
|
||||||
@ -27,13 +48,40 @@ export default {
|
|||||||
return {
|
return {
|
||||||
page_name: frappe.get_route()[1],
|
page_name: frappe.get_route()[1],
|
||||||
valid_items: [],
|
valid_items: [],
|
||||||
search_value: ''
|
selected_items: [],
|
||||||
|
search_value: '',
|
||||||
|
|
||||||
|
// Constants
|
||||||
|
page_title: __('Publish Products'),
|
||||||
|
search_placeholder: __('Search Items ...'),
|
||||||
|
empty_state_message: __(`No Items selected yet.
|
||||||
|
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.`)
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
components: {
|
components: {
|
||||||
SearchInput,
|
SearchInput,
|
||||||
ItemCardsContainer
|
ItemCardsContainer
|
||||||
},
|
},
|
||||||
|
computed: {
|
||||||
|
no_selected_items() {
|
||||||
|
return this.selected_items.length === 0;
|
||||||
|
},
|
||||||
|
|
||||||
|
publish_button_text() {
|
||||||
|
const number = this.selected_items.length;
|
||||||
|
let text = 'Publish';
|
||||||
|
if(number === 1) {
|
||||||
|
text = 'Publish 1 Product';
|
||||||
|
}
|
||||||
|
if(number > 1) {
|
||||||
|
text = `Publish ${number} Products`;
|
||||||
|
}
|
||||||
|
return __(text);
|
||||||
|
}
|
||||||
|
},
|
||||||
created() {
|
created() {
|
||||||
this.get_valid_items();
|
this.get_valid_items();
|
||||||
},
|
},
|
||||||
|
@ -4,6 +4,8 @@ import { get_local_item_card_html } from '../components/item_card';
|
|||||||
import { make_search_bar } from '../components/search_bar';
|
import { make_search_bar } from '../components/search_bar';
|
||||||
import { get_publishing_header } from '../components/publishing_area';
|
import { get_publishing_header } from '../components/publishing_area';
|
||||||
import { ItemPublishDialog } from '../components/item_publish_dialog';
|
import { ItemPublishDialog } from '../components/item_publish_dialog';
|
||||||
|
|
||||||
|
|
||||||
import PublishPage from '../components/PublishPage.vue';
|
import PublishPage from '../components/PublishPage.vue';
|
||||||
|
|
||||||
erpnext.hub.Publish = class Publish {
|
erpnext.hub.Publish = class Publish {
|
||||||
|
@ -213,14 +213,13 @@ body[data-route^="marketplace/"] {
|
|||||||
|
|
||||||
.empty-state {
|
.empty-state {
|
||||||
height: 500px;
|
height: 500px;
|
||||||
|
margin: 15px 0px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.empty-items-container {
|
.empty-state.bordered {
|
||||||
height: 80px;
|
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
border: 1px solid @border-color;
|
border: 1px solid @border-color;
|
||||||
border-style: dashed;
|
border-style: dashed;
|
||||||
margin: 15px 0px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.publish-area.filled {
|
.publish-area.filled {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user