seitime-frappe/frappe/desk/page/user_profile/user_profile_controller.js
2023-07-14 15:41:20 +05:30

494 lines
12 KiB
JavaScript

import BaseTimeline from "../../../public/js/frappe/form/footer/base_timeline";
frappe.provide("frappe.energy_points");
class UserProfile {
constructor(wrapper) {
this.wrapper = $(wrapper);
this.page = frappe.ui.make_app_page({
parent: wrapper,
});
this.sidebar = this.wrapper.find(".layout-side-section");
this.main_section = this.wrapper.find(".layout-main-section");
this.wrapper.bind("show", () => {
this.show();
});
}
show() {
let route = frappe.get_route();
this.user_id = route[1] || frappe.session.user;
frappe.dom.freeze(__("Loading user profile") + "...");
frappe.db.exists("User", this.user_id).then((exists) => {
frappe.dom.unfreeze();
if (exists) {
this.make_user_profile();
} else {
frappe.msgprint(__("User does not exist"));
}
});
}
make_user_profile() {
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_user_activity_timeline();
}
setup_user_search() {
this.$user_search_button = this.page.set_secondary_action(
__("Change User"),
() => this.show_user_search_dialog(),
{ icon: "change", size: "sm" }
);
}
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();
frappe.set_route("user-profile", user);
},
});
dialog.show();
}
render_heatmap() {
this.heatmap = new frappe.Chart(".performance-heatmap", {
type: "heatmap",
countLabel: "Energy Points",
data: {},
discreteDomains: 1,
radius: 3,
height: 150,
});
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 });
});
}
render_line_chart() {
this.line_chart_filters = [
["Energy Point Log", "user", "=", this.user_id, false],
["Energy Point Log", "type", "!=", "Review", false],
];
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", {
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", {
type: "percentage",
data: {
labels: chart.labels,
datasets: chart.datasets,
},
truncateLegends: 1,
barOptions: {
height: 11,
depth: 1,
},
height: 200,
maxSlices: 8,
colors: [
"purple",
"blue",
"cyan",
"teal",
"pink",
"red",
"orange",
"yellow",
],
});
} 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") {
this.line_chart_filters = [
["Energy Point Log", "user", "=", this.user_id, false],
["Energy Point Log", "type", "!=", "Review", false],
];
} else {
this.line_chart_filters[1] = [
"Energy Point Log",
"type",
"=",
selected_item,
false,
];
}
this.update_line_chart_data();
},
},
{
label: "Last Month",
options: ["Last Week", "Last Month", "Last Quarter", "Last Year"],
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();
},
},
];
frappe.dashboard_utils.render_chart_filters(
filters,
"chart-filter",
".line-chart-options",
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);
},
},
];
frappe.dashboard_utils.render_chart_filters(
filters,
"chart-filter",
".percentage-chart-options"
);
}
create_heatmap_chart_filters() {
let filters = [
{
label: frappe.dashboard_utils.get_year(frappe.datetime.now_date()),
options: frappe.dashboard_utils.get_years_since_creation(
frappe.boot.user.creation
),
action: (selected_item) => {
this.update_heatmap_data(frappe.datetime.obj_to_str(selected_item));
},
},
];
frappe.dashboard_utils.render_chart_filters(filters, "chart-filter", ".heatmap-options");
}
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: 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.length) this.month_rank = r.monthly_rank[0];
if (r.all_time_rank.length) this.rank = r.all_time_rank[0];
});
}
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(".user-stats");
let $profile_details_wrapper = this.wrapper.find(".user-stats-detail");
const _get_stat_dom = (value, label, icon) => {
return `<div class="user-stats-item mt-4">
${frappe.utils.icon(icon, "lg", "no-stroke")}
<div>
<div class="stat-value">${value}</div>
<div class="stat-label">${label}</div>
</div>
</div>`;
};
this.get_user_rank().then(() => {
this.get_user_points().then(() => {
let html = $(`
${_get_stat_dom(this.energy_points, __("Energy Points"), "color-energy-points")}
${_get_stat_dom(this.review_points, __("Review Points"), "color-review-points")}
${_get_stat_dom(this.rank, __("Rank"), "color-rank")}
${_get_stat_dom(this.month_rank, __("Monthly Rank"), "color-monthly-rank")}
`);
$profile_details.append(html);
$profile_details_wrapper.removeClass("hide");
});
});
}
go_to_user_settings() {
frappe.set_route("Form", "User", this.user_id);
}
setup_user_activity_timeline() {
this.user_activity_timeline = new UserProfileTimeline({
parent: this.wrapper.find(".recent-activity-list"),
footer: this.wrapper.find(".recent-activity-footer"),
user: this.user_id,
});
this.user_activity_timeline.refresh();
}
}
class UserProfileTimeline extends BaseTimeline {
make() {
super.make();
this.activity_start = 0;
this.activity_limit = 20;
this.setup_show_more_activity();
}
prepare_timeline_contents() {
return this.get_user_activity_data().then((activities) => {
if (!activities.length) {
this.show_more_button.hide();
this.timeline_wrapper.html(`<div>${__("No activities to show")}</div>`);
return;
}
this.show_more_button.toggle(activities.length === this.activity_limit);
this.timeline_items = activities.map((activity) =>
this.get_activity_timeline_item(activity)
);
});
}
get_user_activity_data() {
return frappe.xcall("frappe.desk.page.user_profile.user_profile.get_energy_points_list", {
start: this.activity_start,
limit: this.activity_limit,
user: this.user,
});
}
get_activity_timeline_item(data) {
let icon =
data.type == "Appreciation" ? "clap" : data.type == "Criticism" ? "criticize" : null;
return {
icon: icon,
creation: data.creation,
is_card: true,
content: frappe.energy_points.format_history_log(data),
};
}
setup_show_more_activity() {
this.show_more_button = $(
`<a class="show-more-activity-btn">${__("Show More Activity")}</a>`
);
this.show_more_button.hide();
this.footer.append(this.show_more_button);
this.show_more_button.on("click", () => this.show_more_activity());
}
show_more_activity() {
this.activity_start += this.activity_limit;
this.get_user_activity_data().then((activities) => {
if (!activities.length || activities.length < this.activity_limit) {
this.show_more_button.hide();
}
let timeline_items = activities.map((activity) =>
this.get_activity_timeline_item(activity)
);
timeline_items.map((item) => this.add_timeline_item(item, true));
});
}
}
frappe.provide("frappe.ui");
frappe.ui.UserProfile = UserProfile;