Merge branch 'develop' of https://github.com/frappe/frappe into contacts-ref
This commit is contained in:
commit
5ca8bbdd36
29 changed files with 847 additions and 87 deletions
|
|
@ -1075,12 +1075,4 @@ def generate_keys(user):
|
|||
user_details.save()
|
||||
|
||||
return {"api_secret": api_secret}
|
||||
frappe.throw(frappe._("Not Permitted"), frappe.PermissionError)
|
||||
|
||||
@frappe.whitelist()
|
||||
def update_profile_info(profile_info):
|
||||
profile_info = json.loads(profile_info)
|
||||
user = frappe.get_doc('User', frappe.session.user)
|
||||
user.update(profile_info)
|
||||
user.save()
|
||||
return user
|
||||
frappe.throw(frappe._("Not Permitted"), frappe.PermissionError)
|
||||
|
|
@ -214,7 +214,7 @@ class DashboardChart {
|
|||
return frappe.xcall(
|
||||
method,
|
||||
{
|
||||
chart_name: this.chart_doc.name,
|
||||
chart: this.chart_doc,
|
||||
filters: filters,
|
||||
refresh: refresh ? 1 : 0,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,21 +8,25 @@ from frappe.utils import add_to_date
|
|||
|
||||
def cache_source(function):
|
||||
def wrapper(*args, **kwargs):
|
||||
chart_name = kwargs.get("chart_name")
|
||||
cache_key = 'chart-data:{}'.format(chart_name)
|
||||
chart = kwargs.get("chart")
|
||||
no_cache = kwargs.get("no_cache")
|
||||
if no_cache:
|
||||
return function(chart, no_cache)
|
||||
chart_name = frappe.parse_json(chart).name
|
||||
cache_key = "chart-data:{}".format(chart_name)
|
||||
if int(kwargs.get("refresh") or 0):
|
||||
results = generate_and_cache_results(chart_name, function, cache_key)
|
||||
results = generate_and_cache_results(chart, chart_name, function, cache_key)
|
||||
else:
|
||||
cached_results = frappe.cache().get_value(cache_key)
|
||||
if cached_results:
|
||||
results = json.loads(frappe.safe_decode(cached_results))
|
||||
results = frappe.parse_json(frappe.safe_decode(cached_results))
|
||||
else:
|
||||
results = generate_and_cache_results(chart_name, function, cache_key)
|
||||
results = generate_and_cache_results(chart, chart_name, function, cache_key)
|
||||
return results
|
||||
return wrapper
|
||||
|
||||
def generate_and_cache_results(chart_name, function, cache_key):
|
||||
results = function(chart_name)
|
||||
def generate_and_cache_results(chart, chart_name, function, cache_key):
|
||||
results = function(chart)
|
||||
frappe.cache().set_value(cache_key, json.dumps(results, default=str))
|
||||
frappe.db.set_value("Dashboard Chart", chart_name, "last_synced_on", frappe.utils.now(), update_modified = False)
|
||||
return results
|
||||
|
|
|
|||
|
|
@ -3,20 +3,21 @@
|
|||
# For license information, please see license.txt
|
||||
|
||||
from __future__ import unicode_literals
|
||||
import frappe, json
|
||||
import frappe
|
||||
from frappe import _
|
||||
import datetime
|
||||
from frappe.core.page.dashboard.dashboard import cache_source, get_from_date_from_timespan
|
||||
from frappe.utils import nowdate, add_to_date, getdate, get_last_day, formatdate
|
||||
from frappe.model.document import Document
|
||||
|
||||
@frappe.whitelist()
|
||||
@cache_source
|
||||
def get(chart_name, from_date=None, to_date=None, refresh = None):
|
||||
chart = frappe.get_doc('Dashboard Chart', chart_name)
|
||||
def get(chart, no_cache=None, from_date=None, to_date=None, refresh = None):
|
||||
|
||||
chart = frappe.parse_json(chart)
|
||||
timespan = chart.timespan
|
||||
timegrain = chart.time_interval
|
||||
filters = json.loads(chart.filters_json)
|
||||
filters = frappe.parse_json(chart.filters_json)
|
||||
|
||||
# don't include cancelled documents
|
||||
filters['docstatus'] = ('<', 2)
|
||||
|
|
@ -24,7 +25,7 @@ def get(chart_name, from_date=None, to_date=None, refresh = None):
|
|||
if not from_date:
|
||||
from_date = get_from_date_from_timespan(to_date, timespan)
|
||||
if not to_date:
|
||||
to_date = nowdate()
|
||||
to_date = datetime.datetime.now()
|
||||
|
||||
# get conditions from filters
|
||||
conditions, values = frappe.db.build_conditions(filters)
|
||||
|
|
@ -78,7 +79,7 @@ def convert_to_dates(data, timegrain):
|
|||
result = []
|
||||
for d in data:
|
||||
if timegrain == 'Daily':
|
||||
result.append([add_to_date('{:d}-01-01'.format(int(d[0])), days = d[1]), d[2]])
|
||||
result.append([add_to_date('{:d}-01-01'.format(int(d[0])), days = d[1] - 1), d[2]])
|
||||
elif timegrain == 'Weekly':
|
||||
result.append([add_to_date(add_to_date('{:d}-01-01'.format(int(d[0])), weeks = d[1] + 1), days = -1), d[2]])
|
||||
elif timegrain == 'Monthly':
|
||||
|
|
|
|||
|
|
@ -40,9 +40,10 @@ class TestDashboardChart(unittest.TestCase):
|
|||
if frappe.db.exists('Dashboard Chart', 'Test Dashboard Chart'):
|
||||
frappe.delete_doc('Dashboard Chart', 'Test Dashboard Chart')
|
||||
|
||||
frappe.get_doc(dict(
|
||||
chart = frappe.get_doc(dict(
|
||||
doctype = 'Dashboard Chart',
|
||||
chart_name = 'Test Dashboard Chart',
|
||||
name = 'Test Dashboard Chart',
|
||||
chart_type = 'Count',
|
||||
document_type = 'DocType',
|
||||
based_on = 'creation',
|
||||
|
|
@ -54,7 +55,7 @@ class TestDashboardChart(unittest.TestCase):
|
|||
|
||||
cur_date = datetime.now() - relativedelta(years=1)
|
||||
|
||||
result = get(chart_name ='Test Dashboard Chart', refresh = 1)
|
||||
result = get(chart = chart)
|
||||
for idx in range(13):
|
||||
month = datetime(int(cur_date.year), int(cur_date.strftime('%m')), int(calendar.monthrange(cur_date.year, cur_date.month)[1]))
|
||||
month = formatdate(month.strftime('%Y-%m-%d'))
|
||||
|
|
@ -72,9 +73,9 @@ class TestDashboardChart(unittest.TestCase):
|
|||
|
||||
frappe.db.sql('delete from `tabError Log`')
|
||||
|
||||
frappe.get_doc(dict(
|
||||
chart = dict(
|
||||
doctype = 'Dashboard Chart',
|
||||
chart_name = 'Test Empty Dashboard Chart',
|
||||
name = 'Test Empty Dashboard Chart',
|
||||
chart_type = 'Count',
|
||||
document_type = 'Error Log',
|
||||
based_on = 'creation',
|
||||
|
|
@ -82,11 +83,11 @@ class TestDashboardChart(unittest.TestCase):
|
|||
time_interval = 'Monthly',
|
||||
filters_json = '{}',
|
||||
timeseries = 1
|
||||
)).insert()
|
||||
)
|
||||
|
||||
cur_date = datetime.now() - relativedelta(years=1)
|
||||
|
||||
result = get(chart_name ='Test Empty Dashboard Chart', refresh = 1)
|
||||
result = get(chart = chart, refresh = 1)
|
||||
for idx in range(13):
|
||||
month = datetime(int(cur_date.year), int(cur_date.strftime('%m')), int(calendar.monthrange(cur_date.year, cur_date.month)[1]))
|
||||
month = formatdate(month.strftime('%Y-%m-%d'))
|
||||
|
|
@ -104,9 +105,9 @@ class TestDashboardChart(unittest.TestCase):
|
|||
# create one data point
|
||||
frappe.get_doc(dict(doctype = 'Error Log', creation = '2018-06-01 00:00:00')).insert()
|
||||
|
||||
frappe.get_doc(dict(
|
||||
chart = dict(
|
||||
doctype = 'Dashboard Chart',
|
||||
chart_name = 'Test Empty Dashboard Chart 2',
|
||||
name = 'Test Empty Dashboard Chart 2',
|
||||
chart_type = 'Count',
|
||||
document_type = 'Error Log',
|
||||
based_on = 'creation',
|
||||
|
|
@ -114,11 +115,10 @@ class TestDashboardChart(unittest.TestCase):
|
|||
time_interval = 'Monthly',
|
||||
filters_json = '{}',
|
||||
timeseries = 1
|
||||
)).insert()
|
||||
|
||||
)
|
||||
cur_date = datetime.now() - relativedelta(years=1)
|
||||
|
||||
result = get(chart_name ='Test Empty Dashboard Chart 2', refresh = 1)
|
||||
result = get(chart = chart, refresh = 1)
|
||||
for idx in range(13):
|
||||
month = datetime(int(cur_date.year), int(cur_date.strftime('%m')), int(calendar.monthrange(cur_date.year, cur_date.month)[1]))
|
||||
month = formatdate(month.strftime('%Y-%m-%d'))
|
||||
|
|
|
|||
|
|
@ -29,6 +29,12 @@ frappe.pages['activity'].on_page_load = function(wrapper) {
|
|||
doctype = $(this).attr("data-doctype"),
|
||||
docname = $(this).attr("data-docname");
|
||||
|
||||
[link_doctype, link_name, doctype, docname] =
|
||||
[link_doctype, link_name, doctype, docname].map(decodeURIComponent);
|
||||
|
||||
link_doctype = link_doctype && link_doctype !== 'null' ? link_doctype : null;
|
||||
link_name = link_name && link_name !== 'null' ? link_name : null;
|
||||
|
||||
if (doctype && docname) {
|
||||
if (link_doctype && link_name) {
|
||||
frappe.route_options = {
|
||||
|
|
|
|||
|
|
@ -13,18 +13,14 @@ def get_feed(start, page_length):
|
|||
match_conditions_comment = get_feed_match_conditions(frappe.session.user, 'Comment')
|
||||
|
||||
result = frappe.db.sql("""select X.*
|
||||
from (select `tabCommunication`.name, `tabCommunication`.owner, `tabCommunication`.modified,
|
||||
`tabCommunication`.creation, `tabCommunication`.seen, `tabCommunication`.comment_type,
|
||||
`tabCommunication`.reference_doctype, `tabCommunication`.reference_name, `tabCommunication`.subject,
|
||||
`tabCommunication`.communication_type, `tabCommunication`.communication_medium, `tabCommunication`.content,
|
||||
`tabCommunication Link`.link_doctype, `tabCommunication Link`.link_name
|
||||
from (select name, owner, modified, creation, seen, comment_type,
|
||||
reference_doctype, reference_name, '' as link_doctype, '' as link_name, subject,
|
||||
communication_type, communication_medium, content
|
||||
from
|
||||
`tabCommunication`
|
||||
inner join `tabCommunication Link`
|
||||
on `tabCommunication`.name=`tabCommunication Link`.parent
|
||||
where
|
||||
`tabCommunication`.communication_type = "Communication"
|
||||
and `tabCommunication`.communication_medium != "Email"
|
||||
communication_type = 'Communication'
|
||||
and communication_medium != 'Email'
|
||||
and {match_conditions_communication}
|
||||
UNION
|
||||
select name, owner, modified, creation, '0', 'Updated',
|
||||
|
|
|
|||
|
|
@ -2,10 +2,10 @@
|
|||
<div class="col-xs-3 text-right activity-date"><span class="{%= date_class %}">
|
||||
{%= date_sep || "" %}</span></div>
|
||||
<div class="col-xs-9 activity-message"
|
||||
data-doctype="{%= reference_doctype %}"
|
||||
data-docname="{%= reference_name %}"
|
||||
data-link-doctype="{{ link_doctype }}"
|
||||
data-link-name="{{ link_name }}"
|
||||
data-doctype="{%= encodeURIComponent(reference_doctype) %}"
|
||||
data-docname="{%= encodeURIComponent(reference_name) %}"
|
||||
data-link-doctype="{{ encodeURIComponent(link_doctype) }}"
|
||||
data-link-name="{{ encodeURIComponent(link_name) }}"
|
||||
title="{%= by %} / {%= frappe.datetime.str_to_user(creation) %}">
|
||||
{{ avatar }}
|
||||
<span class="small">
|
||||
|
|
|
|||
0
frappe/desk/page/user_profile/__init__.py
Normal file
0
frappe/desk/page/user_profile/__init__.py
Normal file
121
frappe/desk/page/user_profile/user_profile.css
Normal file
121
frappe/desk/page/user_profile/user_profile.css
Normal file
|
|
@ -0,0 +1,121 @@
|
|||
.user-image-container {
|
||||
margin-top: 7px;
|
||||
padding-bottom: 100%;
|
||||
}
|
||||
|
||||
.user-image-container .standard-image {
|
||||
font-size: 72px;
|
||||
}
|
||||
|
||||
.profile-details {
|
||||
margin: -5px 5px;
|
||||
}
|
||||
|
||||
.profile-links {
|
||||
margin: 30px 5px;
|
||||
}
|
||||
|
||||
.user-initial {
|
||||
font-size: 72px;
|
||||
}
|
||||
|
||||
.chart-column-container{
|
||||
border-bottom: 1px solid #d1d8dd;
|
||||
margin: 5px 0;
|
||||
}
|
||||
|
||||
.chart-container text.title {
|
||||
text-transform: uppercase;
|
||||
font-size: 11px;
|
||||
}
|
||||
|
||||
.heatmap-container {
|
||||
height: 170px
|
||||
}
|
||||
|
||||
.performance-heatmap {
|
||||
width: 80%;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.performance-heatmap .chart-container {
|
||||
margin-left: 30px;
|
||||
}
|
||||
|
||||
.performance-heatmap .frappe-chart {
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
||||
.performance-heatmap .frappe-chart .chart-legend {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.performance-percentage-chart .frappe-chart {
|
||||
position: absolute;
|
||||
top: 5px;
|
||||
}
|
||||
|
||||
.performance-line-chart .frappe-chart {
|
||||
margin-top: -20px;
|
||||
}
|
||||
|
||||
.percentage-chart-container {
|
||||
height: 130px;
|
||||
}
|
||||
|
||||
.line-chart-container .chart-filter {
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.recent-activity {
|
||||
margin: 20px;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.show-more-activity {
|
||||
text-align: center;
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.recent-activity-item {
|
||||
margin: 15px 5px;
|
||||
}
|
||||
|
||||
.interest-icon {
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
.chart-filter {
|
||||
position: relative;
|
||||
top: 5px;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.filter-label {
|
||||
margin-right: 4px;
|
||||
}
|
||||
|
||||
.performance-title {
|
||||
position: relative;
|
||||
left: 30px;
|
||||
top: 20px;
|
||||
}
|
||||
|
||||
@media (max-width: 991px) {
|
||||
.user-profile-sidebar {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.percentage-chart-container {
|
||||
border-top: 1px solid #d1d8dd;
|
||||
}
|
||||
|
||||
.user-profile-sidebar .profile-links {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.user-profile-sidebar .profile-details {
|
||||
width: 50%;
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
25
frappe/desk/page/user_profile/user_profile.html
Normal file
25
frappe/desk/page/user_profile/user_profile.html
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
<div class="row user-profile">
|
||||
<div class="col-md-12">
|
||||
<div class="performance-graphs">
|
||||
<div class="chart-column-container heatmap-container hidden-xs hidden-sm">
|
||||
<div class="performance-heatmap">
|
||||
</div>
|
||||
</div>
|
||||
<div class="chart-column-container percentage-chart-container">
|
||||
<div class="performance-percentage-chart">
|
||||
</div>
|
||||
</div>
|
||||
<div class="chart-column-container line-chart-container">
|
||||
<div class="performance-line-chart">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="recent-activity">
|
||||
<p class="recent-activity-title h6 uppercase">{%=__("Recent Activity") %}</p>
|
||||
<div class="recent-activity-list">
|
||||
</div>
|
||||
<div class="show-more-activity"><a class="text-muted">{%=__("Show More Activity") %}</a></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
456
frappe/desk/page/user_profile/user_profile.js
Normal file
456
frappe/desk/page/user_profile/user_profile.js
Normal file
|
|
@ -0,0 +1,456 @@
|
|||
frappe.provide('frappe.energy_points');
|
||||
|
||||
frappe.pages['user-profile'].on_page_load = function(wrapper) {
|
||||
|
||||
frappe.ui.make_app_page({
|
||||
parent: wrapper,
|
||||
title: __('User Profile'),
|
||||
});
|
||||
|
||||
let user_profile = new UserProfile(wrapper);
|
||||
$(wrapper).bind('show', ()=> {
|
||||
user_profile.show();
|
||||
});
|
||||
};
|
||||
|
||||
class UserProfile {
|
||||
|
||||
constructor(wrapper) {
|
||||
this.wrapper = $(wrapper);
|
||||
this.page = wrapper.page;
|
||||
this.sidebar = this.wrapper.find('.layout-side-section');
|
||||
this.main_section = this.wrapper.find('.layout-main-section');
|
||||
}
|
||||
|
||||
show() {
|
||||
let route = frappe.get_route();
|
||||
this.user_id = route[1] || frappe.session.user;
|
||||
|
||||
//validate if user
|
||||
if (route.length > 1) {
|
||||
frappe.db.exists('User', this.user_id).then( exists => {
|
||||
if (exists) {
|
||||
this.make_user_profile();
|
||||
} else {
|
||||
frappe.msgprint(__('User does not exist'));
|
||||
}
|
||||
});
|
||||
} else {
|
||||
this.user_id = frappe.session.user;
|
||||
this.make_user_profile();
|
||||
}
|
||||
}
|
||||
|
||||
make_user_profile() {
|
||||
frappe.set_route('user-profile', this.user_id);
|
||||
this.user = frappe.user_info(this.user_id);
|
||||
this.page.set_title(this.user.fullname);
|
||||
this.setup_user_search();
|
||||
this.main_section.empty().append(frappe.render_template('user_profile'));
|
||||
this.energy_points = 0;
|
||||
this.review_points = 0;
|
||||
this.rank = 0;
|
||||
this.month_rank = 0;
|
||||
this.render_user_details();
|
||||
this.render_points_and_rank();
|
||||
this.render_heatmap();
|
||||
this.render_line_chart();
|
||||
this.render_percentage_chart('type', 'Type Distribution');
|
||||
this.create_percentage_chart_filters();
|
||||
this.setup_show_more_activity();
|
||||
this.render_user_activity();
|
||||
}
|
||||
|
||||
setup_user_search() {
|
||||
this.$user_search_button = this.page.set_secondary_action('Change User', () => {
|
||||
this.show_user_search_dialog();
|
||||
});
|
||||
}
|
||||
|
||||
show_user_search_dialog() {
|
||||
let dialog = new frappe.ui.Dialog({
|
||||
title: __('Change User'),
|
||||
fields: [
|
||||
{
|
||||
fieldtype: 'Link',
|
||||
fieldname: 'user',
|
||||
options: 'User',
|
||||
label: __('User'),
|
||||
}
|
||||
],
|
||||
primary_action_label: __('Go'),
|
||||
primary_action: ({ user }) => {
|
||||
dialog.hide();
|
||||
this.user_id = user;
|
||||
this.make_user_profile();
|
||||
}
|
||||
});
|
||||
dialog.show();
|
||||
}
|
||||
|
||||
render_heatmap() {
|
||||
this.heatmap = new frappe.Chart('.performance-heatmap', {
|
||||
type: 'heatmap',
|
||||
countLabel: 'Energy Points',
|
||||
data: {},
|
||||
discreteDomains: 0,
|
||||
});
|
||||
this.update_heatmap_data();
|
||||
this.create_heatmap_chart_filters();
|
||||
}
|
||||
|
||||
update_heatmap_data(date_from) {
|
||||
frappe.xcall('frappe.desk.page.user_profile.user_profile.get_energy_points_heatmap_data', {
|
||||
user: this.user_id,
|
||||
date: date_from || frappe.datetime.year_start(),
|
||||
}).then((r) => {
|
||||
this.heatmap.update( {dataPoints: r} );
|
||||
});
|
||||
}
|
||||
|
||||
get_years_since_creation() {
|
||||
//Get years since user account created
|
||||
this.user_creation = frappe.boot.user.creation;
|
||||
let creation_year = this.get_year(this.user_creation);
|
||||
let current_year = this.get_year(frappe.datetime.now_date());
|
||||
let years_list = [];
|
||||
for (var year = current_year; year >= creation_year; year--) {
|
||||
years_list.push(year);
|
||||
}
|
||||
return years_list;
|
||||
}
|
||||
|
||||
get_year(date_str) {
|
||||
return date_str.substring(0, date_str.indexOf('-'));
|
||||
}
|
||||
|
||||
render_line_chart() {
|
||||
this.line_chart_filters = {'user': this.user_id};
|
||||
this.line_chart_config = {
|
||||
timespan: 'Last Month',
|
||||
time_interval: 'Daily',
|
||||
type: 'Line',
|
||||
value_based_on: 'points',
|
||||
chart_type: 'Sum',
|
||||
document_type: 'Energy Point Log',
|
||||
name: 'Energy Points',
|
||||
width: 'half',
|
||||
based_on: 'creation'
|
||||
};
|
||||
|
||||
this.line_chart = new frappe.Chart( '.performance-line-chart', {
|
||||
title: 'Energy Points',
|
||||
type: 'line',
|
||||
height: 200,
|
||||
data: {
|
||||
labels: [],
|
||||
datasets: [{}]
|
||||
},
|
||||
colors: ['purple'],
|
||||
axisOptions: {
|
||||
xIsSeries: 1
|
||||
}
|
||||
});
|
||||
this.update_line_chart_data();
|
||||
this.create_line_chart_filters();
|
||||
}
|
||||
|
||||
update_line_chart_data() {
|
||||
this.line_chart_config.filters_json = JSON.stringify(this.line_chart_filters);
|
||||
|
||||
frappe.xcall('frappe.desk.doctype.dashboard_chart.dashboard_chart.get', {
|
||||
chart: this.line_chart_config,
|
||||
no_cache: 1,
|
||||
}).then(chart => {
|
||||
this.line_chart.update(chart);
|
||||
});
|
||||
}
|
||||
|
||||
render_percentage_chart(field, title) {
|
||||
frappe.xcall('frappe.desk.page.user_profile.user_profile.get_energy_points_percentage_chart_data', {
|
||||
user: this.user_id,
|
||||
field: field
|
||||
}).then(chart => {
|
||||
if (chart.labels.length) {
|
||||
this.percentage_chart = new frappe.Chart( '.performance-percentage-chart', {
|
||||
title: title,
|
||||
type: 'percentage',
|
||||
data: {
|
||||
labels: chart.labels,
|
||||
datasets: chart.datasets
|
||||
},
|
||||
barOptions: {
|
||||
height: 11,
|
||||
depth: 1
|
||||
},
|
||||
height: 160,
|
||||
maxSlices: 8,
|
||||
colors: ['#5e64ff', '#743ee2', '#ff5858', '#ffa00a', '#feef72', '#28a745', '#98d85b', '#a9a7ac'],
|
||||
});
|
||||
} else {
|
||||
this.wrapper.find('.percentage-chart-container').hide();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
create_line_chart_filters() {
|
||||
let filters = [
|
||||
{
|
||||
label: 'All',
|
||||
options: ['All', 'Auto', 'Criticism', 'Appreciation', 'Revert'],
|
||||
action: (selected_item) => {
|
||||
if (selected_item === 'All') delete this.line_chart_filters.type;
|
||||
else this.line_chart_filters.type = selected_item;
|
||||
this.update_line_chart_data();
|
||||
}
|
||||
},
|
||||
{
|
||||
label: 'Last Month',
|
||||
options: ['Last Week', 'Last Month', 'Last Quarter'],
|
||||
action: (selected_item) => {
|
||||
this.line_chart_config.timespan = selected_item;
|
||||
this.update_line_chart_data();
|
||||
}
|
||||
},
|
||||
{
|
||||
label: 'Daily',
|
||||
options: ['Daily', 'Weekly', 'Monthly'],
|
||||
action: (selected_item) => {
|
||||
this.line_chart_config.time_interval = selected_item;
|
||||
this.update_line_chart_data();
|
||||
}
|
||||
},
|
||||
];
|
||||
this.render_chart_filters(filters, '.line-chart-container', 1);
|
||||
}
|
||||
|
||||
create_percentage_chart_filters() {
|
||||
let filters = [
|
||||
{
|
||||
label: 'Type',
|
||||
options: ['Type', 'Reference Doctype', 'Rule'],
|
||||
fieldnames: ['type', 'reference_doctype', 'rule'],
|
||||
action: (selected_item, fieldname) => {
|
||||
let title = selected_item + ' Distribution';
|
||||
this.render_percentage_chart(fieldname, title);
|
||||
}
|
||||
},
|
||||
];
|
||||
this.render_chart_filters(filters, '.percentage-chart-container');
|
||||
}
|
||||
|
||||
create_heatmap_chart_filters() {
|
||||
let filters = [
|
||||
{
|
||||
label: this.get_year(frappe.datetime.now_date()),
|
||||
options: this.get_years_since_creation(),
|
||||
action: (selected_item) => {
|
||||
this.update_heatmap_data(frappe.datetime.obj_to_str(selected_item));
|
||||
}
|
||||
},
|
||||
];
|
||||
this.render_chart_filters(filters, '.heatmap-container');
|
||||
}
|
||||
|
||||
render_chart_filters(filters, container, append) {
|
||||
filters.forEach(filter => {
|
||||
let chart_filter_html = `<div class="chart-filter pull-right">
|
||||
<a class="dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||
<button class="btn btn-default btn-xs">
|
||||
<span class="filter-label">${filter.label}</span>
|
||||
<span class="caret"></span>
|
||||
</button>
|
||||
</a>`;
|
||||
let options_html;
|
||||
|
||||
if (filter.fieldnames) {
|
||||
options_html = filter.options.map((option, i) =>
|
||||
`<li><a data-fieldname = "${filter.fieldnames[i]}">${option}</a></li>`).join('');
|
||||
} else {
|
||||
options_html = filter.options.map( option => `<li><a>${option}</a></li>`).join('');
|
||||
}
|
||||
|
||||
let dropdown_html = chart_filter_html + `<ul class="dropdown-menu">${options_html}</ul></div>`;
|
||||
let $chart_filter = $(dropdown_html);
|
||||
|
||||
if (append) {
|
||||
$chart_filter.prependTo(this.wrapper.find(container));
|
||||
} else $chart_filter.appendTo(this.wrapper.find(container));
|
||||
|
||||
$chart_filter.find('.dropdown-menu').on('click', 'li a', (e) => {
|
||||
let $el = $(e.currentTarget);
|
||||
let fieldname;
|
||||
if ($el.attr('data-fieldname')) {
|
||||
fieldname = $el.attr('data-fieldname');
|
||||
}
|
||||
let selected_item = $el.text();
|
||||
$el.parents('.chart-filter').find('.filter-label').text(selected_item);
|
||||
filter.action(selected_item, fieldname);
|
||||
});
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
edit_profile() {
|
||||
let edit_profile_dialog = new frappe.ui.Dialog({
|
||||
title: __('Edit Profile'),
|
||||
fields: [
|
||||
{
|
||||
fieldtype: 'Attach Image',
|
||||
fieldname: 'user_image',
|
||||
label: 'Profile Image',
|
||||
},
|
||||
{
|
||||
fieldtype: 'Data',
|
||||
fieldname: 'interest',
|
||||
label: 'Interests',
|
||||
},
|
||||
{
|
||||
fieldtype: 'Column Break'
|
||||
},
|
||||
{
|
||||
fieldtype: 'Data',
|
||||
fieldname: 'location',
|
||||
label: 'Location',
|
||||
},
|
||||
{
|
||||
fieldtype: 'Section Break',
|
||||
fieldname: 'Interest',
|
||||
},
|
||||
{
|
||||
fieldtype: 'Small Text',
|
||||
fieldname: 'bio',
|
||||
label: 'Bio',
|
||||
}
|
||||
],
|
||||
primary_action: values => {
|
||||
edit_profile_dialog.disable_primary_action();
|
||||
frappe.xcall('frappe.desk.page.user_profile.user_profile.update_profile_info', {
|
||||
profile_info: values
|
||||
}).then(user => {
|
||||
user.image = user.user_image;
|
||||
this.user = Object.assign(values, user);
|
||||
edit_profile_dialog.hide();
|
||||
this.render_user_details();
|
||||
}).finally(() => {
|
||||
edit_profile_dialog.enable_primary_action();
|
||||
});
|
||||
},
|
||||
primary_action_label: __('Save')
|
||||
});
|
||||
|
||||
edit_profile_dialog.set_values({
|
||||
user_image: this.user.image,
|
||||
location: this.user.location,
|
||||
interest: this.user.interest,
|
||||
bio: this.user.bio
|
||||
});
|
||||
edit_profile_dialog.show();
|
||||
}
|
||||
|
||||
render_user_details() {
|
||||
this.sidebar.empty().append(frappe.render_template('user_profile_sidebar', {
|
||||
user_image: frappe.avatar(this.user_id, 'avatar-frame', 'user_image', this.user.image),
|
||||
user_abbr: this.user.abbr,
|
||||
user_location: this.user.location,
|
||||
user_interest: this.user.interest,
|
||||
user_bio: this.user.bio,
|
||||
}));
|
||||
|
||||
this.setup_user_profile_links();
|
||||
}
|
||||
|
||||
setup_user_profile_links() {
|
||||
if (this.user_id !== frappe.session.user) {
|
||||
this.wrapper.find('.profile-links').hide();
|
||||
} else {
|
||||
this.wrapper.find('.edit-profile-link').on('click', () => {
|
||||
this.edit_profile();
|
||||
});
|
||||
|
||||
this.wrapper.find('.user-settings-link').on('click', () => {
|
||||
this.go_to_user_settings();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
get_user_rank() {
|
||||
return frappe.xcall('frappe.desk.page.user_profile.user_profile.get_user_rank', {
|
||||
user: this.user_id,
|
||||
}).then(r => {
|
||||
|
||||
if (r.monthly_rank[0]) this.month_rank = r.monthly_rank[0][1];
|
||||
if (r.all_time_rank[0]) this.rank = r.all_time_rank[0][1];
|
||||
});
|
||||
}
|
||||
|
||||
get_user_points() {
|
||||
return frappe.xcall(
|
||||
'frappe.social.doctype.energy_point_log.energy_point_log.get_user_energy_and_review_points',
|
||||
{
|
||||
user: this.user_id,
|
||||
}
|
||||
).then(r => {
|
||||
if (r[this.user_id]) {
|
||||
this.energy_points = r[this.user_id].energy_points;
|
||||
this.review_points = r[this.user_id].review_points;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
render_points_and_rank() {
|
||||
let $profile_details = this.wrapper.find('.profile-details');
|
||||
|
||||
this.get_user_rank().then(() => {
|
||||
this.get_user_points().then(() => {
|
||||
let html = $(__(`<p class="user-energy-points text-muted">${__('Energy Points: ')}<span class="rank">{0}</span></p>
|
||||
<p class="user-energy-points text-muted">${__('Review Points: ')}<span class="rank">{1}</span></p>
|
||||
<p class="user-energy-points text-muted">${__('Rank: ')}<span class="rank">{2}</span></p>
|
||||
<p class="user-energy-points text-muted">${__('Monthly Rank: ')}<span class="rank">{3}</span></p>
|
||||
`, [this.energy_points, this.review_points, this.rank, this.month_rank]));
|
||||
|
||||
$profile_details.append(html);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
go_to_user_settings() {
|
||||
frappe.set_route('Form', 'User', this.user_id);
|
||||
}
|
||||
|
||||
render_user_activity() {
|
||||
this.$recent_activity_list = this.wrapper.find('.recent-activity-list');
|
||||
|
||||
let get_recent_energy_points_html = (field) => {
|
||||
let message_html = frappe.energy_points.format_history_log(field);
|
||||
return `<p class="recent-activity-item text-muted"> ${message_html} </p>`;
|
||||
};
|
||||
|
||||
frappe.xcall('frappe.desk.page.user_profile.user_profile.get_energy_points_list', {
|
||||
start: this.activity_start,
|
||||
limit: this.activity_end,
|
||||
user: this.user_id
|
||||
}).then(list => {
|
||||
if (list.length < 11) {
|
||||
let activity_html = `<span class="text-muted">${__('No More Activity')}</span>`;
|
||||
this.wrapper.find('.show-more-activity').html(activity_html);
|
||||
}
|
||||
let html = list.slice(0, 10).map(get_recent_energy_points_html).join('');
|
||||
this.$recent_activity_list.append(html);
|
||||
});
|
||||
}
|
||||
|
||||
setup_show_more_activity() {
|
||||
//Show 10 items at a time
|
||||
this.activity_start = 0;
|
||||
this.activity_end = 11;
|
||||
this.wrapper.find('.show-more-activity').on('click', () => this.show_more_activity());
|
||||
}
|
||||
|
||||
show_more_activity() {
|
||||
this.activity_start = this.activity_end;
|
||||
this.activity_end += 11;
|
||||
this.render_user_activity();
|
||||
}
|
||||
|
||||
}
|
||||
22
frappe/desk/page/user_profile/user_profile.json
Normal file
22
frappe/desk/page/user_profile/user_profile.json
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
{
|
||||
"content": null,
|
||||
"creation": "2019-07-22 12:23:38.425877",
|
||||
"docstatus": 0,
|
||||
"doctype": "Page",
|
||||
"idx": 0,
|
||||
"modified": "2019-07-22 12:23:38.425877",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Desk",
|
||||
"name": "user-profile",
|
||||
"owner": "Administrator",
|
||||
"page_name": "User Profile",
|
||||
"roles": [
|
||||
{
|
||||
"role": "All"
|
||||
}
|
||||
],
|
||||
"script": null,
|
||||
"standard": "Yes",
|
||||
"style": null,
|
||||
"system_page": 0
|
||||
}
|
||||
76
frappe/desk/page/user_profile/user_profile.py
Normal file
76
frappe/desk/page/user_profile/user_profile.py
Normal file
|
|
@ -0,0 +1,76 @@
|
|||
import frappe
|
||||
from datetime import datetime
|
||||
|
||||
@frappe.whitelist()
|
||||
def get_energy_points_heatmap_data(user, date):
|
||||
return dict(frappe.db.sql("""select unix_timestamp(date(creation)), sum(points)
|
||||
from `tabEnergy Point Log`
|
||||
where
|
||||
date(creation) > subdate('{date}', interval 1 year) and
|
||||
date(creation) < subdate('{date}', interval -1 year) and
|
||||
user = '{user}' and
|
||||
type != 'Review'
|
||||
group by date(creation)
|
||||
order by creation asc""".format(user = user, date = date)))
|
||||
|
||||
|
||||
@frappe.whitelist()
|
||||
def get_energy_points_percentage_chart_data(user, field):
|
||||
result = frappe.db.get_all('Energy Point Log',
|
||||
filters = {'user': user, 'type': ['!=', 'Review']},
|
||||
group_by = field,
|
||||
order_by = field,
|
||||
fields = [field, 'ABS(sum(points)) as points'],
|
||||
as_list = True)
|
||||
|
||||
return {
|
||||
"labels": [r[0] for r in result if r[0] != None],
|
||||
"datasets": [{
|
||||
"values": [r[1] for r in result]
|
||||
}]
|
||||
}
|
||||
|
||||
@frappe.whitelist()
|
||||
def get_user_rank(user):
|
||||
month_start = datetime.today().replace(day=1)
|
||||
monthly_rank = frappe.db.get_all('Energy Point Log',
|
||||
group_by = 'user',
|
||||
filters = {'creation': ['>', month_start], 'type' : ['!=', 'Review']},
|
||||
fields = ['user', 'rank() over (order by sum(points) desc) as rank'],
|
||||
as_list = True)
|
||||
|
||||
all_time_rank = frappe.db.get_all('Energy Point Log',
|
||||
group_by = 'user',
|
||||
filters = {'type' : ['!=', 'Review']},
|
||||
fields = ['user', 'rank() over (order by sum(points) desc) as rank'],
|
||||
as_list = True)
|
||||
|
||||
return {
|
||||
'monthly_rank': [r for r in monthly_rank if r[0] == user],
|
||||
'all_time_rank': [r for r in all_time_rank if r[0] == user]
|
||||
}
|
||||
|
||||
|
||||
@frappe.whitelist()
|
||||
def update_profile_info(profile_info):
|
||||
profile_info = frappe.parse_json(profile_info)
|
||||
keys = ['location', 'interest', 'user_image', 'bio']
|
||||
|
||||
for key in keys:
|
||||
if key not in profile_info:
|
||||
profile_info[key] = None
|
||||
|
||||
user = frappe.get_doc('User', frappe.session.user)
|
||||
user.update(profile_info)
|
||||
user.save()
|
||||
return user
|
||||
|
||||
@frappe.whitelist()
|
||||
def get_energy_points_list(start, limit, user):
|
||||
return frappe.db.get_list('Energy Point Log',
|
||||
filters = {'user': user, 'type': ['!=', 'Review']},
|
||||
fields = ['name','user', 'points', 'reference_doctype', 'reference_name', 'reason',
|
||||
'type', 'seen', 'rule', 'owner', 'creation', 'revert_of'],
|
||||
start = start,
|
||||
limit = limit,
|
||||
order_by = 'creation desc')
|
||||
23
frappe/desk/page/user_profile/user_profile_sidebar.html
Normal file
23
frappe/desk/page/user_profile/user_profile_sidebar.html
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
<div class="user-profile-sidebar">
|
||||
<div class="user-image-container hidden-xs hidden-sm">
|
||||
{% if user_image %}
|
||||
{{user_image}}
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="profile-details">
|
||||
{% if user_bio %}
|
||||
<p class="user-bio">{{user_bio}}</p>
|
||||
{% endif %}
|
||||
{% if user_location %}
|
||||
<p class="user-location text-muted"><span class="interest-icon"><i class="fa fa-map-marker"></i></span>{{user_location}}</p>
|
||||
{% endif %}
|
||||
{% if user_interest %}
|
||||
<p class="user-interests text-muted"><span class="interest-icon"><i class="fa fa-puzzle-piece"></i></span>{{user_interest}}</p>
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="profile-links">
|
||||
<p><a class="edit-profile-link">{%=__("Edit Profile") %}</a></p>
|
||||
<p><a class="user-settings-link">{%=__("User Settings") %}</a></p>
|
||||
<p><a class="leaderboard-link" href="#social/users">{%=__("Leaderboard") %}</a></p>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -3,7 +3,9 @@
|
|||
|
||||
frappe.ui.form.on('Google Contacts', {
|
||||
refresh: function(frm) {
|
||||
frm.set_value("user", frappe.session.user);
|
||||
if (!frm.doc.enable) {
|
||||
frm.dashboard.set_headline(__("To use Google Contacts, enable {0}."), [`<a href='#Form/Google Settings'>${__('Google Settings')}</a>`]);
|
||||
}
|
||||
|
||||
frappe.realtime.on('import_google_contacts', (data) => {
|
||||
if (data.progress) {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"autoname": "format:GC-{user}",
|
||||
"autoname": "format:GC-{email_id}",
|
||||
"creation": "2019-06-14 00:09:39.441961",
|
||||
"doctype": "DocType",
|
||||
"engine": "InnoDB",
|
||||
|
|
@ -9,7 +9,6 @@
|
|||
"email_id",
|
||||
"authorize_google_contacts_access",
|
||||
"cb_00",
|
||||
"user",
|
||||
"last_sync_on",
|
||||
"authorization_code",
|
||||
"refresh_token"
|
||||
|
|
@ -21,13 +20,6 @@
|
|||
"fieldtype": "Check",
|
||||
"label": "Enable"
|
||||
},
|
||||
{
|
||||
"fieldname": "user",
|
||||
"fieldtype": "Link",
|
||||
"label": "User",
|
||||
"options": "User",
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "authorization_code",
|
||||
"fieldtype": "Password",
|
||||
|
|
@ -72,7 +64,7 @@
|
|||
"label": "Authorize Google Contacts Access"
|
||||
}
|
||||
],
|
||||
"modified": "2019-06-19 15:26:24.494101",
|
||||
"modified": "2019-08-23 13:50:52.789503",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Integrations",
|
||||
"name": "Google Contacts",
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
// For license information, please see license.txt
|
||||
|
||||
frappe.ui.form.on('Google Settings', {
|
||||
// refresh: function(frm) {
|
||||
// }
|
||||
refresh: function(frm) {
|
||||
frm.dashboard.set_headline(__("For more information, {0}.", [`<a href='https://erpnext.com/docs/user/manual/en/erpnext_integration/google_settings'>${__('Click here')</a>`]));
|
||||
}
|
||||
});
|
||||
|
|
|
|||
|
|
@ -10,7 +10,6 @@
|
|||
"node_modules/frappe-datatable/dist/frappe-datatable.css"
|
||||
],
|
||||
"css/frappe-web-b4.css": [
|
||||
"public/css/font-awesome.css",
|
||||
"public/less/indicator.less",
|
||||
"public/scss/website.scss"
|
||||
],
|
||||
|
|
|
|||
|
|
@ -17,10 +17,15 @@ frappe.ui.form.ControlBarcode = frappe.ui.form.ControlData.extend({
|
|||
|
||||
set_formatted_input(value) {
|
||||
// Set values to display
|
||||
const svg = value;
|
||||
let svg = value;
|
||||
const barcode_value = $(svg).attr('data-barcode-value');
|
||||
|
||||
this.$input.val(barcode_value);
|
||||
if(!barcode_value) {
|
||||
svg = this.get_barcode_html(value);
|
||||
this.doc[this.df.fieldname] = svg;
|
||||
}
|
||||
|
||||
this.$input.val(barcode_value || value);
|
||||
this.barcode_area.html(svg);
|
||||
},
|
||||
|
||||
|
|
|
|||
|
|
@ -199,13 +199,21 @@ frappe.views.BaseList = class BaseList {
|
|||
}
|
||||
|
||||
toggle_side_bar() {
|
||||
this.list_sidebar.parent.toggleClass('hide');
|
||||
this.page.current_view.find('.layout-main-section-wrapper').toggleClass('col-md-10 col-md-12');
|
||||
let show_sidebar = JSON.parse(localStorage.show_sidebar || 'true');
|
||||
show_sidebar = !show_sidebar;
|
||||
localStorage.show_sidebar = show_sidebar;
|
||||
this.show_or_hide_sidebar();
|
||||
}
|
||||
|
||||
show_or_hide_sidebar() {
|
||||
let show_sidebar = JSON.parse(localStorage.show_sidebar || 'true');
|
||||
$(document.body).toggleClass('no-sidebar', !show_sidebar);
|
||||
}
|
||||
|
||||
setup_main_section() {
|
||||
return frappe.run_serially([
|
||||
this.setup_list_wrapper,
|
||||
this.show_or_hide_sidebar,
|
||||
this.setup_filter_area,
|
||||
this.setup_sort_selector,
|
||||
this.setup_result_area,
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ frappe.views.ListGroupBy = class ListGroupBy {
|
|||
this.make_wrapper();
|
||||
|
||||
this.user_settings = frappe.get_user_settings(this.doctype);
|
||||
this.group_by_fields = ['assigned_to'];
|
||||
this.group_by_fields = ['assigned_to', 'owner'];
|
||||
if(this.user_settings.group_by_fields) {
|
||||
this.group_by_fields = this.group_by_fields.concat(this.user_settings.group_by_fields);
|
||||
}
|
||||
|
|
@ -24,7 +24,7 @@ frappe.views.ListGroupBy = class ListGroupBy {
|
|||
});
|
||||
d.set_primary_action("Save", ({ group_by_fields }) => {
|
||||
frappe.model.user_settings.save(this.doctype, 'group_by_fields', group_by_fields || null);
|
||||
this.group_by_fields = group_by_fields ? ['assigned_to', ...group_by_fields] : ['assigned_to'];
|
||||
this.group_by_fields = group_by_fields ? ['assigned_to', 'owner', ...group_by_fields] : ['assigned_to', 'owner'];
|
||||
this.render_group_by_items();
|
||||
d.hide();
|
||||
});
|
||||
|
|
@ -53,9 +53,14 @@ frappe.views.ListGroupBy = class ListGroupBy {
|
|||
|
||||
render_group_by_items() {
|
||||
let get_item_html = (fieldname) => {
|
||||
let label = fieldname === 'assigned_to'
|
||||
? __('Assigned To')
|
||||
: frappe.meta.get_label(this.doctype, fieldname);
|
||||
let label;
|
||||
if (fieldname === 'assigned_to') {
|
||||
label = __('Assigned To');
|
||||
} else if (fieldname === 'owner') {
|
||||
label = __('Created By');
|
||||
} else {
|
||||
label = frappe.meta.get_label(this.doctype, fieldname);
|
||||
}
|
||||
|
||||
return `<li class="group-by-field list-link">
|
||||
<div class="btn-group">
|
||||
|
|
|
|||
|
|
@ -46,28 +46,41 @@ frappe.ui.EnergyPointsNotifications = class {
|
|||
this.$dropdown_list.find('.recent-points-item').last().remove();
|
||||
this.dropdown_items.pop();
|
||||
}
|
||||
let new_item_html = this.get_dropdown_item_html(new_item);
|
||||
$(new_item_html).insertAfter(this.$dropdown_list.find('.points-date-range').eq(0));
|
||||
this.insert_into_dropdown();
|
||||
});
|
||||
}
|
||||
|
||||
insert_into_dropdown() {
|
||||
let new_item = this.dropdown_items[0];
|
||||
let new_item_html = this.get_dropdown_item_html(new_item);
|
||||
let new_item_date_range = this.get_date_range_title(new_item.creation);
|
||||
let current_date_range = this.get_date_range_title(this.dropdown_items[1].creation);
|
||||
if (current_date_range !== new_item_date_range) {
|
||||
let $date_range = $(`<li class="points-date-range text-muted">${new_item_date_range}</li>`);
|
||||
$date_range.insertAfter(this.$dropdown_list.find('.points-updates-header'));
|
||||
$(new_item_html).insertAfter($date_range);
|
||||
} else {
|
||||
$(new_item_html).insertAfter(this.$dropdown_list.find('.points-date-range').eq(0));
|
||||
}
|
||||
}
|
||||
|
||||
check_seen() {
|
||||
let unseen_logs = this.dropdown_items.filter(item => item.seen === 0);
|
||||
frappe.call('frappe.social.doctype.energy_point_log.energy_point_log.set_notification_as_seen', {point_logs: unseen_logs});
|
||||
}
|
||||
|
||||
get_energy_points_date_range(date) {
|
||||
get_date_range_title(date) {
|
||||
let current_date = frappe.datetime.now_date();
|
||||
let prev_week = frappe.datetime.add_days(current_date, -7);
|
||||
let prev_month = frappe.datetime.add_months(frappe.datetime.now_date(), -1);
|
||||
if (date >= current_date) {
|
||||
return 'Today';
|
||||
return __('Today');
|
||||
} else if (date > prev_week) {
|
||||
return 'Last 7 days';
|
||||
return __('Last 7 days');
|
||||
} else if (date > prev_month) {
|
||||
return 'Last 30 days';
|
||||
return __('Last 30 days');
|
||||
} else {
|
||||
return 'Older';
|
||||
return __('Older');
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -96,13 +109,13 @@ frappe.ui.EnergyPointsNotifications = class {
|
|||
let view_full_log_html = '';
|
||||
|
||||
if (this.dropdown_items.length) {
|
||||
let date_range= this.get_energy_points_date_range(this.dropdown_items[0].creation);
|
||||
body_html += `<li class="points-date-range text-muted">${__(date_range)}</li>`;
|
||||
let date_range = this.get_date_range_title(this.dropdown_items[0].creation);
|
||||
body_html += `<li class="points-date-range text-muted">${date_range}</li>`;
|
||||
this.dropdown_items.forEach(field => {
|
||||
let current_field_date_range = this.get_energy_points_date_range(field.creation);
|
||||
let current_field_date_range = this.get_date_range_title(field.creation);
|
||||
if (date_range !== current_field_date_range) {
|
||||
body_html+=`<li class="points-date-range text-muted">${__(current_field_date_range)}</li>`;
|
||||
date_range=current_field_date_range;
|
||||
body_html += `<li class="points-date-range text-muted">${current_field_date_range}</li>`;
|
||||
date_range = current_field_date_range;
|
||||
}
|
||||
let item_html = this.get_dropdown_item_html(field);
|
||||
if (item_html) body_html += item_html;
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@
|
|||
{%= __("Settings") %}</span>
|
||||
<b class="caret hidden-xs hidden-sm"></b></a>
|
||||
<ul class="dropdown-menu" id="toolbar-user" role="menu">
|
||||
<li><a href="#social/profile/{%= encodeURIComponent(frappe.session.user) %}">
|
||||
<li><a href="#user-profile">
|
||||
{%= __("My Profile") %}</a></li>
|
||||
<li><a href="#Form/User/{%= encodeURIComponent(frappe.session.user) %}">
|
||||
{%= __("My Settings") %}</a></li>
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ frappe.provide('frappe.energy_points');
|
|||
|
||||
Object.assign(frappe.energy_points, {
|
||||
get_points(points) {
|
||||
return `<span class='bold' style="color: ${points >= 0 ? '#45A163': '#e42121'}">
|
||||
return `<span class="bold" style="color: ${points >= 0 ? '#45A163': '#e42121'}">
|
||||
${points > 0 ? '+': ''}${points}
|
||||
</span>`;
|
||||
},
|
||||
|
|
@ -24,7 +24,7 @@ Object.assign(frappe.energy_points, {
|
|||
const route = frappe.utils.get_form_link(log.reference_doctype, log.reference_name);
|
||||
const formatted_log = `<span>
|
||||
${this.get_points(log.points)}
|
||||
<a href="${route}">${this.get_history_log_message(log)}</a>
|
||||
<a href="${route}" class="text-muted">${this.get_history_log_message(log)}</a>
|
||||
${log.reason ? separator + log.reason: ''}
|
||||
${separator + frappe.datetime.comment_when(log.creation)}
|
||||
</span>`;
|
||||
|
|
|
|||
|
|
@ -1081,6 +1081,18 @@ body.full-width {
|
|||
}
|
||||
}
|
||||
|
||||
body.no-sidebar {
|
||||
@media (min-width: @screen-md) {
|
||||
.layout-side-section {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.layout-main-section-wrapper {
|
||||
width: 100% !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// utilities
|
||||
|
||||
.whitespace-nowrap {
|
||||
|
|
|
|||
|
|
@ -399,7 +399,7 @@ body[data-route^="Module"] .main-menu {
|
|||
.group-by-dropdown, .list-stats-dropdown {
|
||||
max-height: 300px;
|
||||
overflow-y: auto;
|
||||
max-width: 200px;
|
||||
max-width: 250px;
|
||||
}
|
||||
.dropdown-search {
|
||||
padding: 8px;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
@import "variables";
|
||||
@import "frappe/public/css/font-awesome";
|
||||
@import "~bootstrap/scss/bootstrap";
|
||||
@import "multilevel-dropdown";
|
||||
@import "website-image";
|
||||
|
|
|
|||
|
|
@ -221,7 +221,7 @@ def get_context(context):
|
|||
"payer_name": frappe.utils.get_fullname(frappe.session.user),
|
||||
"order_id": doc.name,
|
||||
"currency": self.currency,
|
||||
"redirect_to": frappe.utils.get_url(self.route)
|
||||
"redirect_to": frappe.utils.get_url(self.success_url or self.route)
|
||||
}
|
||||
|
||||
# Redirect the user to this url
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue