mirror of
https://github.com/frappe/erpnext.git
synced 2026-05-31 18:59:08 +00:00
[hub] merge conflicts
This commit is contained in:
@@ -86,6 +86,10 @@ export default {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!route) {
|
||||||
|
return NotFound;
|
||||||
|
}
|
||||||
|
|
||||||
return route_map[route];
|
return route_map[route];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
102
erpnext/public/js/hub/Sidebar.vue
Normal file
102
erpnext/public/js/hub/Sidebar.vue
Normal file
@@ -0,0 +1,102 @@
|
|||||||
|
<template>
|
||||||
|
<div ref="sidebar-container">
|
||||||
|
<ul class="list-unstyled hub-sidebar-group" data-nav-buttons>
|
||||||
|
<li class="hub-sidebar-item" v-for="item in items" :key="item.label" v-route="item.route" v-show="item.condition === undefined || item.condition()">
|
||||||
|
{{ item.label }}
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<ul class="list-unstyled hub-sidebar-group" data-categories>
|
||||||
|
<li class="hub-sidebar-item" v-for="category in categories" :key="category.label" v-route="category.route">
|
||||||
|
{{ category.label }}
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
items: [
|
||||||
|
{
|
||||||
|
label: __('Browse'),
|
||||||
|
route: 'marketplace/home'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: __('Become a Seller'),
|
||||||
|
action: this.show_register_dialog,
|
||||||
|
condition: () => !hub.settings.registered
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: __('Saved Products'),
|
||||||
|
route: 'marketplace/saved-products',
|
||||||
|
condition: () => hub.settings.registered
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: __('Your Profile'),
|
||||||
|
route: 'marketplace/profile',
|
||||||
|
condition: () => hub.settings.registered
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: __('Your Products'),
|
||||||
|
route: 'marketplace/my-products',
|
||||||
|
condition: () => hub.settings.registered
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: __('Publish Products'),
|
||||||
|
route: 'marketplace/publish',
|
||||||
|
condition: () => hub.settings.registered
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: __('Selling'),
|
||||||
|
route: 'marketplace/selling',
|
||||||
|
condition: () => hub.settings.registered
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: __('Buying'),
|
||||||
|
route: 'marketplace/buying',
|
||||||
|
condition: () => hub.settings.registered
|
||||||
|
},
|
||||||
|
],
|
||||||
|
categories: []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
this.get_categories()
|
||||||
|
.then(categories => {
|
||||||
|
this.categories = categories.map(c => {
|
||||||
|
return {
|
||||||
|
label: __(c.name),
|
||||||
|
route: 'marketplace/category/' + c.name
|
||||||
|
}
|
||||||
|
});
|
||||||
|
this.categories.unshift({
|
||||||
|
label: __('All'),
|
||||||
|
route: 'marketplace/home'
|
||||||
|
});
|
||||||
|
this.$nextTick(() => {
|
||||||
|
this.update_sidebar_state();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.update_sidebar_state();
|
||||||
|
frappe.route.on('change', () => this.update_sidebar_state());
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
get_categories() {
|
||||||
|
return hub.call('get_categories');
|
||||||
|
},
|
||||||
|
update_sidebar_state() {
|
||||||
|
const container = $(this.$refs['sidebar-container']);
|
||||||
|
const route = frappe.get_route();
|
||||||
|
const route_str = route.join('/');
|
||||||
|
const part_route_str = route.slice(0, 2).join('/');
|
||||||
|
const $sidebar_item = container.find(`[data-route="${route_str}"], [data-route="${part_route_str}"]`);
|
||||||
|
|
||||||
|
const $siblings = container.find('[data-route]');
|
||||||
|
$siblings.removeClass('active').addClass('text-muted');
|
||||||
|
$sidebar_item.addClass('active').removeClass('text-muted');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
@@ -3,6 +3,7 @@ import './vue-plugins';
|
|||||||
|
|
||||||
// components
|
// components
|
||||||
import PageContainer from './PageContainer.vue';
|
import PageContainer from './PageContainer.vue';
|
||||||
|
import Sidebar from './Sidebar.vue';
|
||||||
import { ProfileDialog } from './components/profile_dialog';
|
import { ProfileDialog } from './components/profile_dialog';
|
||||||
|
|
||||||
// helpers
|
// helpers
|
||||||
@@ -57,79 +58,10 @@ erpnext.hub.Marketplace = class Marketplace {
|
|||||||
make_sidebar() {
|
make_sidebar() {
|
||||||
this.$sidebar = this.$parent.find('.layout-side-section').addClass('hidden-xs');
|
this.$sidebar = this.$parent.find('.layout-side-section').addClass('hidden-xs');
|
||||||
|
|
||||||
this.make_sidebar_nav_buttons();
|
new Vue({
|
||||||
this.make_sidebar_categories();
|
el: $('<div>').appendTo(this.$sidebar)[0],
|
||||||
}
|
render: h => h(Sidebar)
|
||||||
|
});
|
||||||
make_sidebar_nav_buttons() {
|
|
||||||
let $nav_group = this.$sidebar.find('[data-nav-buttons]');
|
|
||||||
if (!$nav_group.length) {
|
|
||||||
$nav_group = $('<ul class="list-unstyled hub-sidebar-group" data-nav-buttons>').appendTo(this.$sidebar);
|
|
||||||
}
|
|
||||||
$nav_group.empty();
|
|
||||||
|
|
||||||
const user_specific_items_html = this.registered
|
|
||||||
? `<li class="hub-sidebar-item" data-route="marketplace/saved-products">
|
|
||||||
${__('Saved Products')}
|
|
||||||
</li>
|
|
||||||
<li class="hub-sidebar-item text-muted" data-route="marketplace/profile">
|
|
||||||
${__('Your Profile')}
|
|
||||||
</li>
|
|
||||||
<li class="hub-sidebar-item text-muted" data-route="marketplace/publish">
|
|
||||||
${__('Publish Products')}
|
|
||||||
</li>
|
|
||||||
<li class="hub-sidebar-item text-muted" data-route="marketplace/selling">
|
|
||||||
${__('Selling')}
|
|
||||||
</li>
|
|
||||||
<li class="hub-sidebar-item text-muted" data-route="marketplace/buying">
|
|
||||||
${__('Buying')}
|
|
||||||
</li>
|
|
||||||
`
|
|
||||||
|
|
||||||
: `<li class="hub-sidebar-item text-muted" data-action="show_register_dialog">
|
|
||||||
${__('Become a seller')}
|
|
||||||
</li>`;
|
|
||||||
|
|
||||||
$nav_group.append(`
|
|
||||||
<li class="hub-sidebar-item" data-route="marketplace/home">
|
|
||||||
${__('Browse')}
|
|
||||||
</li>
|
|
||||||
${user_specific_items_html}
|
|
||||||
`);
|
|
||||||
}
|
|
||||||
|
|
||||||
make_sidebar_categories() {
|
|
||||||
hub.call('get_categories')
|
|
||||||
.then(categories => {
|
|
||||||
categories = categories.map(d => d.name);
|
|
||||||
|
|
||||||
const sidebar_items = [
|
|
||||||
`<li class="hub-sidebar-item bold is-title">
|
|
||||||
${__('Category')}
|
|
||||||
</li>`,
|
|
||||||
`<li class="hub-sidebar-item active" data-route="marketplace/home">
|
|
||||||
${__('All')}
|
|
||||||
</li>`,
|
|
||||||
...(this.registered
|
|
||||||
? [`<li class="hub-sidebar-item active" data-route="marketplace/my-products">
|
|
||||||
${__('Your Products')}
|
|
||||||
</li>`]
|
|
||||||
: []),
|
|
||||||
...categories.map(category => `
|
|
||||||
<li class="hub-sidebar-item text-muted" data-route="marketplace/category/${category}">
|
|
||||||
${__(category)}
|
|
||||||
</li>
|
|
||||||
`)
|
|
||||||
];
|
|
||||||
|
|
||||||
this.$sidebar.append(`
|
|
||||||
<ul class="list-unstyled">
|
|
||||||
${sidebar_items.join('')}
|
|
||||||
</ul>
|
|
||||||
`);
|
|
||||||
|
|
||||||
this.update_sidebar();
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
make_body() {
|
make_body() {
|
||||||
@@ -147,18 +79,6 @@ erpnext.hub.Marketplace = class Marketplace {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
update_sidebar() {
|
|
||||||
const route = frappe.get_route();
|
|
||||||
const route_str = route.join('/');
|
|
||||||
const part_route_str = route.slice(0, 2).join('/');
|
|
||||||
const $sidebar_item = this.$sidebar.find(`[data-route="${route_str}"], [data-route="${part_route_str}"]`);
|
|
||||||
|
|
||||||
|
|
||||||
const $siblings = this.$sidebar.find('[data-route]');
|
|
||||||
$siblings.removeClass('active').addClass('text-muted');
|
|
||||||
$sidebar_item.addClass('active').removeClass('text-muted');
|
|
||||||
}
|
|
||||||
|
|
||||||
refresh() {
|
refresh() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
<template>
|
<template>
|
||||||
<div v-if="item_details">
|
<div v-if="item_details">
|
||||||
|
<div>
|
||||||
|
<a class="text-muted" v-route="'marketplace/buying'">← {{ __('Back to Messages') }}</a>
|
||||||
|
</div>
|
||||||
<section-header>
|
<section-header>
|
||||||
<div class="flex flex-column margin-bottom">
|
<div class="flex flex-column margin-bottom">
|
||||||
<h4>{{ item_details.item_name }}</h4>
|
<h4>{{ item_details.item_name }}</h4>
|
||||||
|
|||||||
@@ -7,7 +7,6 @@
|
|||||||
|
|
||||||
<detail-view
|
<detail-view
|
||||||
:title="title"
|
:title="title"
|
||||||
:subtitles="subtitles"
|
|
||||||
:image="image"
|
:image="image"
|
||||||
:sections="sections"
|
:sections="sections"
|
||||||
:show_skeleton="init"
|
:show_skeleton="init"
|
||||||
|
|||||||
@@ -1,101 +0,0 @@
|
|||||||
import SubPage from './subpage';
|
|
||||||
|
|
||||||
erpnext.hub.MessageList = class BuyingMessages extends SubPage {
|
|
||||||
make_wrapper() {
|
|
||||||
const messages_of = this.options[0];
|
|
||||||
if (messages_of === 'Buying') {
|
|
||||||
this.back_route = 'marketplace/buying-messages'
|
|
||||||
} else {
|
|
||||||
this.back_route = 'marketplace/selling-messages'
|
|
||||||
}
|
|
||||||
super.make_wrapper();
|
|
||||||
this.add_back_link(__('Back to Messages'), this.back_route);
|
|
||||||
this.$message_container = this.add_section({ title: 'Buy' });
|
|
||||||
}
|
|
||||||
|
|
||||||
refresh() {
|
|
||||||
const item_code = frappe.get_route()[2] || null;
|
|
||||||
if (!item_code) {
|
|
||||||
frappe.set_route(this.back_route);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.get_item_details(item_code)
|
|
||||||
.then(item_details => {
|
|
||||||
this.item_details = item_details;
|
|
||||||
this.$message_container.find('.hub-section-header h4').text(this.item_details.item_name);
|
|
||||||
|
|
||||||
// make chat area
|
|
||||||
this.$message_container.find('.hub-section-body').html(`
|
|
||||||
<div class="col-md-7 message-container">
|
|
||||||
<div class="message-list"></div>
|
|
||||||
<div class="message-input"></div>
|
|
||||||
</div>
|
|
||||||
`)
|
|
||||||
this.make_message_input();
|
|
||||||
|
|
||||||
// fetch messages
|
|
||||||
this.get_messages(item_details)
|
|
||||||
.then(messages => {
|
|
||||||
const $message_list = this.$message_container.find('.message-list');
|
|
||||||
const html = messages.map(get_message_html).join('');
|
|
||||||
$message_list.html(html);
|
|
||||||
frappe.dom.scroll_to_bottom($message_list);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
get_messages(item_details) {
|
|
||||||
return hub.call('get_messages', {
|
|
||||||
against_seller: item_details.hub_seller,
|
|
||||||
against_item: item_details.hub_item_code
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
get_item_details(hub_item_code) {
|
|
||||||
return hub.call('get_item_details', { hub_item_code })
|
|
||||||
}
|
|
||||||
|
|
||||||
make_message_input() {
|
|
||||||
this.message_input = new frappe.ui.CommentArea({
|
|
||||||
parent: this.$message_container.find('.message-input'),
|
|
||||||
on_submit: (message) => {
|
|
||||||
this.message_input.reset();
|
|
||||||
|
|
||||||
// append message html
|
|
||||||
const $message_list = this.$message_container.find('.message-list');
|
|
||||||
const message_html = get_message_html({
|
|
||||||
sender: hub.settings.company_email,
|
|
||||||
content: message
|
|
||||||
});
|
|
||||||
$message_list.append(message_html);
|
|
||||||
frappe.dom.scroll_to_bottom($message_list);
|
|
||||||
|
|
||||||
// send message
|
|
||||||
hub.call('send_message', {
|
|
||||||
from_seller: hub.settings.company_email,
|
|
||||||
to_seller: this.item_details.hub_seller,
|
|
||||||
hub_item: this.item_details.hub_item_code,
|
|
||||||
message
|
|
||||||
});
|
|
||||||
},
|
|
||||||
no_wrapper: true
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function get_message_html(message) {
|
|
||||||
return `
|
|
||||||
<div class="level margin-bottom">
|
|
||||||
<div class="level-left ellipsis" style="width: 80%;">
|
|
||||||
${frappe.avatar(message.sender)}
|
|
||||||
<div style="white-space: normal;">
|
|
||||||
${message.content}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="level-right text-muted">
|
|
||||||
${comment_when(message.creation, true)}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
`;
|
|
||||||
}
|
|
||||||
@@ -21,7 +21,9 @@ Vue.component('empty-state', EmptyState);
|
|||||||
Vue.directive('route', {
|
Vue.directive('route', {
|
||||||
bind(el, binding) {
|
bind(el, binding) {
|
||||||
const route = binding.value;
|
const route = binding.value;
|
||||||
|
if (!route) return;
|
||||||
el.classList.add('cursor-pointer');
|
el.classList.add('cursor-pointer');
|
||||||
|
el.dataset.route = route;
|
||||||
el.addEventListener('click', () => frappe.set_route(route));
|
el.addEventListener('click', () => frappe.set_route(route));
|
||||||
},
|
},
|
||||||
unbind(el) {
|
unbind(el) {
|
||||||
|
|||||||
@@ -100,6 +100,7 @@ body[data-route^="marketplace/"] {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.hub-card-image {
|
.hub-card-image {
|
||||||
|
position: relative;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
object-fit: contain;
|
object-fit: contain;
|
||||||
@@ -212,6 +213,7 @@ body[data-route^="marketplace/"] {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.hub-list-image {
|
.hub-list-image {
|
||||||
|
position: relative;
|
||||||
width: 58px;
|
width: 58px;
|
||||||
height: 58px;
|
height: 58px;
|
||||||
border-right: 1px solid @border-color;
|
border-right: 1px solid @border-color;
|
||||||
|
|||||||
Reference in New Issue
Block a user