[hub][vue] Home page, add section title in item key in v-for
This commit is contained in:
parent
53fada1ae9
commit
de426cb543
@ -9,7 +9,7 @@
|
|||||||
</empty-state>
|
</empty-state>
|
||||||
<item-card
|
<item-card
|
||||||
v-for="item in items"
|
v-for="item in items"
|
||||||
:key="item[item_id_fieldname]"
|
:key="container_name + '_' +item[item_id_fieldname]"
|
||||||
:item="item"
|
:item="item"
|
||||||
:item_id_fieldname="item_id_fieldname"
|
:item_id_fieldname="item_id_fieldname"
|
||||||
:is_local="is_local"
|
:is_local="is_local"
|
||||||
@ -29,6 +29,7 @@ import EmptyState from './EmptyState.vue';
|
|||||||
export default {
|
export default {
|
||||||
name: 'item-cards-container',
|
name: 'item-cards-container',
|
||||||
props: {
|
props: {
|
||||||
|
container_name: String,
|
||||||
items: Array,
|
items: Array,
|
||||||
item_id_fieldname: String,
|
item_id_fieldname: String,
|
||||||
is_local: Boolean,
|
is_local: Boolean,
|
||||||
|
@ -1,20 +0,0 @@
|
|||||||
function make_search_bar({wrapper, on_search, placeholder = __('Search for anything')}) {
|
|
||||||
const $search = $(`
|
|
||||||
<div class="hub-search-container">
|
|
||||||
<input type="text" class="form-control" placeholder="${placeholder}">
|
|
||||||
</div>`
|
|
||||||
);
|
|
||||||
wrapper.append($search);
|
|
||||||
const $search_input = $search.find('input');
|
|
||||||
|
|
||||||
$search_input.on('keydown', frappe.utils.debounce((e) => {
|
|
||||||
if (e.which === frappe.ui.keyCode.ENTER) {
|
|
||||||
const search_value = $search_input.val();
|
|
||||||
on_search(search_value);
|
|
||||||
}
|
|
||||||
}, 300));
|
|
||||||
}
|
|
||||||
|
|
||||||
export {
|
|
||||||
make_search_bar
|
|
||||||
}
|
|
@ -1,7 +1,6 @@
|
|||||||
import Vue from 'vue/dist/vue.js';
|
import Vue from 'vue/dist/vue.js';
|
||||||
|
|
||||||
// pages
|
// pages
|
||||||
import './pages/home';
|
|
||||||
import './pages/item';
|
import './pages/item';
|
||||||
import './pages/seller';
|
import './pages/seller';
|
||||||
import './pages/profile';
|
import './pages/profile';
|
||||||
@ -9,6 +8,7 @@ import './pages/messages';
|
|||||||
import './pages/buying_messages';
|
import './pages/buying_messages';
|
||||||
import './pages/not_found';
|
import './pages/not_found';
|
||||||
|
|
||||||
|
import Home from './pages/Home.vue';
|
||||||
import SavedProducts from './pages/SavedProducts.vue';
|
import SavedProducts from './pages/SavedProducts.vue';
|
||||||
import Publish from './pages/Publish.vue';
|
import Publish from './pages/Publish.vue';
|
||||||
import Category from './pages/Category.vue';
|
import Category from './pages/Category.vue';
|
||||||
@ -170,7 +170,7 @@ erpnext.hub.Marketplace = class Marketplace {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (route[1] === 'home' && !this.subpages.home) {
|
if (route[1] === 'home' && !this.subpages.home) {
|
||||||
this.subpages.home = new erpnext.hub.Home(this.$body);
|
this.subpages.home = new erpnext.hub.HomePage(this.$body);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (route[1] === 'search' && !this.subpages.search) {
|
if (route[1] === 'search' && !this.subpages.search) {
|
||||||
@ -266,6 +266,23 @@ erpnext.hub.Marketplace = class Marketplace {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
erpnext.hub.HomePage = class {
|
||||||
|
constructor(parent) {
|
||||||
|
this.$wrapper = $(`<div id="vue-area-home">`).appendTo($(parent));
|
||||||
|
|
||||||
|
new Vue({
|
||||||
|
render: h => h(Home)
|
||||||
|
}).$mount('#vue-area-home');
|
||||||
|
}
|
||||||
|
|
||||||
|
show() {
|
||||||
|
$('[data-page-name="home"]').show();
|
||||||
|
}
|
||||||
|
|
||||||
|
hide() {
|
||||||
|
$('[data-page-name="home"]').hide();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
erpnext.hub.SavedProductsPage = class {
|
erpnext.hub.SavedProductsPage = class {
|
||||||
constructor(parent) {
|
constructor(parent) {
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
<h5>{{ page_title }}</h5>
|
<h5>{{ page_title }}</h5>
|
||||||
|
|
||||||
<item-cards-container
|
<item-cards-container
|
||||||
|
:container_name="page_title"
|
||||||
:items="items"
|
:items="items"
|
||||||
:item_id_fieldname="item_id_fieldname"
|
:item_id_fieldname="item_id_fieldname"
|
||||||
:on_click="go_to_item_details_page"
|
:on_click="go_to_item_details_page"
|
||||||
|
103
erpnext/public/js/hub/pages/Home.vue
Normal file
103
erpnext/public/js/hub/pages/Home.vue
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
<template>
|
||||||
|
<div
|
||||||
|
class="marketplace-page"
|
||||||
|
:data-page-name="page_name"
|
||||||
|
>
|
||||||
|
<search-input
|
||||||
|
:placeholder="search_placeholder"
|
||||||
|
:on_search="set_search_route"
|
||||||
|
v-model="search_value"
|
||||||
|
>
|
||||||
|
</search-input>
|
||||||
|
|
||||||
|
<div v-for="section in sections"
|
||||||
|
:key="section.title"
|
||||||
|
>
|
||||||
|
<div class="hub-items-header margin-bottom level">
|
||||||
|
<h4>{{ section.title }}</h4>
|
||||||
|
<p :data-route="'marketplace/category/' + section.title">{{ 'See All' }}</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<item-cards-container
|
||||||
|
:container_name="section.title"
|
||||||
|
:items="section.items"
|
||||||
|
:item_id_fieldname="item_id_fieldname"
|
||||||
|
:on_click="go_to_item_details_page"
|
||||||
|
>
|
||||||
|
</item-cards-container>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import SearchInput from '../components/SearchInput.vue';
|
||||||
|
import ItemCardsContainer from '../components/ItemCardsContainer.vue';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'home-page',
|
||||||
|
components: {
|
||||||
|
SearchInput,
|
||||||
|
ItemCardsContainer
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
page_name: frappe.get_route()[1],
|
||||||
|
item_id_fieldname: 'hub_item_code',
|
||||||
|
search_value: '',
|
||||||
|
|
||||||
|
sections: [],
|
||||||
|
|
||||||
|
// Constants
|
||||||
|
search_placeholder: __('Search for anything ...'),
|
||||||
|
};
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
// refreshed
|
||||||
|
this.search_value = '';
|
||||||
|
this.get_items();
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
get_items() {
|
||||||
|
hub.call('get_data_for_homepage', {
|
||||||
|
country: frappe.defaults.get_user_default('country')
|
||||||
|
})
|
||||||
|
.then((data) => {
|
||||||
|
this.sections.push({
|
||||||
|
title: __('Explore'),
|
||||||
|
items: data.random_items
|
||||||
|
});
|
||||||
|
if (data.items_by_country.length) {
|
||||||
|
this.sections.push({
|
||||||
|
title: __('Near you'),
|
||||||
|
items: data.items_by_country
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const category_items = data.category_items;
|
||||||
|
|
||||||
|
if (category_items) {
|
||||||
|
Object.keys(category_items).map(category => {
|
||||||
|
const items = category_items[category];
|
||||||
|
|
||||||
|
this.sections.push({
|
||||||
|
title: __(category),
|
||||||
|
items
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
go_to_item_details_page(hub_item_code) {
|
||||||
|
frappe.set_route(`marketplace/item/${hub_item_code}`);
|
||||||
|
},
|
||||||
|
|
||||||
|
set_search_route() {
|
||||||
|
frappe.set_route('marketplace', 'search', this.search_value);
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped></style>
|
@ -21,6 +21,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<item-cards-container
|
<item-cards-container
|
||||||
|
:container_name="page_title"
|
||||||
:items="selected_items"
|
:items="selected_items"
|
||||||
:item_id_fieldname="item_id_fieldname"
|
:item_id_fieldname="item_id_fieldname"
|
||||||
:is_local="true"
|
:is_local="true"
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
<h5>{{ page_title }}</h5>
|
<h5>{{ page_title }}</h5>
|
||||||
|
|
||||||
<item-cards-container
|
<item-cards-container
|
||||||
|
:container_name="page_title"
|
||||||
:items="items"
|
:items="items"
|
||||||
:item_id_fieldname="item_id_fieldname"
|
:item_id_fieldname="item_id_fieldname"
|
||||||
:on_click="go_to_item_details_page"
|
:on_click="go_to_item_details_page"
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
<h5>{{ page_title }}</h5>
|
<h5>{{ page_title }}</h5>
|
||||||
|
|
||||||
<item-cards-container
|
<item-cards-container
|
||||||
|
:container_name="page_title"
|
||||||
:items="items"
|
:items="items"
|
||||||
:item_id_fieldname="item_id_fieldname"
|
:item_id_fieldname="item_id_fieldname"
|
||||||
:on_click="go_to_item_details_page"
|
:on_click="go_to_item_details_page"
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
>
|
>
|
||||||
<search-input
|
<search-input
|
||||||
:placeholder="search_placeholder"
|
:placeholder="search_placeholder"
|
||||||
:on_search="set_route"
|
:on_search="set_route_and_get_items"
|
||||||
v-model="search_value"
|
v-model="search_value"
|
||||||
>
|
>
|
||||||
</search-input>
|
</search-input>
|
||||||
@ -13,6 +13,7 @@
|
|||||||
<h5>{{ page_title }}</h5>
|
<h5>{{ page_title }}</h5>
|
||||||
|
|
||||||
<item-cards-container
|
<item-cards-container
|
||||||
|
container_name="Search"
|
||||||
:items="items"
|
:items="items"
|
||||||
:item_id_fieldname="item_id_fieldname"
|
:item_id_fieldname="item_id_fieldname"
|
||||||
:on_click="go_to_item_details_page"
|
:on_click="go_to_item_details_page"
|
||||||
@ -62,7 +63,7 @@ export default {
|
|||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
set_route() {
|
set_route_and_get_items() {
|
||||||
frappe.set_route('marketplace', 'search', this.search_value);
|
frappe.set_route('marketplace', 'search', this.search_value);
|
||||||
this.get_items();
|
this.get_items();
|
||||||
},
|
},
|
||||||
|
@ -1,60 +0,0 @@
|
|||||||
import SubPage from './subpage';
|
|
||||||
import { make_search_bar } from '../components/search_bar';
|
|
||||||
import { get_item_card_container_html } from '../components/items_container';
|
|
||||||
import { get_item_card_html } from '../components/item_card';
|
|
||||||
|
|
||||||
erpnext.hub.Home = class Home extends SubPage {
|
|
||||||
make_wrapper() {
|
|
||||||
super.make_wrapper();
|
|
||||||
|
|
||||||
make_search_bar({
|
|
||||||
wrapper: this.$wrapper,
|
|
||||||
on_search: keyword => {
|
|
||||||
frappe.set_route('marketplace', 'search', keyword);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
refresh() {
|
|
||||||
this.get_items_and_render();
|
|
||||||
}
|
|
||||||
|
|
||||||
get_items_and_render() {
|
|
||||||
this.$wrapper.find('.hub-items-container').empty();
|
|
||||||
this.get_data()
|
|
||||||
.then(data => {
|
|
||||||
this.render(data);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
get_data() {
|
|
||||||
return hub.call('get_data_for_homepage', { country: frappe.defaults.get_user_default('country') });
|
|
||||||
}
|
|
||||||
|
|
||||||
render(data) {
|
|
||||||
let html = get_item_card_container_html(data.random_items, __('Explore'));
|
|
||||||
this.$wrapper.append(html);
|
|
||||||
|
|
||||||
if (data.items_by_country.length) {
|
|
||||||
html = get_item_card_container_html(data.items_by_country, __('Near you'));
|
|
||||||
this.$wrapper.append(html);
|
|
||||||
}
|
|
||||||
|
|
||||||
const category_items = data.category_items;
|
|
||||||
|
|
||||||
if (category_items) {
|
|
||||||
Object.keys(category_items).map(category => {
|
|
||||||
const items = category_items[category];
|
|
||||||
const see_all_link = `<p data-route="marketplace/category/${category}">See All</p>`;
|
|
||||||
|
|
||||||
html = get_item_card_container_html(
|
|
||||||
items,
|
|
||||||
__(category),
|
|
||||||
get_item_card_html,
|
|
||||||
see_all_link
|
|
||||||
);
|
|
||||||
this.$wrapper.append(html);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
x
Reference in New Issue
Block a user